feat: slot op liniaal/geodriehoek en richtingsbewust langs de lat tekenen (v0.3.76-beta)
Some checks failed
dev - build & deploy naar test / build-and-deploy (push) Failing after 34s
Some checks failed
dev - build & deploy naar test / build-and-deploy (push) Failing after 34s
- Slot-knop (🔓/🔒) op liniaal én geodriehoek: vastgezet gereedschap kan niet meer verschuiven of draaien (draaiknop verdwijnt), er kan alleen nog langs getekend worden; tweede klik ontgrendelt - Naast de lat beslist nu de richting i.p.v. één vaste afstand: binnen 22px van een rand wacht de haal de eerste ~7px beweging af - loopt die grofweg evenwijdig aan de rand (≤30°), dan kleeft hij, anders blijft hij vrij; een tik zet gewoon een stip - Daarmee is langs de lat tekenen betrouwbaar (ook met dikke digibord-vingers) zónder dat de lat vrije halen in de buurt grijpt - Op de lat zelf blijft de intentie ondubbelzinnig: direct kleven binnen 24px van de rand - Geverifieerd in headless Chromium: 12 nieuwe checks (richtingsregel, stip-tik, slot aan/uit, vastgezet = onverplaatsbaar maar betekenbaar) + de drie bestaande suites (35 checks) blijven groen Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
This commit is contained in:
parent
5d12d2f8ec
commit
85268050fd
4 changed files with 81 additions and 30 deletions
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
0.3.75-beta
|
||||
0.3.76-beta
|
||||
|
|
|
|||
|
|
@ -373,6 +373,8 @@
|
|||
.dtool-opts button:hover{background:var(--accent-soft);}
|
||||
/* lengteknop toont de maat ("10 cm") en is dus breder dan een rond knopje */
|
||||
.dtool-opts .do-wide{width:auto; min-width:48px; padding:0 9px; border-radius:12px;}
|
||||
/* slot-knop kleurt mee zodra het gereedschap vaststaat */
|
||||
.dtool-opts .do-lock.on{background:var(--accent-soft);}
|
||||
/* live hoek-uitlezing tijdens het draaien van liniaal/geodriehoek */
|
||||
.dtool-deg{
|
||||
display:none; position:absolute; left:50%; top:50%; margin:-16px 0 0 -24px;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ const REGISTRY = [
|
|||
{ id:"names", cat:"tools", icon:"🎯", w:420, h:430, minW:320, minH:330, mount:mountNames },
|
||||
{ id:"birthday",cat:"class", icon:"🎂", w:620, h:560, minW:400, minH:400, mount:mountBirthday },
|
||||
{ id:"schedule", cat:"class", icon:"📅", w:500, h:520, minW:340, minH:340, mount:mountSchedule },
|
||||
{ id:"light", cat:"class", icon:"🚦", w:480, h:440, minW:320, minH:320, mount:mountLight },
|
||||
{ id:"mood", cat:"class", icon:"🌡️", w:530, h:360, minW:350, minH:260, mount:mountMood },
|
||||
{ id:"poll", cat:"class", icon:"📊", w:540, h:500, minW:360, minH:330, mount:mountPoll },
|
||||
{ id:"media", cat:"media", icon:"🎬", w:560, h:420, minW:320, minH:240, mount:mountMedia }
|
||||
|
|
@ -577,8 +578,10 @@ function makeMovable(t){
|
|||
const px = (e.clientX - r.left) * (board.clientWidth / r.width);
|
||||
const py = (e.clientY - r.top) * (board.clientHeight / r.height);
|
||||
const hit = nearestEdge(px, py);
|
||||
if(hit && hit.d <= 24){ startInkStroke(e, 24); return; }
|
||||
if(hit && hit.d <= 24){ startInkStroke(e, true); return; }
|
||||
}
|
||||
/* vastgezet gereedschap verschuift en draait niet meer (slot-knop) */
|
||||
if(t._locked) return;
|
||||
if(e.target.classList.contains("dtool-rot")){
|
||||
const r = t.getBoundingClientRect();
|
||||
const cx = r.left+r.width/2, cy = r.top+r.height/2;
|
||||
|
|
@ -661,6 +664,7 @@ function toggleDTool(kind){
|
|||
<div class="dtool-opts">
|
||||
<button class="do-len do-wide"></button>
|
||||
<button class="do-hc">◐</button>
|
||||
<button class="do-lock">🔓</button>
|
||||
</div>`;
|
||||
t.querySelector(".do-len").addEventListener("click", ()=>{
|
||||
t._cm = RULER_CMS[(RULER_CMS.indexOf(t._cm)+1) % RULER_CMS.length]; drawRuler();
|
||||
|
|
@ -764,6 +768,7 @@ function toggleDTool(kind){
|
|||
<button class="do-len do-wide"></button>
|
||||
<button class="do-mode do-wide"></button>
|
||||
<button class="do-hc">◐</button>
|
||||
<button class="do-lock">🔓</button>
|
||||
</div>`;
|
||||
t.querySelector(".do-len").addEventListener("click", ()=>{
|
||||
t._cm = GEO_CMS[(GEO_CMS.indexOf(t._cm)+1) % GEO_CMS.length]; drawGeo();
|
||||
|
|
@ -852,6 +857,18 @@ function toggleDTool(kind){
|
|||
const rot = document.createElement("button");
|
||||
rot.className = "dtool-rot"; rot.textContent = "↻";
|
||||
t.appendChild(rot);
|
||||
/* slot: zet het gereedschap vast op zijn plek - niets kan hem meer
|
||||
verschuiven of draaien, zodat er rustig langs getekend kan worden */
|
||||
const lockBtn = t.querySelector(".do-lock");
|
||||
const syncLock = ()=>{
|
||||
lockBtn.textContent = t._locked ? "🔒" : "🔓";
|
||||
lockBtn.title = T("dtLock");
|
||||
lockBtn.setAttribute("aria-pressed", String(!!t._locked));
|
||||
lockBtn.classList.toggle("on", !!t._locked);
|
||||
rot.style.display = t._locked ? "none" : "";
|
||||
};
|
||||
lockBtn.addEventListener("click", ()=>{ t._locked = !t._locked; syncLock(); });
|
||||
syncLock();
|
||||
}
|
||||
makeMovable(t);
|
||||
board.appendChild(t);
|
||||
|
|
@ -952,22 +969,31 @@ function snapPoint(x, y){
|
|||
/* start van een haal; ook aanroepbaar vanaf de liniaal/geodriehoek zelf
|
||||
(pen op de randzone van de lat = tekenen, niet verslepen) - de pointer
|
||||
capture op bInk stuurt de vervolg-events vanzelf hierheen.
|
||||
snapDist: naast de lat een kleine zone (10px, anders "grijpt" de lat
|
||||
halen die vrij bedoeld zijn), óp de lat zelf ruimer (24px, zie makeMovable). */
|
||||
function startInkStroke(e, snapDist = 10){
|
||||
Naast de lat beslist de RICHTING: binnen 22px van een rand wachten we de
|
||||
eerste ~7px beweging af; loopt die grofweg evenwijdig aan de rand (≤30°),
|
||||
dan kleeft de haal - anders blijft hij vrij. Zo grijpt de lat geen vrije
|
||||
halen en werkt langs de rand tekenen toch betrouwbaar. Op de lat zelf
|
||||
(fromTool) is de intentie ondubbelzinnig en kleeft de haal direct. */
|
||||
let bPend = null;
|
||||
function startInkStroke(e, fromTool = false){
|
||||
if(PEN.tool==="text"){ startBoardText(e); return; }
|
||||
bInk.setPointerCapture(e.pointerId);
|
||||
bDraw = true;
|
||||
PEN.nib = PEN.size*0.8;
|
||||
[bx,by] = bPos(e);
|
||||
bSnap = null;
|
||||
bSnap = null; bPend = null;
|
||||
bMidX = bMidY = null;
|
||||
if(PEN.tool!=="erase" && PEN.tool!=="hand"){
|
||||
const k = bInk.width / board.clientWidth;
|
||||
const hit = nearestEdge(bx/k, by/k);
|
||||
if(hit && hit.d <= snapDist) bSnap = hit;
|
||||
if(fromTool){
|
||||
if(hit && hit.d <= 24) bSnap = hit;
|
||||
}else if(hit && hit.d <= 22){
|
||||
bPend = { x0:bx, y0:by, hit };
|
||||
return; /* nog niets tekenen; de eerste beweging beslist (flush hieronder) */
|
||||
}
|
||||
}
|
||||
[bx,by] = snapPoint(bx, by);
|
||||
bMidX = bMidY = null;
|
||||
bStroke(bx+0.01, by+0.01, e.pressure, e.pointerType);
|
||||
}
|
||||
bInk.addEventListener("pointerdown", e=>{
|
||||
|
|
@ -979,11 +1005,30 @@ bInk.addEventListener("pointermove", e=>{
|
|||
if(!bDraw) return;
|
||||
(e.getCoalescedEvents ? e.getCoalescedEvents() : [e]).forEach(ev=>{
|
||||
const [rx,ry] = bPos(ev);
|
||||
if(bPend){
|
||||
const k = bInk.width / board.clientWidth;
|
||||
const dx = rx - bPend.x0, dy = ry - bPend.y0;
|
||||
if(Math.hypot(dx, dy)/k < 7) return; /* nog te weinig beweging om te beslissen */
|
||||
const move = Math.atan2(dy, dx), edge = Math.atan2(bPend.hit.uy, bPend.hit.ux);
|
||||
let diff = Math.abs(move - edge) % Math.PI;
|
||||
diff = Math.min(diff, Math.PI - diff);
|
||||
if(diff <= Math.PI/6) bSnap = bPend.hit;
|
||||
const [sx, sy] = snapPoint(bPend.x0, bPend.y0);
|
||||
bx = sx; by = sy; bMidX = bMidY = null;
|
||||
bStroke(sx+0.01, sy+0.01, ev.pressure, ev.pointerType);
|
||||
bPend = null;
|
||||
}
|
||||
const [x,y] = snapPoint(rx, ry);
|
||||
bStroke(x, y, ev.pressure, ev.pointerType);
|
||||
});
|
||||
});
|
||||
const bStop = ()=>{
|
||||
if(bDraw && bPend){
|
||||
/* tik zonder beweging vlak naast de lat: gewoon een vrije stip zetten */
|
||||
bx = bPend.x0; by = bPend.y0; bMidX = bMidY = null;
|
||||
bStroke(bx+0.01, by+0.01, 0, "mouse");
|
||||
bPend = null;
|
||||
}
|
||||
if(bDraw){
|
||||
/* markeerstift: de haal staat dekkend op de overlay - nu in één keer
|
||||
met vaste transparantie op de inktlaag zetten (egale kleur, geen
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"use strict";
|
||||
/* version — shown until /api/version resolves (or if the fetch fails, e.g. offline).
|
||||
Kept in sync by hand with the VERSION file at the repo root on every release. */
|
||||
const VERSION = "0.3.75-beta";
|
||||
const VERSION = "0.3.76-beta";
|
||||
(function(){
|
||||
const tag = document.getElementById("verTag");
|
||||
tag.textContent = "v"+VERSION;
|
||||
|
|
@ -96,15 +96,16 @@ const I18N = {
|
|||
wFull:"Maximaliseren", wUnfull:"Terugzetten",
|
||||
wZoom:"Inhoud groter of kleiner (voor slechtzienden)",
|
||||
wg_flits:"Flitswoorden", wg_flits_d:"Een woord flitst kort in beeld – lezen voordat het verdwijnt!",
|
||||
flFlash:"⚡ Flits", flShow:"👁 Toon", flNext:"Volgende ▸", flSec:"sec",
|
||||
flFlash:"⚡ Flits", flShow:"👁 Toon", flNext:"Volgende ▸", flSec:"sec", flMission:"Lees het woord voordat het verdwijnt.", flQuestion:"Kon je het woord zelf lezen?", flGotIt:"🌟 Gelukt!", flAgain:"Nog oefenen", flScore:"{score} sterren",
|
||||
wg_dice:"Dobbelstenen", wg_dice_d:"Gooi 1, 2 of 3 grote dobbelstenen.",
|
||||
diceRoll:"🎲 Gooi!", diceSum:"Samen",
|
||||
wg_light:"Stoplicht", wg_light_d:"Rood, oranje of groen – bijvoorbeeld voor het werkrumoer.",
|
||||
diceRoll:"🎲 Gooi!", diceSum:"Samen", diceMission:"Gooi, tel de ogen en controleer de uitkomst.", diceHistory:"Vorige worpen",
|
||||
wg_light:"Klassenstoplicht", wg_light_d:"Maak in één oogopslag duidelijk of kinderen luisteren, fluisteren of rustig mogen werken.",
|
||||
lightRed:"Rood", lightRedHint:"Stop en luister", lightOrange:"Oranje", lightOrangeHint:"Fluister en rond af", lightGreen:"Groen", lightGreenHint:"Je mag rustig werken", lightStatus:"{color}: {hint}",
|
||||
wg_names:"Namenkiezer", wg_names_d:"Kies willekeurig een naam uit de klas.",
|
||||
namesPh:"Eén naam per regel…", namesPick:"🎯 Kies!", namesNoRep:"Zonder herhaling",
|
||||
namesDone:"Iedereen is geweest! 🎉",
|
||||
namesDone:"Iedereen is geweest! 🎉", namesReset:"Opnieuw", namesProgress:"{used} van {total} geweest",
|
||||
wg_hak:"Hakken & plakken", wg_hak_d:"Woorden in klanken hakken en weer plakken, met voorlezen.",
|
||||
hakChop:"✂️ Hak", hakGlue:"🔗 Plak", hakSay:"🔊 Lees voor",
|
||||
hakChop:"✂️ Hak", hakGlue:"🔗 Plak", hakSay:"🔊 Lees voor", hakHint:"Bekijk en hoor de klankgroepen in het woord.",
|
||||
wg_ball:"Ballonnenwoord", wg_ball_d:"Raad het woord letter voor letter voordat de ballonnen knappen.",
|
||||
wg_anchor:"Ankerwoorden", wg_anchor_d:"Woordweb voor woordenschatonderwijs: leer woorden in samenhang rond een themawoord (het anker), met plaatjes. Elk woord verankert aan de woorden eromheen.",
|
||||
fabAnchor:"Ankerdiagram (woordweb)",
|
||||
|
|
@ -114,15 +115,15 @@ const I18N = {
|
|||
birthdaySprinkles:"Spikkels", birthdayFruit:"Fruit", birthdayStars:"Sterren", birthdayNone:"Geen versiering",
|
||||
wg_numberline:"Getallenlijn", wg_numberline_d:"Oefen getalbegrip met een instelbare, interactieve getallenlijn.",
|
||||
numberlineFrom:"Van", numberlineTo:"Tot", numberlineStep:"Stap", numberlineNew:"Nieuwe opdracht", numberlineTask:"Zet de stip op {number}",
|
||||
numberlineCheck:"Controleren", numberlineGood:"Goed gevonden! 🌟", numberlineTry:"Kijk nog eens naar de getallenlijn.",
|
||||
wg_fractions:"Breukenmuur", wg_fractions_d:"Vergelijk breuken visueel en markeer gelijke delen.",
|
||||
numberlineCheck:"Controleren", numberlineGood:"Goed gevonden! 🌟", numberlineTry:"Kijk nog eens naar de getallenlijn.", numberlineScore:"{score} sterren · reeks {streak}",
|
||||
wg_fractions:"Breukenmuur", wg_fractions_d:"Bouw breuken, vergelijk de gekleurde delen en ontdek gelijkwaardige breuken.",
|
||||
wg_clock:"Oefenklok", wg_clock_d:"Leer kloktijden op vier niveaus met meerdere leerwijzen en spellen.",
|
||||
wg_placevalue:"Plaatswaardetabel", wg_placevalue_d:"Ontdek de waarde van cijfers tot honderdduizend.",
|
||||
wg_money:"Geldrekenen", wg_money_d:"Oefen bedragen maken, geld tellen en wisselgeld op drie niveaus.",
|
||||
wg_trees:"Bomen & bladeren", wg_trees_d:"Leer achttien Nederlandse boomsoorten met vijf foto-, kenmerk- en koppeloefeningen.",
|
||||
wg_birds:"Vogels herkennen", wg_birds_d:"Leer achttien Nederlandse vogels met vier foto-, kenmerk- en naamoefeningen.",
|
||||
wg_plants:"Wilde planten", wg_plants_d:"Herken twaalf algemene wilde planten aan echte foto's en duidelijke veldkenmerken.",
|
||||
wg_topography:"Topografie Nederland", wg_topography_d:"Oefen provincies, plaatsen, landsdelen, rivieren en werelddelen op nauwkeurige kaarten.",
|
||||
wg_topography:"Topografie", wg_topography_d:"Oefen Nederland én de wereld: provincies, plaatsen, landsdelen, rivieren en werelddelen op nauwkeurige kaarten.",
|
||||
worldActivity:"Werkvorm", worldLearn:"Leren", worldQuiz:"Quiz", worldExercise:"Oefening", worldLevel:"Niveau", worldTreeView:"Wat zie je?", worldTreeWhole:"Hele boom", worldTreeLeaf:"Blad", worldTreeMixed:"Boom en blad",
|
||||
worldExerciseRecognize:"Herken de soort", worldExercisePair:"Koppel boom en blad", worldExerciseClue:"Raad met kenmerken", worldExercisePhoto:"Kies de juiste foto", worldExerciseLatin:"Wetenschappelijke naam",
|
||||
worldScore:"Score: {score} · reeks: {streak}", worldExploreHint:"Bekijk de kenmerken en vergelijk de soorten.", worldQuestionTree:"Welke boom zie je?", worldQuestionLeaf:"Bij welke boom hoort dit blad?", worldQuestionBird:"Welke vogel zie je?", worldQuestionPlant:"Welke wilde plant zie je?",
|
||||
|
|
@ -146,10 +147,10 @@ const I18N = {
|
|||
wg_mood:"Gevoelsmeter", wg_mood_d:"Doe een snelle, anonieme check-in met de klas.",
|
||||
wg_poll:"Klaspoll", wg_poll_d:"Stem samen op maximaal zes antwoorden.",
|
||||
clock24Hour:"24-uursklok",
|
||||
widgetSettings:"Instellingen", clockWelcome:"Oefenen met de klok", clockWelcomeHint:"Kies bovenaan niveau 1, 2 of 3. Kies bij Instellingen hoe de opdracht wordt getoond en start daarna.", clockSetTitle:"Zet de wijzers op de goede tijd", clockReadTitle:"Bekijk de opdracht en maak de tijd", clockChooseTitle:"Kies het juiste tijdblok", clockYourTask:"Jouw opdracht", clockLinkHands:"Grote wijzer draait mee", clockTypeHint:"Voer de tijd in als UU:MM.", clockLevel1Hint:"Niveau 1: hele en halve uren", clockLevel2Hint:"Niveau 2: stappen van vijf minuten", clockLevel3Hint:"Niveau 3: alle minuten, met optioneel 24 uur en dagdelen", clockBuildHint:"Sleep vier cijfers naar de vakken en maak UU:MM.", clockDigitGhost:"?", clockDigit:"Cijfer {digit}", clockIncomplete:"Maak eerst de volledige tijd af.", clockCorrect:"Goed gedaan! Kies de volgende opdracht. 🌟", clockTryAgain:"Bijna! Probeer het nog een keer.", clockStartTask:"Start opdracht", clockNextTask:"Volgende opdracht", clockLevel:"Niveau", clockLevelHour:"Hele uren", clockLevelQuarter:"Kwartieren", clockLevelFive:"Vijf minuten", clockLevelMinute:"Iedere minuut", clockLearningStyle:"Opdracht tonen", clockStyleAnalogue:"Analoge klok", clockStyleDigital:"Grote digitale tijd", clockStyleWords:"In woorden", clockStyleBoth:"Klok, cijfers en woorden", clockDragHint:"Sleep de wijzers om de tijd te veranderen.", clockGame:"Spel", clockGameSet:"Klok zetten", clockGameRead:"Tijd aflezen", clockGameChoose:"Kies de tijd", clockStart:"Kies ‘Nieuwe opdracht’ om te beginnen", clockRead:"Welke tijd zie je? Stel je antwoord hieronder in.", clockChoose:"Welke digitale tijd hoort bij deze klok?", clockTry:"Nog niet. Het goede antwoord is {time}.", clockScore:"Score: {score} · reeks: {streak}", clockWordsHour:"{hour} uur", clockWordsQuarterPast:"kwart over {hour}", clockWordsHalf:"half {hour}", clockWordsQuarterTo:"kwart voor {hour}", clockWordsPast:"{minutes} over {hour}", clockWordsTo:"{minutes} voor {hour}", clockMorning:"in de ochtend", clockAfternoon:"in de middag", clockEvening:"in de avond", clockNight:"in de nacht", fractionRows:"Rijen", fractionLabels:"Breuken tonen", clockTask:"Oefenopdracht", clockSet:"Zet de klok op {time}", clockHour:"Uur", clockMinute:"Minuten", placeNumber:"Getal", moneyMake:"Maak € {amount}", wordtypeSentence:"Zin", wordtypeHint:"Tik: blauw zelfstandig naamwoord · groen werkwoord · geel bijvoeglijk naamwoord", scheduleActivity:"activiteit…", scheduleEmpty:"Voeg de eerste activiteit toe.", pollReset:"Opnieuw", pollQuestion:"Vraag", pollOptions:"Antwoorden (één per regel)", galleryFavorites:"Favorieten", galleryFavorite:"Favoriet maken", galleryEmpty:"Geen widgets gevonden.", gallerySearch:"Zoek widgets…", templateMath:"Rekenles", templateLanguage:"Taalles", templateDay:"Dagstart", exportBoard:"Exporteren", importBoard:"Importeren", importError:"Dit is geen geldig Teach-bordbestand.", widgetDuplicate:"Dupliceren", widgetLock:"Vastzetten", widgetUnlock:"Losmaken", widgetPreview:"Voorbeeld zonder bediening", undo:"Ongedaan maken", redo:"Opnieuw",
|
||||
widgetSettings:"Instellingen", clockWelcome:"Oefenen met de klok", clockWelcomeHint:"Kies bovenaan niveau 1, 2 of 3. Kies bij Instellingen hoe de opdracht wordt getoond en start daarna.", clockSetTitle:"Zet de wijzers op de goede tijd", clockReadTitle:"Bekijk de opdracht en maak de tijd", clockChooseTitle:"Kies het juiste tijdblok", clockYourTask:"Jouw opdracht", clockLinkHands:"Grote wijzer draait mee", clockTypeHint:"Voer de tijd in als UU:MM.", clockLevel1Hint:"Niveau 1: hele en halve uren", clockLevel2Hint:"Niveau 2: stappen van vijf minuten", clockLevel3Hint:"Niveau 3: alle minuten, met optioneel 24 uur en dagdelen", clockBuildHint:"Sleep vier cijfers naar de vakken en maak UU:MM.", clockDigitGhost:"?", clockDigit:"Cijfer {digit}", clockIncomplete:"Maak eerst de volledige tijd af.", clockCorrect:"Goed gedaan! Kies de volgende opdracht. 🌟", clockTryAgain:"Bijna! Probeer het nog een keer.", clockStartTask:"Start opdracht", clockNextTask:"Volgende opdracht", clockLevel:"Niveau", clockLevelHour:"Hele uren", clockLevelQuarter:"Kwartieren", clockLevelFive:"Vijf minuten", clockLevelMinute:"Iedere minuut", clockLearningStyle:"Opdracht tonen", clockStyleAnalogue:"Analoge klok", clockStyleDigital:"Grote digitale tijd", clockStyleWords:"In woorden", clockStyleBoth:"Klok, cijfers en woorden", clockDragHint:"Sleep de wijzers om de tijd te veranderen.", clockGame:"Spel", clockGameSet:"Klok zetten", clockGameRead:"Tijd aflezen", clockGameChoose:"Kies de tijd", clockStart:"Kies ‘Nieuwe opdracht’ om te beginnen", clockRead:"Welke tijd zie je? Stel je antwoord hieronder in.", clockChoose:"Welke digitale tijd hoort bij deze klok?", clockTry:"Nog niet. Het goede antwoord is {time}.", clockScore:"Score: {score} · reeks: {streak}", clockWordsHour:"{hour} uur", clockWordsQuarterPast:"kwart over {hour}", clockWordsHalf:"half {hour}", clockWordsQuarterTo:"kwart voor {hour}", clockWordsPast:"{minutes} over {hour}", clockWordsTo:"{minutes} voor {hour}", clockMorning:"in de ochtend", clockAfternoon:"in de middag", clockEvening:"in de avond", clockNight:"in de nacht", fractionRows:"Rijen", fractionLabels:"Breuken tonen", fractionHint:"Tik in een rij tot waar je de breuk wilt kleuren.", fractionSelected:"Gekozen breuk: {fraction}", fractionClear:"Leegmaken", clockTask:"Oefenopdracht", clockSet:"Zet de klok op {time}", clockHour:"Uur", clockMinute:"Minuten", placeNumber:"Getal", moneyMake:"Maak € {amount}", wordtypeSentence:"Zin", wordtypeHint:"Tik: blauw zelfstandig naamwoord · groen werkwoord · geel bijvoeglijk naamwoord", scheduleActivity:"activiteit…", scheduleEmpty:"Voeg de eerste activiteit toe.", scheduleCount:"{count} momenten op de planning", pollReset:"Opnieuw", pollQuestion:"Vraag", pollOptions:"Antwoorden (één per regel)", pollTotal:"{count} stemmen", moodTotal:"{count} kinderen hebben gekozen", moodVote:"Kies {face}", galleryFavorites:"Favorieten", galleryFavorite:"Favoriet maken", galleryEmpty:"Geen widgets gevonden.", gallerySearch:"Zoek widgets…", templateMath:"Rekenles", templateLanguage:"Taalles", templateDay:"Dagstart", exportBoard:"Exporteren", importBoard:"Importeren", importError:"Dit is geen geldig Teach-bordbestand.", widgetDuplicate:"Dupliceren", widgetLock:"Vastzetten", widgetUnlock:"Losmaken", widgetPreview:"Voorbeeld zonder bediening", undo:"Ongedaan maken", redo:"Opnieuw",
|
||||
wg_sentence:"Zinsbouwer", wg_sentence_d:"Bouw zinnen met kleurgecodeerde zinsdelen en voeg eigen woorden toe.",
|
||||
sentence_who:"Wie?", sentence_does:"Doet wat?", sentence_what:"Wat of waar?", sentenceHint:"Kies woorden om een zin te maken…",
|
||||
sentenceAdd:"eigen woord of zinsdeel…", sentenceClear:"Wissen", sentenceSpeak:"🔊 Lees voor", sentenceRemove:"Verwijder woord",
|
||||
sentenceAdd:"eigen woord of zinsdeel…", sentenceClear:"Wissen", sentenceSpeak:"🔊 Lees voor", sentenceRemove:"Verwijder woord", sentenceSurprise:"✨ Verrassingszin",
|
||||
anchorPh:"thema…", anchorHint:"Woordweb: zet het themawoord in het midden en bouw eromheen · tik op een vak en typ · sleep om te schuiven",
|
||||
anchorHintReadonly:"Sleep de achtergrond om te schuiven",
|
||||
anchorColor:"Kleur: klik om te wisselen (verbind woorden met dezelfde kleur)",
|
||||
|
|
@ -245,6 +246,7 @@ const I18N = {
|
|||
parentUnlinkWarn:"Verwijdert alleen de koppeling; het account van je kind blijft bestaan.",
|
||||
parentProgress:"📈 Voortgang", parentProgressEmpty:"Nog geen voortgang.",
|
||||
dtLen:"Lengte", dtContrast:"Hoog contrast",
|
||||
dtLock:"Vastzetten: kan niet meer verschuiven of draaien, alleen nog langs tekenen",
|
||||
dtMode:"Basis: grote hoofdhoeken en hele centimeters. Volledig: graden per 2° met dubbele schaal, millimeters en evenwijdige hulplijnen.",
|
||||
dtModeBasic:"basis", dtModeFull:"volledig",
|
||||
pupilEmpty:"Je leerkracht heeft nog niets voor je klaargezet.",
|
||||
|
|
@ -370,15 +372,16 @@ const I18N = {
|
|||
wFull:"Maximize", wUnfull:"Restore",
|
||||
wZoom:"Content bigger or smaller (low vision)",
|
||||
wg_flits:"Flash words", wg_flits_d:"A word flashes briefly – read it before it disappears!",
|
||||
flFlash:"⚡ Flash", flShow:"👁 Show", flNext:"Next ▸", flSec:"sec",
|
||||
flFlash:"⚡ Flash", flShow:"👁 Show", flNext:"Next ▸", flSec:"sec", flMission:"Read the word before it disappears.", flQuestion:"Could you read the word by yourself?", flGotIt:"🌟 Got it!", flAgain:"Practise again", flScore:"{score} stars",
|
||||
wg_dice:"Dice", wg_dice_d:"Roll 1, 2 or 3 big dice.",
|
||||
diceRoll:"🎲 Roll!", diceSum:"Total",
|
||||
wg_light:"Traffic light", wg_light_d:"Red, orange or green – e.g. for classroom noise.",
|
||||
diceRoll:"🎲 Roll!", diceSum:"Total", diceMission:"Roll, count the dots and check the total.", diceHistory:"Previous rolls",
|
||||
wg_light:"Class traffic light", wg_light_d:"Show at a glance whether children listen, whisper or work quietly.",
|
||||
lightRed:"Red", lightRedHint:"Stop and listen", lightOrange:"Amber", lightOrangeHint:"Whisper and finish", lightGreen:"Green", lightGreenHint:"You may work quietly", lightStatus:"{color}: {hint}",
|
||||
wg_names:"Name picker", wg_names_d:"Pick a random name from the class.",
|
||||
namesPh:"One name per line…", namesPick:"🎯 Pick!", namesNoRep:"No repeats",
|
||||
namesDone:"Everyone has had a turn! 🎉",
|
||||
namesDone:"Everyone has had a turn! 🎉", namesReset:"Start over", namesProgress:"{used} of {total} picked",
|
||||
wg_hak:"Chop & blend", wg_hak_d:"Chop words into sounds and blend them back, with read-aloud.",
|
||||
hakChop:"✂️ Chop", hakGlue:"🔗 Blend", hakSay:"🔊 Read aloud",
|
||||
hakChop:"✂️ Chop", hakGlue:"🔗 Blend", hakSay:"🔊 Read aloud", hakHint:"See and hear the sound groups in the word.",
|
||||
wg_ball:"Balloon word", wg_ball_d:"Guess the word letter by letter before the balloons pop.",
|
||||
wg_anchor:"Anchor words", wg_anchor_d:"Word web for vocabulary teaching: learn words in meaningful clusters around a theme word (the anchor), with pictures. Every word anchors to its neighbours.",
|
||||
fabAnchor:"Anchor diagram (word web)",
|
||||
|
|
@ -388,15 +391,15 @@ const I18N = {
|
|||
birthdaySprinkles:"Sprinkles", birthdayFruit:"Fruit", birthdayStars:"Stars", birthdayNone:"No decoration",
|
||||
wg_numberline:"Number line", wg_numberline_d:"Practise number sense with an adjustable, interactive number line.",
|
||||
numberlineFrom:"From", numberlineTo:"To", numberlineStep:"Step", numberlineNew:"New task", numberlineTask:"Move the marker to {number}",
|
||||
numberlineCheck:"Check", numberlineGood:"Well done! 🌟", numberlineTry:"Take another look at the number line.",
|
||||
wg_fractions:"Fraction wall", wg_fractions_d:"Compare fractions visually and mark equal parts.",
|
||||
numberlineCheck:"Check", numberlineGood:"Well done! 🌟", numberlineTry:"Take another look at the number line.", numberlineScore:"{score} stars · streak {streak}",
|
||||
wg_fractions:"Fraction wall", wg_fractions_d:"Build fractions, compare coloured parts and discover equivalent fractions.",
|
||||
wg_clock:"Practice clock", wg_clock_d:"Learn time at four levels with multiple learning styles and games.",
|
||||
wg_placevalue:"Place value", wg_placevalue_d:"Explore digit values up to hundred thousands.",
|
||||
wg_money:"Money", wg_money_d:"Practise making amounts, counting money and change at three levels.",
|
||||
wg_trees:"Trees & leaves", wg_trees_d:"Learn eighteen Dutch tree species with five photo, feature and matching exercises.",
|
||||
wg_birds:"Bird identification", wg_birds_d:"Learn eighteen Dutch birds with four photo, feature and naming exercises.",
|
||||
wg_plants:"Wild plants", wg_plants_d:"Recognise twelve common wild plants from real photographs and clear field marks.",
|
||||
wg_topography:"Map of the Netherlands", wg_topography_d:"Practise provinces, places, regions, rivers and continents on accurate maps.",
|
||||
wg_topography:"Topography", wg_topography_d:"Practise the Netherlands and the world: provinces, places, regions, rivers and continents on accurate maps.",
|
||||
worldActivity:"Activity", worldLearn:"Learn", worldQuiz:"Quiz", worldExercise:"Exercise", worldLevel:"Level", worldTreeView:"What do you see?", worldTreeWhole:"Whole tree", worldTreeLeaf:"Leaf", worldTreeMixed:"Tree and leaf",
|
||||
worldExerciseRecognize:"Recognise the species", worldExercisePair:"Match tree and leaf", worldExerciseClue:"Guess from features", worldExercisePhoto:"Choose the correct photo", worldExerciseLatin:"Scientific name",
|
||||
worldScore:"Score: {score} · streak: {streak}", worldExploreHint:"Study the features and compare the species.", worldQuestionTree:"Which tree do you see?", worldQuestionLeaf:"Which tree does this leaf belong to?", worldQuestionBird:"Which bird do you see?", worldQuestionPlant:"Which wild plant do you see?",
|
||||
|
|
@ -420,10 +423,10 @@ const I18N = {
|
|||
wg_mood:"Mood check-in", wg_mood_d:"Run a quick anonymous class check-in.",
|
||||
wg_poll:"Class poll", wg_poll_d:"Vote together on up to six answers.",
|
||||
clock24Hour:"24-hour clock",
|
||||
widgetSettings:"Settings", clockWelcome:"Practise telling time", clockWelcomeHint:"Choose level 1, 2 or 3 at the top. In Settings, choose how the task is shown, then start.", clockSetTitle:"Move the hands to the correct time", clockReadTitle:"View the task and make the time", clockChooseTitle:"Choose the correct time block", clockYourTask:"Your task", clockLinkHands:"Move the minute hand along", clockTypeHint:"Enter the time as HH:MM.", clockLevel1Hint:"Level 1: whole and half hours", clockLevel2Hint:"Level 2: five-minute steps", clockLevel3Hint:"Level 3: every minute, with optional 24-hour time and day parts", clockBuildHint:"Drag four digits into the slots to make HH:MM.", clockDigitGhost:"?", clockDigit:"Digit {digit}", clockIncomplete:"Complete the full time first.", clockCorrect:"Well done! Choose the next task. 🌟", clockTryAgain:"Almost! Try again.", clockStartTask:"Start task", clockNextTask:"Next task", clockLevel:"Level", clockLevelHour:"Whole hours", clockLevelQuarter:"Quarter hours", clockLevelFive:"Five minutes", clockLevelMinute:"Every minute", clockLearningStyle:"Show task as", clockStyleAnalogue:"Analogue clock", clockStyleDigital:"Large digital time", clockStyleWords:"In words", clockStyleBoth:"Clock, digits and words", clockDragHint:"Drag the hands to change the time.", clockGame:"Game", clockGameSet:"Set the clock", clockGameRead:"Read the time", clockGameChoose:"Choose the time", clockStart:"Choose ‘New task’ to begin", clockRead:"What time is it? Set your answer below.", clockChoose:"Which digital time matches this clock?", clockTry:"Not yet. The correct answer is {time}.", clockScore:"Score: {score} · streak: {streak}", clockWordsHour:"{hour} o'clock", clockWordsQuarterPast:"quarter past {hour}", clockWordsHalf:"half past {hour}", clockWordsQuarterTo:"quarter to {hour}", clockWordsPast:"{minutes} past {hour}", clockWordsTo:"{minutes} to {hour}", clockMorning:"in the morning", clockAfternoon:"in the afternoon", clockEvening:"in the evening", clockNight:"at night", fractionRows:"Rows", fractionLabels:"Show fractions", clockTask:"Practice task", clockSet:"Set the clock to {time}", clockHour:"Hour", clockMinute:"Minutes", placeNumber:"Number", moneyMake:"Make € {amount}", wordtypeSentence:"Sentence", wordtypeHint:"Tap: blue noun · green verb · yellow adjective", scheduleActivity:"activity…", scheduleEmpty:"Add the first activity.", pollReset:"Reset", pollQuestion:"Question", pollOptions:"Answers (one per line)", galleryFavorites:"Favourites", galleryFavorite:"Add favourite", galleryEmpty:"No widgets found.", gallerySearch:"Search widgets…", templateMath:"Maths lesson", templateLanguage:"Language lesson", templateDay:"Day start", exportBoard:"Export", importBoard:"Import", importError:"This is not a valid Teach board file.", widgetDuplicate:"Duplicate", widgetLock:"Lock", widgetUnlock:"Unlock", widgetPreview:"Preview without controls", undo:"Undo", redo:"Redo",
|
||||
widgetSettings:"Settings", clockWelcome:"Practise telling time", clockWelcomeHint:"Choose level 1, 2 or 3 at the top. In Settings, choose how the task is shown, then start.", clockSetTitle:"Move the hands to the correct time", clockReadTitle:"View the task and make the time", clockChooseTitle:"Choose the correct time block", clockYourTask:"Your task", clockLinkHands:"Move the minute hand along", clockTypeHint:"Enter the time as HH:MM.", clockLevel1Hint:"Level 1: whole and half hours", clockLevel2Hint:"Level 2: five-minute steps", clockLevel3Hint:"Level 3: every minute, with optional 24-hour time and day parts", clockBuildHint:"Drag four digits into the slots to make HH:MM.", clockDigitGhost:"?", clockDigit:"Digit {digit}", clockIncomplete:"Complete the full time first.", clockCorrect:"Well done! Choose the next task. 🌟", clockTryAgain:"Almost! Try again.", clockStartTask:"Start task", clockNextTask:"Next task", clockLevel:"Level", clockLevelHour:"Whole hours", clockLevelQuarter:"Quarter hours", clockLevelFive:"Five minutes", clockLevelMinute:"Every minute", clockLearningStyle:"Show task as", clockStyleAnalogue:"Analogue clock", clockStyleDigital:"Large digital time", clockStyleWords:"In words", clockStyleBoth:"Clock, digits and words", clockDragHint:"Drag the hands to change the time.", clockGame:"Game", clockGameSet:"Set the clock", clockGameRead:"Read the time", clockGameChoose:"Choose the time", clockStart:"Choose ‘New task’ to begin", clockRead:"What time is it? Set your answer below.", clockChoose:"Which digital time matches this clock?", clockTry:"Not yet. The correct answer is {time}.", clockScore:"Score: {score} · streak: {streak}", clockWordsHour:"{hour} o'clock", clockWordsQuarterPast:"quarter past {hour}", clockWordsHalf:"half past {hour}", clockWordsQuarterTo:"quarter to {hour}", clockWordsPast:"{minutes} past {hour}", clockWordsTo:"{minutes} to {hour}", clockMorning:"in the morning", clockAfternoon:"in the afternoon", clockEvening:"in the evening", clockNight:"at night", fractionRows:"Rows", fractionLabels:"Show fractions", fractionHint:"Tap a row up to the part you want to colour.", fractionSelected:"Selected fraction: {fraction}", fractionClear:"Clear", clockTask:"Practice task", clockSet:"Set the clock to {time}", clockHour:"Hour", clockMinute:"Minutes", placeNumber:"Number", moneyMake:"Make € {amount}", wordtypeSentence:"Sentence", wordtypeHint:"Tap: blue noun · green verb · yellow adjective", scheduleActivity:"activity…", scheduleEmpty:"Add the first activity.", scheduleCount:"{count} moments in the schedule", pollReset:"Reset", pollQuestion:"Question", pollOptions:"Answers (one per line)", pollTotal:"{count} votes", moodTotal:"{count} children have chosen", moodVote:"Choose {face}", galleryFavorites:"Favourites", galleryFavorite:"Add favourite", galleryEmpty:"No widgets found.", gallerySearch:"Search widgets…", templateMath:"Maths lesson", templateLanguage:"Language lesson", templateDay:"Day start", exportBoard:"Export", importBoard:"Import", importError:"This is not a valid Teach board file.", widgetDuplicate:"Duplicate", widgetLock:"Lock", widgetUnlock:"Unlock", widgetPreview:"Preview without controls", undo:"Undo", redo:"Redo",
|
||||
wg_sentence:"Sentence builder", wg_sentence_d:"Build sentences with colour-coded parts and add your own words.",
|
||||
sentence_who:"Who?", sentence_does:"Does what?", sentence_what:"What or where?", sentenceHint:"Choose words to build a sentence…",
|
||||
sentenceAdd:"your own word or phrase…", sentenceClear:"Clear", sentenceSpeak:"🔊 Read aloud", sentenceRemove:"Remove word",
|
||||
sentenceAdd:"your own word or phrase…", sentenceClear:"Clear", sentenceSpeak:"🔊 Read aloud", sentenceRemove:"Remove word", sentenceSurprise:"✨ Surprise sentence",
|
||||
anchorPh:"theme…", anchorHint:"Word web: put the theme word in the middle and build around it · tap a cell and type · drag to pan",
|
||||
anchorHintReadonly:"Drag the background to pan",
|
||||
anchorColor:"Colour: click to cycle (connect words with the same colour)",
|
||||
|
|
@ -464,7 +467,7 @@ const I18N = {
|
|||
imgQuotaMb:"limit in MB", imgQuotaInvalid:"Enter a valid limit.", imgSchools:"Schools",
|
||||
imgUsers:"Users", imgSearchUsers:"Search user…",
|
||||
cats:["Animals","Food","Nature","Transport","Things","Body"],
|
||||
notesPh:"Write here…",
|
||||
notesPh:"Write here…", notesColor:"Note colour", notesLarge:"Large letters", notesCount:"{count} characters",
|
||||
start:"Start", pause:"Pause", reset:"Reset", min:"min",
|
||||
tmDigits:"Digits", tmVisual:"Visual clock", tmBoth:"Both", tmSound:"Sound on/off",
|
||||
tmHint:"Drag the red disc to set the time.",
|
||||
|
|
@ -519,6 +522,7 @@ const I18N = {
|
|||
parentUnlinkWarn:"Removes only the link; your child's account remains.",
|
||||
parentProgress:"📈 Progress", parentProgressEmpty:"No progress yet.",
|
||||
dtLen:"Length", dtContrast:"High contrast",
|
||||
dtLock:"Lock in place: can no longer move or rotate, only draw along it",
|
||||
dtMode:"Basic: big main angles and whole centimetres. Full: degrees every 2° with a double scale, millimetres and parallel guide lines.",
|
||||
dtModeBasic:"basic", dtModeFull:"full",
|
||||
pupilEmpty:"Your teacher hasn't set up anything for you yet.",
|
||||
|
|
|
|||
Loading…
Reference in a new issue