Wordpress_Chinese/module_hanzi.js

122 lines
4.2 KiB
JavaScript
Raw Permalink Normal View History

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>
2026-03-15 17:54:48 +00:00
const hanziApp = (() => {
// ---------------------------------------------------------
// CRÉE LE HTML D'UN WIDGET et retourne les IDs
// ---------------------------------------------------------
function newWidget(rootID) {
const root = document.getElementById(rootID);
const uid = rootID;
root.innerHTML = `
<div id="challenge_${uid}"></div>
<div id="canvas_${uid}"></div>
<button id="valid_${uid}">Vérifier</button>
<p id="feedback_${uid}"></p>
`;
2026-03-15 16:28:39 +00:00
2026-03-15 17:54:48 +00:00
return {
challengeID: `challenge_${uid}`,
canvasID: `canvas_${uid}`,
feedbackID: `feedback_${uid}`,
button_OK_ID: `valid_${uid}`
};
}
// ---------------------------------------------------------
// INITIALISE UN WIDGET
// ---------------------------------------------------------
function init(options = {}) {
let iNb = 0;
const datas = options.datas;
let writers = [], okArray = [];
function loadNext() {
displayChallenge(options.challengeID, datas[iNb]);
const res = initMultiCanvas(options.canvasID, datas[iNb].hanzi, options.view_settings);
writers = res.writers;
okArray = res.okArray;
startMultiQuiz(writers, okArray);
2026-03-15 16:28:39 +00:00
}
2026-03-12 08:05:10 +00:00
2026-03-15 17:54:48 +00:00
function handleClick() {
const allOK = checkAll(okArray, options.feedbackID);
if (!allOK) return;
iNb++;
if (iNb >= datas.length) {
document.getElementById(options.feedbackID).textContent = "Fini !";
document.getElementById(options.button_OK_ID).removeEventListener("click", handleClick);
return;
}
loadNext();
2026-03-12 08:05:10 +00:00
}
2026-03-15 17:54:48 +00:00
loadNext();
document.getElementById(options.button_OK_ID).addEventListener("click", handleClick);
}
// ---------------------------------------------------------
// AFFICHAGE DU CHALLENGE
// ---------------------------------------------------------
function displayChallenge(divID, item) {
document.getElementById(divID).textContent =
"Écrire : " + item.valeur + " / " + item.pinyin;
}
// ---------------------------------------------------------
// CRÉATION MULTI-CANVAS
// ---------------------------------------------------------
function initMultiCanvas(containerID, hanzi, view_settings) {
const CHAR_SIZE = 150;
const chars = [...hanzi];
const container = document.getElementById(containerID);
container.innerHTML = "";
container.style.cssText = "display:flex;flex-direction:row;flex-wrap:nowrap;align-items:flex-start;gap:12px";
const okArray = new Array(chars.length).fill(false);
const writers = chars.map((char, index) => {
const div = document.createElement("div");
div.id = `${containerID}_${index}`;
container.appendChild(div);
const hw = HanziWriter.create(div.id, char, {
width: CHAR_SIZE, height: CHAR_SIZE,
showCharacter: view_settings?.showCharacter ?? true,
showOutline: view_settings?.showOutline ?? true,
showHintAfterMisses: 1, highlightOnComplete: false, padding: 5
});
div.style.cssText = `display:inline-block;width:${CHAR_SIZE}px;height:${CHAR_SIZE}px;flex-shrink:0`;
return hw;
});
return { writers, okArray };
}
// ---------------------------------------------------------
// LANCER UN QUIZ PAR CANVAS
// ---------------------------------------------------------
function startMultiQuiz(writers, okArray) {
writers.forEach((hw, idx) => {
hw.quiz({
onMistake: () => { okArray[idx] = false; },
onComplete: () => { okArray[idx] = true; }
});
});
}
// ---------------------------------------------------------
// CHECK GLOBAL
// ---------------------------------------------------------
function checkAll(okArray, feedbackId) {
const el = document.getElementById(feedbackId);
const allOK = okArray.every(Boolean);
el.textContent = allOK ? "✔️ Bravo !" : "❌ Incorrect, continuez !";
el.style.color = allOK ? "green" : "red";
return allOK;
}
// ---------------------------------------------------------
// EXPORT
// ---------------------------------------------------------
return { newWidget, init };
})();
</script>