1(function () { 2 "use strict"; 3 4 var cfg = window.TV_CONFIG || {}; 5 var projects = window.TV_PROJECTS || []; 6 var backSrc = (cfg.cardBack || "").trim(); 7 var foil = typeof cfg.foilIntensity === "number" ? cfg.foilIntensity : 0.5; 8 9 /* ---------- build the cards ---------- */ 10 11 function cardMarkup(p) { 12 var art = (p.art || "").trim() 13 ? '<img src="' + p.art + '" alt="">' 14 : '<div class="art-tbd">ART TBD</div>'; 15 16 var back = backSrc 17 ? '<img src="' + backSrc + '" alt="">' 18 : '<div class="back-lockup">' + 19 '<div class="back-name">TONY VIRELLI</div>' + 20 '<img src="assets/logo-orange.svg" alt="">' + 21 '<div class="back-series">COLLECTION SERIES 01</div>' + 22 '</div>'; 23 24 return '' + 25 '<div class="card-glow" style="background:' + p.accent + '"></div>' + 26 '<div class="card-face">' + 27 '<div class="card-front">' + 28 '<div class="card-holo"></div>' + 29 '<div class="card-inner">' + 30 '<div class="card-art">' + art + '</div>' + 31 '<div class="card-head">' + 32 '<div class="card-title">' + p.title + '</div>' + 33 '<div class="card-kind" style="color:' + p.accent + '"><span class="dash"></span>' + p.kind + '</div>' + 34 '</div>' + 35 '<div class="card-meta"><span>NO. ' + p.slot + '</span><span>' + p.host + '</span></div>' + 36 '</div>' + 37 '<div class="card-glare"></div>' + 38 '</div>' + 39 '<div class="card-back">' + 40 '<div class="card-back-panel" style="background-color:' + (cfg.cardBackColor || "#0b0b0b") + '">' + back + '</div>' + 41 '<div class="card-glare"></div>' + 42 '</div>' + 43 '</div>'; 44 } 45 46 var grid = document.getElementById("cardGrid"); 47 if (grid) { 48 projects.forEach(function (p) { 49 var a = document.createElement("a"); 50 a.className = "card"; 51 a.href = p.href; 52 a.target = "_blank"; 53 a.rel = "noopener"; 54 a.innerHTML = cardMarkup(p); 55 a.addEventListener("contextmenu", function (e) { 56 e.preventDefault(); 57 var face = a.querySelector(".card-face"); 58 var on = face.dataset.on === "1"; 59 face.dataset.on = on ? "0" : "1"; 60 face.style.transform = on ? "rotateY(0deg)" : "rotateY(180deg)"; 61 }); 62 grid.appendChild(a); 63 }); 64 } 65 66 /* ---------- card tilt, glare, foil ---------- */ 67 68 var cards = Array.prototype.slice.call(document.querySelectorAll(".card")); 69 70 function onCardMove(e) { 71 cards.forEach(function (el) { 72 var r = el.getBoundingClientRect(); 73 var px = (e.clientX - r.left) / r.width; 74 var py = (e.clientY - r.top) / r.height; 75 var inside = px >= 0 && px <= 1 && py >= 0 && py <= 1; 76 var glares = el.querySelectorAll(".card-glare"); 77 var holo = el.querySelector(".card-holo"); 78 var glow = el.querySelector(".card-glow"); 79 80 if (glow) glow.style.opacity = inside ? "0.5" : "0"; 81 82 if (inside) { 83 var ry = (px - 0.5) * 24; 84 var rx = -(py - 0.5) * 24; 85 el.style.transform = "perspective(900px) rotateY(" + ry + "deg) rotateX(" + rx + "deg) scale(1.045)"; 86 Array.prototype.forEach.call(glares, function (glare, i) { 87 glare.style.opacity = "1"; 88 var gx = i === 1 ? (1 - px) * 100 : px * 100; 89 glare.style.background = "radial-gradient(circle at " + gx + "% " + (py * 100) + 90 "%, rgba(255,255,255,0.34), rgba(255,255,255,0.05) 42%, transparent 62%)"; 91 }); 92 if (holo) { 93 holo.style.opacity = String(foil); 94 holo.style.backgroundPosition = (px * 100) + "% " + (py * 100) + "%"; 95 } 96 } else { 97 el.style.transform = "perspective(900px)"; 98 Array.prototype.forEach.call(glares, function (g) { g.style.opacity = "0"; }); 99 if (holo) holo.style.opacity = "0"; 100 } 101 }); 102 } 103 104 /* ---------- hero parallax ---------- */ 105 106 function onHeroMove(e) { 107 var hero = document.getElementById("hero"); 108 if (!hero) return; 109 var r = hero.getBoundingClientRect(); 110 var px = (e.clientX - r.left) / r.width; 111 var py = (e.clientY - r.top) / r.height; 112 var bg = document.getElementById("heroBg"); 113 var type = document.getElementById("heroType"); 114 var spot = document.getElementById("heroSpot"); 115 116 if (bg) bg.style.transform = "translate3d(" + (-(px - 0.5) * 26) + "px," + (-(py - 0.5) * 18) + "px,0) scale(1.04)"; 117 if (type) type.style.transform = "translate3d(" + ((px - 0.5) * 12) + "px," + ((py - 0.5) * 8) + "px,0)"; 118 if (spot) { 119 spot.style.background = "radial-gradient(560px circle at " + (px * 100) + "% " + (py * 100) + 120 "%, rgba(248,109,12,0.20), transparent 70%)"; 121 } 122 } 123 124 var fine = !window.matchMedia || window.matchMedia("(hover: hover) and (pointer: fine)").matches; 125 if (fine) { 126 document.addEventListener("mousemove", onHeroMove); 127 document.addEventListener("mousemove", onCardMove); 128 } 129 130 /* ---------- misc ---------- */ 131 132 var year = document.getElementById("year"); 133 if (year) year.textContent = new Date().getFullYear(); 134})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.