init
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
/* ==========================================================================
|
||||
Transfer Broadcast Graphics - Controller
|
||||
Data: data/transfers.json (generated from assets/transfers-list.csv)
|
||||
========================================================================== */
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var REVEAL_TIME = 5000; // 5 seconds in State 1, then -> compact
|
||||
var AUTOPLAY_MS = 8000; // auto-advance interval
|
||||
|
||||
var transfers = [];
|
||||
var currentIndex = 0;
|
||||
var compactTimer = null;
|
||||
var autoplayTimer = null;
|
||||
var isHidden = true;
|
||||
var autoplayOn = false;
|
||||
|
||||
var container, card, opCounter;
|
||||
|
||||
function $(id) { return document.getElementById(id); }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
async function init() {
|
||||
container = $("graphicsContainer");
|
||||
card = $("transferCard");
|
||||
opCounter = $("currentTransfer");
|
||||
|
||||
try {
|
||||
var res = await fetch("data/transfers.json");
|
||||
var data = await res.json();
|
||||
transfers = data.transfers;
|
||||
} catch (e) {
|
||||
console.error("Failed to load transfers.json", e);
|
||||
opCounter.textContent = "DATA ERROR";
|
||||
return;
|
||||
}
|
||||
|
||||
updateCounter();
|
||||
setupKeys();
|
||||
console.log("Loaded " + transfers.length + " transfers. Press \u2192 or Enter to start.");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
function showTransfer(index) {
|
||||
if (!transfers.length) return;
|
||||
var t = transfers[index];
|
||||
if (!t) return;
|
||||
|
||||
container.classList.remove("compact");
|
||||
|
||||
// photo
|
||||
$("playerPhoto").src = t.photo;
|
||||
|
||||
// text
|
||||
$("playerName").textContent = t.playerName;
|
||||
$("teamName").textContent = t.team.name;
|
||||
$("teamLogo").src = t.team.logo;
|
||||
|
||||
// price / status
|
||||
var badge = $("priceBadge");
|
||||
var priceValue = $("priceValue");
|
||||
var priceLabel = $("priceLabel");
|
||||
|
||||
badge.classList.remove("free-agent", "loan");
|
||||
|
||||
if (t.status === "free-agent") {
|
||||
badge.classList.add("free-agent");
|
||||
priceLabel.textContent = "СТАТУС";
|
||||
priceValue.textContent = t.price;
|
||||
} else if (t.status === "loan") {
|
||||
badge.classList.add("loan");
|
||||
priceLabel.textContent = "СТАТУС";
|
||||
priceValue.textContent = t.price;
|
||||
} else {
|
||||
priceLabel.textContent = "СУММА";
|
||||
priceValue.textContent = t.price;
|
||||
}
|
||||
|
||||
// team colour vars
|
||||
card.style.setProperty("--team-color", t.team.color);
|
||||
card.style.setProperty("--team-accent", t.team.accent);
|
||||
|
||||
// trigger reveal animation (restart)
|
||||
card.classList.remove("reveal");
|
||||
void card.offsetWidth;
|
||||
card.classList.add("reveal");
|
||||
|
||||
// show
|
||||
container.classList.remove("hidden");
|
||||
container.classList.add("visible");
|
||||
isHidden = false;
|
||||
|
||||
// schedule 5 s compact transition
|
||||
clearTimeout(compactTimer);
|
||||
compactTimer = setTimeout(function () {
|
||||
card.classList.remove("reveal"); // clear animation fill-mode locks so transitions are clean
|
||||
container.classList.add("compact");
|
||||
}, REVEAL_TIME);
|
||||
|
||||
updateCounter();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
function next() {
|
||||
if (isHidden) { showTransfer(currentIndex); return; }
|
||||
currentIndex = (currentIndex + 1) % transfers.length;
|
||||
showTransfer(currentIndex);
|
||||
}
|
||||
function prev() {
|
||||
if (isHidden) { showTransfer(currentIndex); return; }
|
||||
currentIndex = (currentIndex - 1 + transfers.length) % transfers.length;
|
||||
showTransfer(currentIndex);
|
||||
}
|
||||
function replay() { showTransfer(currentIndex); }
|
||||
|
||||
function toggleHide() {
|
||||
if (isHidden) {
|
||||
isHidden = false;
|
||||
replay();
|
||||
} else {
|
||||
isHidden = true;
|
||||
container.classList.add("hidden");
|
||||
container.classList.remove("visible");
|
||||
clearTimeout(compactTimer);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleAutoplay() {
|
||||
autoplayOn = !autoplayOn;
|
||||
if (autoplayOn) {
|
||||
console.log("Autoplay ON");
|
||||
if (isHidden) replay();
|
||||
autoplayTimer = setInterval(next, AUTOPLAY_MS);
|
||||
} else {
|
||||
console.log("Autoplay OFF");
|
||||
clearInterval(autoplayTimer);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
function updateCounter() {
|
||||
if (transfers.length && opCounter)
|
||||
opCounter.textContent = (currentIndex + 1) + " / " + transfers.length;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
function setupKeys() {
|
||||
document.addEventListener("keydown", function (e) {
|
||||
switch (e.key) {
|
||||
case "ArrowRight":
|
||||
case "Enter":
|
||||
e.preventDefault(); next(); break;
|
||||
case "ArrowLeft":
|
||||
case "Backspace":
|
||||
e.preventDefault(); prev(); break;
|
||||
case "r": case "R": replay(); break;
|
||||
case "h": case "H": toggleHide(); break;
|
||||
case "a": case "A": toggleAutoplay(); break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Expose for CasparCG / OBS / external control
|
||||
window.transferGraphics = {
|
||||
next: next,
|
||||
prev: prev,
|
||||
replay: replay,
|
||||
hide: function () { if (!isHidden) toggleHide(); },
|
||||
show: function () { if (isHidden) toggleHide(); },
|
||||
showAt: function (i) { currentIndex = i; showTransfer(i); },
|
||||
autoplay: toggleAutoplay,
|
||||
};
|
||||
|
||||
// GO
|
||||
if (document.readyState === "loading")
|
||||
document.addEventListener("DOMContentLoaded", init);
|
||||
else
|
||||
init();
|
||||
})();
|
||||
Reference in New Issue
Block a user