refactoring Claude
This commit is contained in:
parent
97359d172b
commit
13d65f8995
6 changed files with 150 additions and 229 deletions
23
datas.js
23
datas.js
|
|
@ -14,16 +14,17 @@ const nombresChinois = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const pronomsChinois = [
|
const pronomsChinois = [
|
||||||
{ hanzi: "我", pinyin: "wǒ", francais: "je / moi" },
|
{ hanzi: "它们", pinyin: "tāmen", valeur: "ils/elles (objets, animaux)" },
|
||||||
{ hanzi: "你", pinyin: "nǐ", francais: "tu / toi" },
|
{ hanzi: "我", pinyin: "wǒ", valeur: "je / moi" },
|
||||||
{ hanzi: "您", pinyin: "nín", francais: "vous (politesse)" },
|
{ hanzi: "你", pinyin: "nǐ", valeur: "tu / toi" },
|
||||||
{ hanzi: "他", pinyin: "tā", francais: "il / lui" },
|
{ hanzi: "您", pinyin: "nín", valeur: "vous (politesse)" },
|
||||||
{ hanzi: "她", pinyin: "tā", francais: "elle" },
|
{ hanzi: "他", pinyin: "tā", valeur: "il / lui" },
|
||||||
{ hanzi: "它", pinyin: "tā", francais: "il/elle (objet, animal)" },
|
{ hanzi: "她", pinyin: "tā", valeur: "elle" },
|
||||||
{ hanzi: "我们", pinyin: "wǒmen", francais: "nous" },
|
{ hanzi: "它", pinyin: "tā", valeur: "il/elle (objet, animal)" },
|
||||||
{ hanzi: "你们", pinyin: "nǐmen", francais: "vous (pluriel)" },
|
{ hanzi: "我们", pinyin: "wǒmen", valeur: "nous" },
|
||||||
{ hanzi: "他们", pinyin: "tāmen", francais: "ils (masculin ou mixte)" },
|
{ hanzi: "你们", pinyin: "nǐmen", valeur: "vous (pluriel)" },
|
||||||
{ hanzi: "她们", pinyin: "tāmen", francais: "elles (féminin)" },
|
{ hanzi: "他们", pinyin: "tāmen", valeur: "ils (masculin ou mixte)" },
|
||||||
{ hanzi: "它们", pinyin: "tāmen", francais: "ils/elles (objets, animaux)" }
|
{ hanzi: "她们", pinyin: "tāmen", valeur: "elles (féminin)" },
|
||||||
|
{ hanzi: "它们", pinyin: "tāmen", valeur: "ils/elles (objets, animaux)" }
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
21
hanzi_1.html
21
hanzi_1.html
|
|
@ -1,19 +1,10 @@
|
||||||
<div id="challenge"></div>
|
<div id="hanzi_nbr_help_widget"></div>
|
||||||
<div id="canvas" class="hanzi-canvas-container"></div>
|
|
||||||
<button id="valid">Vérifier</button>
|
|
||||||
<p id="feedback"></p>
|
|
||||||
<script>
|
|
||||||
const module1 = createMyReusableModule();
|
|
||||||
|
|
||||||
module1.init({
|
<script>
|
||||||
challengeID: "challenge",
|
const id1s = hanziApp.newWidget("hanzi_nbr_help_widget");
|
||||||
canvasID: "canvas",
|
hanziApp.init({
|
||||||
feedbackID: "feedback",
|
...id1s,
|
||||||
button_OK_ID: "valid",
|
view_settings: { showCharacter: true, showOutline: true },
|
||||||
view_settings: {
|
|
||||||
showCharacter: true,
|
|
||||||
showOutline: true,
|
|
||||||
},
|
|
||||||
datas: nombresChinois
|
datas: nombresChinois
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
21
hanzi_2.html
21
hanzi_2.html
|
|
@ -1,19 +1,10 @@
|
||||||
<div id="challenge1"></div>
|
<div id="hanzi_nbr_wohelp_widget"></div>
|
||||||
<div id="canvas1" class="hanzi-canvas-container"></div>
|
|
||||||
<button id="valid1">Vérifier</button>
|
|
||||||
<p id="feedback1"></p>
|
|
||||||
<script>
|
|
||||||
const module2 = createMyReusableModule();
|
|
||||||
|
|
||||||
module2.init({
|
<script>
|
||||||
challengeID: "challenge1",
|
const id2s = hanziApp.newWidget("hanzi_nbr_wohelp_widget");
|
||||||
canvasID: "canvas1",
|
hanziApp.init({
|
||||||
feedbackID: "feedback1",
|
...id2s,
|
||||||
button_OK_ID: "valid1",
|
view_settings: { showCharacter: false, showOutline: false },
|
||||||
view_settings: {
|
|
||||||
showCharacter: false,
|
|
||||||
showOutline: false,
|
|
||||||
},
|
|
||||||
datas: nombresChinois
|
datas: nombresChinois
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
21
hanzi_3.html
21
hanzi_3.html
|
|
@ -1,19 +1,10 @@
|
||||||
<div id="challenge3"></div>
|
<div id="hanzi_pronom_help_widget"></div>
|
||||||
<div id="canvas3" class="hanzi-canvas-container"></div>
|
|
||||||
<button id="valid3">Vérifier</button>
|
|
||||||
<p id="feedback3"></p>
|
|
||||||
<script>
|
|
||||||
const module3 = createMyReusableModule();
|
|
||||||
|
|
||||||
module3.init({
|
<script>
|
||||||
challengeID: "challenge3",
|
const id3s = hanziApp.newWidget("hanzi_pronom_help_widget");
|
||||||
canvasID: "canvas3",
|
hanziApp.init({
|
||||||
feedbackID: "feedback3",
|
...id3s,
|
||||||
button_OK_ID: "valid3",
|
view_settings: { showCharacter: true, showOutline: true },
|
||||||
view_settings: {
|
|
||||||
showCharacter: true,
|
|
||||||
showOutline: true,
|
|
||||||
},
|
|
||||||
datas: pronomsChinois
|
datas: pronomsChinois
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
176
module_hanzi.js
176
module_hanzi.js
|
|
@ -1,115 +1,93 @@
|
||||||
<script src="https://cdn.jsdelivr.net/npm/hanzi-writer@3.5/dist/hanzi-writer.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/hanzi-writer@3.5/dist/hanzi-writer.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function createMyReusableModule() {
|
const hanziApp = (() => {
|
||||||
|
|
||||||
function init(options = {}) {
|
// ---------------------------------------------------------
|
||||||
|
// CRÉE LE HTML D'UN WIDGET et retourne les IDs
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
function newWidget(rootID) {
|
||||||
|
const root = document.getElementById(rootID);
|
||||||
|
const uid = rootID;
|
||||||
|
|
||||||
let iNb = 0;
|
root.innerHTML = `
|
||||||
let datas = options.datas;
|
<div id="challenge_${uid}"></div>
|
||||||
let datas_length = datas.length;
|
<div id="canvas_${uid}"></div>
|
||||||
|
<button id="valid_${uid}">Vérifier</button>
|
||||||
|
<p id="feedback_${uid}"></p>
|
||||||
|
`;
|
||||||
|
|
||||||
displayChallenge(
|
return {
|
||||||
options.challengeID,
|
challengeID: `challenge_${uid}`,
|
||||||
datas[iNb].valeur,
|
canvasID: `canvas_${uid}`,
|
||||||
datas[iNb].pinyin
|
feedbackID: `feedback_${uid}`,
|
||||||
);
|
button_OK_ID: `valid_${uid}`
|
||||||
|
};
|
||||||
// --- INITIALISATION MULTI‑CANVAS ---
|
|
||||||
let { writers, okArray } = initMultiCanvas(
|
|
||||||
options.canvasID,
|
|
||||||
datas[iNb].hanzi,
|
|
||||||
options.view_settings
|
|
||||||
);
|
|
||||||
|
|
||||||
startMultiQuiz(writers, okArray);
|
|
||||||
|
|
||||||
const bouton = document.querySelector("#" + options.button_OK_ID);
|
|
||||||
|
|
||||||
const handleClick = () => {
|
|
||||||
|
|
||||||
let isOK = checkAll(okArray, options.feedbackID);
|
|
||||||
|
|
||||||
switch (isOK) {
|
|
||||||
case 0:
|
|
||||||
// incorrect → rien
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
// correct → mot suivant
|
|
||||||
iNb++;
|
|
||||||
|
|
||||||
if (iNb >= datas_length) {
|
|
||||||
document.getElementById(options.feedbackID).textContent = "Fini !";
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
displayChallenge(
|
// ---------------------------------------------------------
|
||||||
options.challengeID,
|
// INITIALISE UN WIDGET
|
||||||
datas[iNb].valeur,
|
// ---------------------------------------------------------
|
||||||
datas[iNb].pinyin
|
function init(options = {}) {
|
||||||
);
|
let iNb = 0;
|
||||||
|
const datas = options.datas;
|
||||||
// Réinitialiser les canvas pour le nouveau mot
|
let writers = [], okArray = [];
|
||||||
let res = initMultiCanvas(
|
|
||||||
options.canvasID,
|
|
||||||
datas[iNb].hanzi,
|
|
||||||
options.view_settings
|
|
||||||
);
|
|
||||||
|
|
||||||
|
function loadNext() {
|
||||||
|
displayChallenge(options.challengeID, datas[iNb]);
|
||||||
|
const res = initMultiCanvas(options.canvasID, datas[iNb].hanzi, options.view_settings);
|
||||||
writers = res.writers;
|
writers = res.writers;
|
||||||
okArray = res.okArray;
|
okArray = res.okArray;
|
||||||
|
|
||||||
startMultiQuiz(writers, okArray);
|
startMultiQuiz(writers, okArray);
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
bouton.addEventListener("click", handleClick);
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadNext();
|
||||||
|
document.getElementById(options.button_OK_ID).addEventListener("click", handleClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// AFFICHAGE DU CHALLENGE
|
// AFFICHAGE DU CHALLENGE
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
function displayChallenge(divName, chineseChar, pinyin) {
|
function displayChallenge(divID, item) {
|
||||||
document.getElementById(divName).textContent =
|
document.getElementById(divID).textContent =
|
||||||
"Écrire : " + chineseChar + " / " + pinyin;
|
"Écrire : " + item.valeur + " / " + item.pinyin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// CRÉATION MULTI‑CANVAS
|
// CRÉATION MULTI-CANVAS
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
function initMultiCanvas(containerID, hanzi, view_settings) {
|
function initMultiCanvas(containerID, hanzi, view_settings) {
|
||||||
|
const CHAR_SIZE = 150;
|
||||||
const chars = [...hanzi]; // "十一" → ["十","一"]
|
const chars = [...hanzi];
|
||||||
|
|
||||||
const container = document.getElementById(containerID);
|
const container = document.getElementById(containerID);
|
||||||
container.innerHTML = ""; // reset
|
container.innerHTML = "";
|
||||||
|
container.style.cssText = "display:flex;flex-direction:row;flex-wrap:nowrap;align-items:flex-start;gap:12px";
|
||||||
|
|
||||||
let writers = [];
|
const okArray = new Array(chars.length).fill(false);
|
||||||
let okArray = new Array(chars.length).fill(false);
|
const writers = chars.map((char, index) => {
|
||||||
|
const div = document.createElement("div");
|
||||||
chars.forEach((char, index) => {
|
div.id = `${containerID}_${index}`;
|
||||||
|
container.appendChild(div);
|
||||||
const c = document.createElement("div");
|
const hw = HanziWriter.create(div.id, char, {
|
||||||
c.id = `${containerID}_${index}`;
|
width: CHAR_SIZE, height: CHAR_SIZE,
|
||||||
c.style.display = "inline-block";
|
showCharacter: view_settings?.showCharacter ?? true,
|
||||||
c.style.marginRight = "10px";
|
showOutline: view_settings?.showOutline ?? true,
|
||||||
container.appendChild(c);
|
showHintAfterMisses: 1, highlightOnComplete: false, padding: 5
|
||||||
|
|
||||||
const hw = HanziWriter.create(c.id, char, {
|
|
||||||
width: 150,
|
|
||||||
height: 150,
|
|
||||||
showCharacter: view_settings.showCharacter,
|
|
||||||
showOutline: view_settings.showOutline,
|
|
||||||
showHintAfterMisses: 1,
|
|
||||||
highlightOnComplete: false,
|
|
||||||
padding: 5
|
|
||||||
});
|
});
|
||||||
|
div.style.cssText = `display:inline-block;width:${CHAR_SIZE}px;height:${CHAR_SIZE}px;flex-shrink:0`;
|
||||||
writers.push(hw);
|
return hw;
|
||||||
});
|
});
|
||||||
|
|
||||||
return { writers, okArray };
|
return { writers, okArray };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,14 +95,9 @@ function createMyReusableModule() {
|
||||||
// LANCER UN QUIZ PAR CANVAS
|
// LANCER UN QUIZ PAR CANVAS
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
function startMultiQuiz(writers, okArray) {
|
function startMultiQuiz(writers, okArray) {
|
||||||
|
|
||||||
writers.forEach((hw, idx) => {
|
writers.forEach((hw, idx) => {
|
||||||
|
|
||||||
okArray[idx] = false; // reset
|
|
||||||
|
|
||||||
hw.quiz({
|
hw.quiz({
|
||||||
onMistake: () => { okArray[idx] = false; },
|
onMistake: () => { okArray[idx] = false; },
|
||||||
onCorrectStroke: () => {},
|
|
||||||
onComplete: () => { okArray[idx] = true; }
|
onComplete: () => { okArray[idx] = true; }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -134,25 +107,16 @@ function createMyReusableModule() {
|
||||||
// CHECK GLOBAL
|
// CHECK GLOBAL
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
function checkAll(okArray, feedbackId) {
|
function checkAll(okArray, feedbackId) {
|
||||||
|
const el = document.getElementById(feedbackId);
|
||||||
const allOK = okArray.every(v => v === true);
|
const allOK = okArray.every(Boolean);
|
||||||
|
el.textContent = allOK ? "✔️ Bravo !" : "❌ Incorrect, continuez !";
|
||||||
if (allOK) {
|
el.style.color = allOK ? "green" : "red";
|
||||||
document.getElementById(feedbackId).textContent = "✔️ Bravo !";
|
return allOK;
|
||||||
document.getElementById(feedbackId).style.color = "green";
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
document.getElementById(feedbackId).textContent = "❌ Incorrect, continue !";
|
|
||||||
document.getElementById(feedbackId).style.color = "red";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// EXPORT
|
// EXPORT
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
return {
|
return { newWidget, init };
|
||||||
init
|
})();
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
17
styles.html
17
styles.html
|
|
@ -1,17 +0,0 @@
|
||||||
<style>
|
|
||||||
.hanzi-canvas-container {
|
|
||||||
display: flex !important;
|
|
||||||
flex-direction: row !important;
|
|
||||||
gap: 12px;
|
|
||||||
align-items: flex-start;
|
|
||||||
flex-wrap: nowrap !important;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border: 2px solid #000;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hanzi-canvas-container > div {
|
|
||||||
display: inline-flex !important;
|
|
||||||
flex: 0 0 auto !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Loading…
Reference in a new issue