Verbeter anatomie en plaatsing van avataraccessoires (v0.4.46-beta) #1

Open
bes-r wants to merge 192 commits from bes-r/avatar-realism into main AGit
3 changed files with 21 additions and 12 deletions
Showing only changes of commit 63490719d6 - Show all commits

View file

@ -1 +1 @@
0.4.19-beta 0.4.20-beta

View file

@ -2,7 +2,7 @@
"use strict"; "use strict";
/* version shown until /api/version resolves (or if the fetch fails, e.g. offline). /* 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. */ Kept in sync by hand with the VERSION file at the repo root on every release. */
const VERSION = "0.4.19-beta"; const VERSION = "0.4.20-beta";
(function(){ (function(){
const tag = document.getElementById("verTag"); const tag = document.getElementById("verTag");
tag.textContent = "v"+VERSION; tag.textContent = "v"+VERSION;

View file

@ -361,22 +361,30 @@ function worldFlashCard(card,name,visual,S,redraw,onNext,onAssess){
} }
/* ---- letterblokken: spel de naam met dezelfde sleep-blokken-mechaniek als /* ---- letterblokken: spel de naam met dezelfde sleep-blokken-mechaniek als
letters.js, hier gevoed door de naam van de soort/plaats. Elk vak toont letters.js, hier gevoed door de naam van de soort/plaats. Het puntenpatroon
meteen het puntenpatroon (en de letter) van het juiste antwoord - bewust van het juiste antwoord staat altijd in het vak (zelfde tastbare hint als
de makkelijkste ondersteuning, want deze namen zijn voor de meeste overal elders); of de LETTER er ook gewoon bij staat hangt af van het
kinderen onbekende spelling; het quiz/foto/latijn-werk hierboven test niveau, net als bij letters.js: niveau 1 verklapt alles, niveau 2 de
het herkennen al veel strenger. */ helft, niveau 3 niets - alleen de stippen blijven dan over als hint. */
const worldIsLetter=ch=>/\p{L}/u.test(ch); const worldIsLetter=ch=>/\p{L}/u.test(ch);
const worldSpellPool=name=>[...name.toLowerCase()].filter(worldIsLetter); const worldSpellPool=name=>[...name.toLowerCase()].filter(worldIsLetter);
function worldSpellRevealMask(count,level){
if(level===1)return new Array(count).fill(true);
if(level===3)return new Array(count).fill(false);
const hideCount=Math.max(1,Math.min(count-1,Math.round(count/2)));
const hidden=new Set(worldShuffle([...Array(count).keys()]).slice(0,hideCount));
return Array.from({length:count},(_,i)=>!hidden.has(i));
}
function worldSpellNeedsNewTray(S,name){ function worldSpellNeedsNewTray(S,name){
const letters=worldSpellPool(name); const letters=worldSpellPool(name);
return !Array.isArray(S.answerLetters)||S.answerLetters.length!==letters.length||!Array.isArray(S.trayLetters); return !Array.isArray(S.answerLetters)||S.answerLetters.length!==letters.length||!Array.isArray(S.trayLetters)||!Array.isArray(S.revealMask)||S.revealMask.length!==letters.length;
} }
function worldSpellNewTray(S,name){ function worldSpellNewTray(S,name){
const letters=worldSpellPool(name); const letters=worldSpellPool(name);
const distractPool="abcdefghijklmnopqrstuvwxyz".split("").filter(c=>!letters.includes(c)); const distractPool="abcdefghijklmnopqrstuvwxyz".split("").filter(c=>!letters.includes(c));
S.trayLetters=worldShuffle([...letters,...worldShuffle(distractPool).slice(0,4)]); S.trayLetters=worldShuffle([...letters,...worldShuffle(distractPool).slice(0,4)]);
S.answerLetters=letters.map(()=>null); S.answerLetters=letters.map(()=>null);
S.revealMask=worldSpellRevealMask(letters.length,S.level);
S.spellSolved=false; S.spellSolved=false;
} }
function worldLetterBlock(ch,trayIndex,letters,S,redraw){ function worldLetterBlock(ch,trayIndex,letters,S,redraw){
@ -472,7 +480,7 @@ function worldSpellAnswer(name,S,redraw){
slot.dataset.index=idx; slot.dataset.index=idx;
const ghost=document.createElement("div"); const ghost=document.createElement("div");
ghost.className="ghost"; ghost.className="ghost";
ghost.textContent=letters[idx]; ghost.textContent=S.revealMask[idx]?letters[idx]:"?";
const dots=dotGrid(letters[idx]); const dots=dotGrid(letters[idx]);
dots.classList.add("slot-dots"); dots.classList.add("slot-dots");
slot.append(ghost,dots); slot.append(ghost,dots);
@ -506,7 +514,7 @@ function mountWorldQuiz(root,init,config){
const S=Object.assign({ const S=Object.assign({
activity:"quiz",exercise:"recognize",level:1,view:config.type==="trees"?"mixed":config.type==="birds"?"bird":"plant", activity:"quiz",exercise:"recognize",level:1,view:config.type==="trees"?"mixed":config.type==="birds"?"bird":"plant",
score:0,streak:0,target:"",taskView:"",options:[],picked:"",solved:false,feedback:"", score:0,streak:0,target:"",taskView:"",options:[],picked:"",solved:false,feedback:"",
flashRevealed:false,answerLetters:null,trayLetters:null,spellSolved:false, flashRevealed:false,answerLetters:null,trayLetters:null,revealMask:null,spellSolved:false,
},init||{}); },init||{});
S.level=Math.max(1,Math.min(3,+S.level||1)); S.level=Math.max(1,Math.min(3,+S.level||1));
if(!exerciseOptions.some(([id])=>id===S.exercise))S.exercise="recognize"; if(!exerciseOptions.some(([id])=>id===S.exercise))S.exercise="recognize";
@ -538,6 +546,7 @@ function mountWorldQuiz(root,init,config){
S.flashRevealed=false; S.flashRevealed=false;
S.answerLetters=null; S.answerLetters=null;
S.trayLetters=null; S.trayLetters=null;
S.revealMask=null;
S.spellSolved=false; S.spellSolved=false;
draw(); draw();
}; };
@ -933,7 +942,7 @@ function mountTopography(root,init){
const S=Object.assign({ const S=Object.assign({
activity:"quiz",mode:"provinces",level:1,score:0,streak:0, activity:"quiz",mode:"provinces",level:1,score:0,streak:0,
target:"",picked:"",solved:false,feedback:"", target:"",picked:"",solved:false,feedback:"",
flashRevealed:false,answerLetters:null,trayLetters:null,spellSolved:false, flashRevealed:false,answerLetters:null,trayLetters:null,revealMask:null,spellSolved:false,
},init||{}); },init||{});
S.level=Math.max(1,Math.min(3,+S.level||1)); S.level=Math.max(1,Math.min(3,+S.level||1));
if(!modeOptions.some(([id])=>id===S.mode))S.mode="provinces"; if(!modeOptions.some(([id])=>id===S.mode))S.mode="provinces";
@ -955,7 +964,7 @@ function mountTopography(root,init){
let target=items[Math.floor(Math.random()*items.length)]; let target=items[Math.floor(Math.random()*items.length)];
if(items.length>1)while(target.id===previous)target=items[Math.floor(Math.random()*items.length)]; if(items.length>1)while(target.id===previous)target=items[Math.floor(Math.random()*items.length)];
S.target=target.id;S.picked="";S.solved=false;S.feedback=""; S.target=target.id;S.picked="";S.solved=false;S.feedback="";
S.flashRevealed=false;S.answerLetters=null;S.trayLetters=null;S.spellSolved=false; S.flashRevealed=false;S.answerLetters=null;S.trayLetters=null;S.revealMask=null;S.spellSolved=false;
draw(); draw();
}; };
const answer=id=>{ const answer=id=>{