2026-03-12 08:05:10 +00:00
|
|
|
<script src="https://cdn.jsdelivr.net/npm/hanzi-writer@3.5/dist/hanzi-writer.min.js"></script>
|
|
|
|
|
<script>
|
|
|
|
|
function createMyReusableModule() {
|
|
|
|
|
|
|
|
|
|
// Chaque instance possède son propre état
|
|
|
|
|
let iNb = 0;
|
|
|
|
|
let ok = false;
|
|
|
|
|
let hw = null;
|
2026-03-13 00:40:30 +00:00
|
|
|
let datas_length = 0;
|
2026-03-12 08:05:10 +00:00
|
|
|
|
|
|
|
|
function init(options = {}) {
|
|
|
|
|
displayChallenge(
|
|
|
|
|
options.challengeID,
|
|
|
|
|
options.datas[iNb].valeur,
|
|
|
|
|
options.datas[iNb].pinyin
|
|
|
|
|
);
|
|
|
|
|
|
2026-03-13 00:40:30 +00:00
|
|
|
datas_length = options.datas.length;
|
|
|
|
|
|
2026-03-12 08:05:10 +00:00
|
|
|
// Initialisation du writer
|
|
|
|
|
hw = initHW(
|
|
|
|
|
options.canvasID,
|
|
|
|
|
options.datas[iNb].hanzi,
|
|
|
|
|
options.view_settings.showCharacter,
|
|
|
|
|
options.view_settings.showOutline
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const callback_ok = () => { ok = true; };
|
|
|
|
|
const callback_nok = () => { ok = false; };
|
|
|
|
|
|
|
|
|
|
// Lancer le premier quiz
|
|
|
|
|
startQuiz1(hw, callback_ok, callback_nok);
|
|
|
|
|
|
|
|
|
|
const bouton = document.querySelector("#" + options.button_OK_ID);
|
|
|
|
|
|
|
|
|
|
const handleClick = () => {
|
|
|
|
|
let isOK = check(ok, options.feedbackID, options.challengeID);
|
|
|
|
|
|
|
|
|
|
switch (isOK) {
|
|
|
|
|
case 0:
|
|
|
|
|
// fail
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
// success
|
|
|
|
|
iNb++;
|
|
|
|
|
|
2026-03-13 00:40:30 +00:00
|
|
|
if (iNb >= datas_length) {
|
2026-03-12 08:05:10 +00:00
|
|
|
document.getElementById(options.feedbackID).textContent = "Fini !";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
callback_nok();
|
|
|
|
|
displayChallenge(
|
|
|
|
|
options.challengeID,
|
|
|
|
|
options.datas[iNb].valeur,
|
|
|
|
|
options.datas[iNb].pinyin
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
nextQuiz(
|
|
|
|
|
hw,
|
|
|
|
|
options.datas[iNb].hanzi,
|
|
|
|
|
callback_ok,
|
|
|
|
|
callback_nok
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bouton.addEventListener("click", handleClick);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function displayChallenge(divName, chineseChar, pinyin) {
|
|
|
|
|
document.getElementById(divName).textContent =
|
|
|
|
|
"Écrire : " + chineseChar + " / " + pinyin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function initHW(canvasID, currentChar, bShowCharacter, bShowOutline) {
|
|
|
|
|
return HanziWriter.create(canvasID, currentChar, {
|
|
|
|
|
width: 150,
|
|
|
|
|
height: 150,
|
|
|
|
|
showCharacter: bShowCharacter,
|
|
|
|
|
showOutline: bShowOutline,
|
|
|
|
|
showHintAfterMisses: 1,
|
|
|
|
|
highlightOnComplete: false,
|
|
|
|
|
padding: 5
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function startQuiz1(hw, fbok, fbpok) {
|
|
|
|
|
fbpok(); // reset
|
|
|
|
|
|
|
|
|
|
hw.quiz({
|
|
|
|
|
onMistake: () => fbpok(),
|
|
|
|
|
onCorrectStroke: () => { },
|
|
|
|
|
onComplete: () => fbok()
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return >0 if ok; 0: fail; -1 if finish
|
|
|
|
|
function check(ok, feedbackId) {
|
|
|
|
|
if (ok) {
|
|
|
|
|
document.getElementById(feedbackId).textContent = "✔️ Bravo !";
|
|
|
|
|
document.getElementById(feedbackId).style.color = "green";
|
|
|
|
|
return 1;
|
|
|
|
|
} else {
|
|
|
|
|
document.getElementById(feedbackId).textContent = "❌ Incorrect, continue !";
|
|
|
|
|
document.getElementById(feedbackId).style.color = "red";
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function nextQuiz(hw, hanzi, fbok, fbpok) {
|
|
|
|
|
hw.setCharacter(hanzi);
|
|
|
|
|
startQuiz1(hw, fbok, fbpok);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// On expose uniquement init()
|
|
|
|
|
return {
|
|
|
|
|
init
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</script>
|