All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 36s
- Geluidsmeter: meet het klasgeluid live via de microfoon in een verticale
meter (rustig/pratend/te luid). Twee aanpasbare streefniveaus ("Rustig
tot" / "Te luid vanaf") laten de leerkracht de meter afstemmen op het
eigen lokaal en apparaat. Microfoon staat standaard uit en start alleen
na een expliciete klik; er wordt niets opgenomen of verstuurd, alles
blijft lokaal in de browser. Stopt de microfoonstream vanzelf zodra de
widget van het bord verdwijnt, ook als "Stop" niet eerst is ingedrukt.
- Gevoelszones: individuele check-in met vier zones (blauw/groen/geel/
rood, Zones of Regulation-stijl) - elke zone geeft een korte uitleg én
een concrete tip om jezelf te helpen. Anders dan de bestaande
Gevoelsmeter (mood.js), die een anonieme klaspoll is.
- Ademhalingsoefening: een groeiende/krimpende cirkel begeleidt rustig
ademhalen in drie instelbare tempo's (4-4, 4-7-8, box breathing),
met rondjesteller.
- Complimentenmachine: trekt een willekeurig compliment uit twintig
kindvriendelijke complimenten, met dezelfde spin-en-onthul-animatie als
de namenkiezer.
- Alle vier volledig tweetalig (nl/en), toegevoegd aan de mobiele-dekking-
test, en geverifieerd in de browser inclusief een echte (fake) micro-
foonstream voor de geluidsmeter.
66 lines
3.3 KiB
JavaScript
66 lines
3.3 KiB
JavaScript
/* widget: Complimentenmachine */
|
|
/* =========================================================
|
|
Trek een willekeurig compliment - zelfde spin-en-onthul-mechaniek als
|
|
de namenkiezer (names.js)
|
|
==========================================================*/
|
|
const COMPLIMENTS = Object.freeze([
|
|
{ nl:"Jij bent een fijne klasgenoot!", en:"You're a great classmate!" },
|
|
{ nl:"Wat knap dat je dat zelf hebt uitgezocht!", en:"Great job figuring that out yourself!" },
|
|
{ nl:"Jij luistert altijd goed naar anderen.", en:"You're always a great listener." },
|
|
{ nl:"Je hebt vandaag hard gewerkt, goed gedaan!", en:"You worked hard today, well done!" },
|
|
{ nl:"Jij deelt graag met anderen.", en:"You love sharing with others." },
|
|
{ nl:"Wat fijn dat jij er bent!", en:"We're so glad you're here!" },
|
|
{ nl:"Jij bent heel behulpzaam.", en:"You're very helpful." },
|
|
{ nl:"Je hebt een mooie glimlach.", en:"You have a lovely smile." },
|
|
{ nl:"Jij geeft nooit op, dat is knap!", en:"You never give up, that's impressive!" },
|
|
{ nl:"Jij bent een echte teamspeler.", en:"You're a real team player." },
|
|
{ nl:"Wat een goed idee had jij daar!", en:"That was a great idea you had!" },
|
|
{ nl:"Jij maakt anderen graag blij.", en:"You love making others happy." },
|
|
{ nl:"Je hebt heel goed je best gedaan.", en:"You tried really hard." },
|
|
{ nl:"Jij bent creatief en origineel.", en:"You're creative and original." },
|
|
{ nl:"Jij zegt altijd eerlijk wat je denkt.", en:"You always speak your mind honestly." },
|
|
{ nl:"Jij bent een fijne vriend(in).", en:"You're a great friend." },
|
|
{ nl:"Wat kun jij goed samenwerken!", en:"You're so good at working together!" },
|
|
{ nl:"Jij maakt de klas een fijnere plek.", en:"You make our class a nicer place." },
|
|
{ nl:"Jij durft dingen te proberen, goed zo!", en:"You're brave enough to try new things!" },
|
|
{ nl:"Jij bent trots op jezelf, en dat mag!", en:"You're proud of yourself, and that's great!" },
|
|
]);
|
|
function mountCompliments(root, initState){
|
|
let current = null, spinning = false;
|
|
root.innerHTML = `
|
|
<div class="cpl">
|
|
<p class="play-mission cpl-mission"></p>
|
|
<div class="cpl-card"><span class="cpl-icon">💝</span><p class="cpl-text"></p></div>
|
|
<button class="tbtn cpl-draw"></button>
|
|
</div>`;
|
|
const card = root.querySelector(".cpl-card"), text = root.querySelector(".cpl-text"), drawBtn = root.querySelector(".cpl-draw");
|
|
function pickRandom(){ return COMPLIMENTS[Math.floor(Math.random() * COMPLIMENTS.length)]; }
|
|
function draw(){
|
|
if(spinning) return;
|
|
spinning = true;
|
|
card.classList.remove("show");
|
|
let n = 0;
|
|
const iv = setInterval(()=>{
|
|
text.textContent = pickRandom()[LANG];
|
|
tone(500 + Math.random() * 200, 0.03, 0, "square", 0.04);
|
|
if(++n >= 10){
|
|
clearInterval(iv);
|
|
current = pickRandom();
|
|
text.textContent = current[LANG];
|
|
card.classList.add("show");
|
|
confetti(card);
|
|
sndWin();
|
|
spinning = false;
|
|
}
|
|
}, 70);
|
|
}
|
|
drawBtn.addEventListener("click", draw);
|
|
function labels(){
|
|
root.querySelector(".cpl-mission").textContent = T("wg_compliments_d");
|
|
drawBtn.textContent = "💝 " + T("complimentsDraw");
|
|
if(current) text.textContent = current[LANG];
|
|
}
|
|
document.addEventListener("langchange", labels);
|
|
labels();
|
|
return { getState: ()=>({}) };
|
|
}
|