let dernierHash = null; async function obtenirHashFichier() { try { const response = await fetch('/data/baptiste_final.yaml'); const contenu = await response.text(); return btoa(contenu); // Encodage en Base64 comme hash simplifié } catch (error) { console.error("Erreur lors de la récupération du contenu du fichier :", error); return null; } } async function analyserModifications() { try { const response = await fetch('/data/baptiste_final.yaml'); const data = await response.json(); // Vérifier les cartes ajoutées dans `liste_carte_defaut` if (Array.isArray(data.liste_carte_defaut)) { data.liste_carte_defaut.forEach((carte) => { if (carte.donné === "non" && !document.querySelector(`[data-numero="${carte.numero}"]`)) { creerCarte(document.getElementById('zone_cartes'), carte.image, carte.numero, carte.lettre); } }); } // Vérifier les cartes ajoutées dans `liste_carte_échangé` if (Array.isArray(data.liste_carte_échangé)) { data.liste_carte_échangé.forEach((carte) => { if (carte.recupéré === "oui" && !document.querySelector(`[data-numero="${carte.numero}"]`)) { creerCarte(document.getElementById('zone_cartes'), carte.image, carte.numero, carte.lettre); } }); } } catch (error) { console.error("Erreur lors de l'analyse des modifications :", error); } } async function surveillerModifications() { try { const nouveauHash = await obtenirHashFichier(); if (dernierHash && nouveauHash !== dernierHash) { console.log("Fichier modifié. Analyse des modifications..."); analyserModifications(); // Vérifie les changements dans le fichier } dernierHash = nouveauHash; } catch (error) { console.error("Erreur lors de la surveillance des modifications :", error); } } async function chargerCartes() { try { const response = await fetch('/data/baptiste_final.yaml'); const data = await response.json(); const zoneCartes = document.getElementById('zone_cartes'); const emplacements = document.getElementById('emplacements'); // Charger les cartes de `liste_carte_defaut` où donné = "non" if (Array.isArray(data.liste_carte_defaut)) { data.liste_carte_defaut.forEach((carte) => { if (carte.donné === "non") { creerCarte(zoneCartes, carte.image, carte.numero, carte.lettre); } }); } // Charger les cartes de `liste_carte_échangé` où recupéré = "oui" if (Array.isArray(data.liste_carte_échangé)) { data.liste_carte_échangé.forEach((carte) => { if (carte.recupéré === "oui") { creerCarte(zoneCartes, carte.image, carte.numero, carte.lettre); } }); } // Créer les points d'aimantation for (let i = 0; i < 6; i++) { const rond = document.createElement('div'); rond.className = 'emplacement'; rond.dataset.index = i; // Identifier chaque rond emplacements.appendChild(rond); } } catch (error) { console.error("Erreur lors du chargement des cartes :", error); } } // Fonction pour créer une carte function creerCarte(zone, image, numero, lettre) { const carte = document.createElement('div'); carte.className = 'carte'; carte.style.backgroundImage = `url(${image})`; if (numero !== undefined) { carte.dataset.numero = numero; // Ajoute l'attribut data-numero uniquement si numero est défini } else { console.error("Le numéro de la carte est undefined."); } if (lettre !== undefined) { carte.dataset.lettre = lettre; // Ajoute l'attribut data-lettre } else { console.error("La lettre de la carte est undefined."); } positionAleatoire(zone, carte); // Positionner aléatoirement dans la partie haute rendreDeplacable(carte); // Rendre la carte déplaçable zone.appendChild(carte); } function positionAleatoire(zone, carte) { const zoneRect = zone.getBoundingClientRect(); const minMargin = 80; // Marge minimale pour éviter les bordures // Calculer les limites du tiers central verticalement const topLimit = zoneRect.height / 3; // Début du tiers central const bottomLimit = (zoneRect.height * 2) / 3 - carte.offsetHeight; // Calculer les limites horizontalement (avec marge) const leftLimit = minMargin; // Marge gauche const rightLimit = zoneRect.width - carte.offsetWidth - minMargin; // Marge droite // Générer une position aléatoire dans les limites définies const top = Math.random() * (bottomLimit - topLimit) + topLimit; // Position verticale dans le tiers central const left = Math.random() * (rightLimit - leftLimit) + leftLimit; // Position horizontale avec marges // Orientation aléatoire const rotation = Math.random() * 30 - 15; // Entre -15° et 15° carte.style.top = `${top}px`; carte.style.left = `${left}px`; carte.style.transform = `rotate(${rotation}deg)`; } function rendreDeplacable(carte) { let offsetX, offsetY; let hasMoved = false; // Indique si la carte a été déplacée carte.addEventListener('pointerdown', (e) => { // console.log("Pointer down : Début du déplacement."); offsetX = e.clientX - carte.getBoundingClientRect().left; offsetY = e.clientY - carte.getBoundingClientRect().top; carte.style.cursor = 'grabbing'; // Ajout de la classe pour zoom in carte.classList.add('zoom-in'); // console.log("Classe zoom-in ajoutée."); const pointerMove = (e) => { carte.style.left = `${e.clientX - offsetX}px`; carte.style.top = `${e.clientY - offsetY}px`; // Vérifier l'aimantation pendant le déplacement verifierAimantation(carte); }; const pointerUp = () => { // console.log("Pointer up : Fin du déplacement."); carte.style.cursor = 'grab'; // Retirer la classe pour zoom in carte.classList.remove('zoom-in'); // console.log("Classe zoom-in retirée."); if (carte.dataset.aimantee === "true") { // console.log("Carte reste aimantée"); } else { // console.log("Carte n'est plus aimantée"); } // Vérifier si la carte est dans la zone blanche if (isInZoneBlanche(carte)) { supprimerCarte(carte); // Supprimer la carte } window.removeEventListener('pointermove', pointerMove); window.removeEventListener('pointerup', pointerUp); }; window.addEventListener('pointermove', pointerMove); window.addEventListener('pointerup', pointerUp); }); } function isInZoneBlanche(carte) { // Sélectionner la zone blanche const zoneBlanche = document.querySelector('.zone-blanche'); if (!zoneBlanche) { console.error("Zone blanche non trouvée dans le DOM."); return false; } // Obtenir les dimensions et la position de la zone blanche const zoneRect = zoneBlanche.getBoundingClientRect(); const carteRect = carte.getBoundingClientRect(); // Vérifier si le centre de la carte est dans la zone blanche const carteCenterX = carteRect.left + carteRect.width / 2; const carteCenterY = carteRect.top + carteRect.height / 2; return ( carteCenterX >= zoneRect.left && carteCenterX <= zoneRect.right && carteCenterY >= zoneRect.top && carteCenterY <= zoneRect.bottom ); } // Supprimer la carte et mettre à jour le fichier YAML async function supprimerCarte(carte) { const carteImage = carte.style.backgroundImage.match(/url\(["']?(.*?)["']?\)/)?.[1]; const response = await fetch('/data/baptiste_final.yaml'); const data = await response.json(); // Vérifier si la carte est dans liste_carte_defaut const carteDefaut = data.liste_carte_defaut.find((c) => c.image === carteImage); if (carteDefaut) { carteDefaut.donné = "oui"; } else { // Sinon, vérifier si elle est dans liste_carte_échangé const carteEchange = data.liste_carte_échangé.find((c) => c.image === carteImage); if (carteEchange) { carteEchange.recupéré = "non"; } } // Mettre à jour le fichier YAML await fetch('/update_yaml', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); // Supprimer la carte du DOM carte.remove(); } // Vérifier si une carte est au-dessus d'un rond let lettresPlacees = Array(6).fill(null); // Tableau pour stocker les lettres placées function verifierAimantation(carte) { const emplacements = document.querySelectorAll('.emplacement'); const aimantationDistance = 50; // Augmenter la distance pour plus de tolérance let aimantationEffectuee = false; // Initialisation de la variable // Si la carte est verrouillée, ignorer les nouvelles vérifications if (carte.dataset.verrouAimantation === "true") { return; } emplacements.forEach((rond, index) => { const rondRect = rond.getBoundingClientRect(); const carteRect = carte.getBoundingClientRect(); // Calculer les centres const carteCenterX = carteRect.left + carteRect.width / 2; const carteCenterY = carteRect.top + carteRect.height / 2; const rondCenterX = rondRect.left + rondRect.width / 2; const rondCenterY = rondRect.top + rondRect.height / 2; // Vérifier si le centre de la carte est proche du centre du rond const distanceX = Math.abs(carteCenterX - rondCenterX); const distanceY = Math.abs(carteCenterY - rondCenterY); if ( distanceX <= aimantationDistance && distanceY <= aimantationDistance && !rond.dataset.lettre // Vérifie que l'emplacement n'est pas déjà occupé ) { aimanterCarte(carte, rond,index); carte.dataset.aimantee = "true"; // Marque la carte comme aimantée rond.dataset.lettre = index; // Associe la lettre de la carte à l'emplacement console.log(`Lettre ${carte.dataset.lettre} assignée à l'emplacement ${index}`); aimantationEffectuee = true; carte.classList.remove('zoom-in'); // Désactive le zoom après aimantation } }); if (!aimantationEffectuee) { // Si la carte n'est plus aimantée, retirer la lettre uniquement si elle est actuellement associée à ce rond emplacements.forEach((rond, index) => { if ( rond.dataset.lettre === carte.dataset.lettre && carte.dataset.aimantee === "true" && rond.dataset.index == index // Vérifie que l'index correspond ) { delete rond.dataset.lettre; // Supprime la lettre du rond delete rond.dataset.index; // Supprime l'index associé console.log(`Lettre ${carte.dataset.lettre} retirée de l'emplacement ${index}`); } }); carte.dataset.aimantee = "false"; // Marquer la carte comme non aimantée } // Vérifier le mot après chaque changement verifierMotCache(); } // Vérifie si le mot caché est formé function verifierMotCache() { const emplacements = document.querySelectorAll('.emplacement'); const motAttendu = "ROUTER"; // Mot à découvrir let motForme = ""; emplacements.forEach((rond,index) => { motForme += rond.dataset.lettre || "_"; // Ajouter la lettre ou "_" si l'emplacement est vide }); console.log(`Mot formé : ${motForme}`); const zoneMotForme = document.getElementById('mot-forme'); if (zoneMotForme) { zoneMotForme.textContent = `Mot formé : ${motForme}`; } if (motForme === motAttendu) { console.log("Bravo ! Vous avez trouvé le mot caché !"); const zoneMotForme = document.getElementById('mot-forme'); if (zoneMotForme) { zoneMotForme.textContent = '${motForme}'; } else if (zoneMotForme) { zoneMotForme.style.color = "#333"; // Réinitialiser la couleur si le mot n'est pas trouvé } } } // Faire glisser et pivoter une carte relâchée en dehors des zones d'aimantation function lancerCarte(carte) { const zone = document.getElementById('zone_cartes'); const zoneRect = zone.getBoundingClientRect(); const vitesseX = (Math.random() - 0.5) * 10; const vitesseY = (Math.random() - 0.5) * 10; let dureeGlissement = 100; // Durée maximale de glissement en ms const startTime = Date.now(); const interval = setInterval(() => { const carteRect = carte.getBoundingClientRect(); let top = parseFloat(carte.style.top || 0) + vitesseY; let left = parseFloat(carte.style.left || 0) + vitesseX; if (Date.now() - startTime > dureeGlissement) { clearInterval(interval); return; } if ( carteRect.left + vitesseX < 0 || carteRect.right + vitesseX > zoneRect.width || carteRect.top + vitesseY < 0 || carteRect.bottom + vitesseY > zoneRect.height ) { clearInterval(interval); } else { carte.style.top = `${top}px`; carte.style.left = `${left}px`; // Rotation relative const currentRotation = parseFloat( carte.style.transform.replace(/[^-0-9.]/g, '') || 0 ); const rotation = currentRotation + (Math.random() * 10 - 5); // Variation relative carte.style.transform = `rotate(${rotation}deg)`; } }, 10); } // Ajuster progressivement la rotation vers zéro function ajusterRotation(carte) { let currentRotation = parseFloat( getComputedStyle(carte).transform.match(/matrix.*\((.+)\)/)?.[1]?.split(', ')[1] || 0 ); const targetRotation = 0; const step = (targetRotation - currentRotation) / 10; const interval = setInterval(() => { if (Math.abs(currentRotation - targetRotation) <= Math.abs(step)) { carte.style.transform = `rotate(0deg)`; clearInterval(interval); } else { currentRotation += step; carte.style.transform = `rotate(${currentRotation}deg)`; } }, 50); } // Tableau global pour stocker les lettres associées à chaque rond const rondLettres = Array(6).fill(null); // Initialise un tableau de 6 éléments avec `null` function aimanterCarte(carte, rond, index) { const rondRect = rond.getBoundingClientRect(); const zoneRect = document.getElementById('zone_cartes').getBoundingClientRect(); // Centrer la carte sur le rond carte.style.left = `${rondRect.left - zoneRect.left + rondRect.width / 2 - carte.offsetWidth / 2}px`; carte.style.top = `${rondRect.top - zoneRect.top + rondRect.height / 2 - carte.offsetHeight / 2}px`; // Réinitialiser la rotation de la carte carte.style.transform = `rotate(0deg)`; // Ajouter une classe pour indiquer l'aimantation (optionnel) carte.classList.add('aimantee'); // Ajouter l'index au dataset rond.dataset.index = index; console.log(`Carte assignée à l'emplacement ${index}`); // Log pour vérifier l'association } // Charger les cartes au démarrage document.addEventListener('DOMContentLoaded', chargerCartes); document.addEventListener('DOMContentLoaded', async () => { dernierHash = await obtenirHashFichier(); // Initialisation du hash setInterval(surveillerModifications, 2000); // Surveiller les modifications toutes les 2 secondes });