teach/public/js/widgets/dice.js
Ramon 7a5d7c57ff
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 41s
feat: maak widgets speelser en kindvriendelijker (v0.3.77-beta)
2026-07-16 14:15:28 +02:00

79 lines
3.2 KiB
JavaScript

/* widget: Dobbelstenen */
/* =========================================================
Dice widget
==========================================================*/
function mountDice(root, initState){
let count = (initState && initState.count) || 2, rolling = false, history=Array.isArray(initState?.history)?initState.history.slice(-5):[];
const PIPS = {1:[4],2:[0,8],3:[0,4,8],4:[0,2,6,8],5:[0,2,4,6,8],6:[0,2,3,5,6,8]};
root.innerHTML = `
<div class="dc">
<div class="mt-top" style="width:100%;">
<div class="tseg dc-seg">
<button data-n="1">1</button><button data-n="2">2</button><button data-n="3">3</button>
</div>
<div class="mt-score dc-sumlbl"></div>
</div>
<p class="play-mission dc-mission"></p>
<div class="dc-row"></div>
<div class="dc-sum" aria-live="polite"></div>
<div class="dc-history"></div>
<button class="tbtn dc-roll"></button>
</div>`;
const row = root.querySelector(".dc-row"),
sumEl = root.querySelector(".dc-sum"),
rollBtn = root.querySelector(".dc-roll");
function face(die, v){
die.querySelectorAll("i").forEach((p,i)=>p.classList.toggle("on", PIPS[v].includes(i)));
die.dataset.v = v;
}
function build(){
row.innerHTML = "";
for(let i=0;i<count;i++){
const d = document.createElement("div");
d.className = "die";
for(let j=0;j<9;j++) d.appendChild(document.createElement("i"));
face(d, 1+Math.floor(Math.random()*6));
row.appendChild(d);
}
sumEl.textContent = "";
}
function roll(){
if(rolling) return;
rolling = true;
sumEl.textContent = "";
const dice = [...row.querySelectorAll(".die")];
dice.forEach(d=>d.classList.add("rolling"));
let n = 0;
const iv = setInterval(()=>{
dice.forEach(d=>face(d, 1+Math.floor(Math.random()*6)));
tone(300+Math.random()*250, 0.04, 0, "square", 0.05);
if(++n >= 9){
clearInterval(iv);
dice.forEach(d=>d.classList.remove("rolling"));
const total = dice.reduce((s,d)=>s + +d.dataset.v, 0);
if(count>1) sumEl.textContent = `${T("diceSum")}: ${total}`;
history.push(total);history=history.slice(-5);renderHistory();
rolling = false;
}
}, 90);
}
function renderHistory(){const box=root.querySelector('.dc-history');box.innerHTML='';if(!history.length)return;const label=document.createElement('span');label.textContent=T('diceHistory');box.append(label,...history.map(value=>{const chip=document.createElement('b');chip.textContent=value;return chip}))}
row.addEventListener("click", roll);
rollBtn.addEventListener("click", roll);
root.querySelectorAll(".dc-seg button").forEach(b=>{
b.addEventListener("click", ()=>{
count = +b.dataset.n;
root.querySelectorAll(".dc-seg button").forEach(x=>x.classList.toggle("on", x===b));
build();
});
});
function labels(){
rollBtn.textContent = T("diceRoll");
root.querySelector('.dc-mission').textContent=T('diceMission');
root.querySelectorAll(".dc-seg button").forEach(x=>x.classList.toggle("on", +x.dataset.n===count));
renderHistory();
}
document.addEventListener("langchange", labels);
labels(); build();
return { getState: ()=>({count,history:[...history]}) };
}