350 lines
13 KiB
JavaScript
350 lines
13 KiB
JavaScript
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);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
});
|
|
}
|
|
} 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);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 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) {
|
|
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.");
|
|
}
|
|
|
|
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
|
|
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
|
|
|
|
emplacements.forEach((rond) => {
|
|
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) {
|
|
aimanterCarte(carte, rond);
|
|
carte.dataset.aimantee = "true"; // Marque la carte comme aimantée
|
|
aimantationEffectuee = true;
|
|
carte.classList.remove('zoom-in'); // Désactive le zoom après aimantation
|
|
}
|
|
});
|
|
if (!aimantationEffectuee) {
|
|
carte.dataset.aimantee = "false"; // La carte n'est plus aimantée
|
|
}
|
|
}
|
|
// 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);
|
|
}
|
|
|
|
function aimanterCarte(carte, rond) {
|
|
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');
|
|
}
|
|
// 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
|
|
}); |