Files
syncfilm/public/madameMode.js
T
2025-06-10 01:17:19 +02:00

260 lines
7.7 KiB
JavaScript

// Configuration du mode Madame
const config = {
maxHearts: 30,
heartColors: ["#ff69b4", "#ff1493", "#ff69b4"],
heartSizes: {
min: 15,
max: 30,
},
heartOpacity: {
min: 0.2,
max: 0.6,
},
animationDuration: {
min: 3,
max: 6,
},
explosionParticles: 8,
explosionDistance: 100,
};
// État du mode Madame
const state = {
isActive: localStorage.getItem("madameMode") === "true",
activeHearts: 0,
cursorHeart: null,
heartInterval: null,
};
// Création du cœur du curseur
function createCursorHeart() {
const heart = document.createElement("div");
heart.className = "cursor-heart";
heart.innerHTML = "❤";
heart.style.display = "none";
document.body.appendChild(heart);
return heart;
}
// Création d'un cœur avec des propriétés aléatoires
function createHeart(x, y) {
const heart = document.createElement("div");
heart.className = "floating-heart";
heart.innerHTML = "❤";
heart.style.position = "fixed";
heart.style.color =
config.heartColors[Math.floor(Math.random() * config.heartColors.length)];
heart.style.fontSize = `${
Math.random() * (config.heartSizes.max - config.heartSizes.min) +
config.heartSizes.min
}px`;
heart.style.opacity =
Math.random() * (config.heartOpacity.max - config.heartOpacity.min) +
config.heartOpacity.min;
heart.style.pointerEvents = "none";
if (x && y) {
heart.style.left = `${x}px`;
heart.style.top = `${y}px`;
} else {
heart.style.left = `${Math.random() * window.innerWidth}px`;
heart.style.top = `${Math.random() * window.innerHeight}px`;
}
const duration =
Math.random() *
(config.animationDuration.max - config.animationDuration.min) +
config.animationDuration.min;
const delay = Math.random() * 2;
heart.style.animation = `float ${duration}s infinite`;
heart.style.animationDelay = `${delay}s`;
return heart;
}
// Création des particules d'explosion
function createExplosionParticles(heart) {
for (let i = 0; i < config.explosionParticles; i++) {
const particle = document.createElement("div");
particle.innerHTML = "❤";
particle.style.position = "fixed";
particle.style.color =
config.heartColors[Math.floor(Math.random() * config.heartColors.length)];
particle.style.fontSize = "12px";
particle.style.opacity = "0.8";
particle.style.pointerEvents = "none";
particle.style.left = heart.style.left;
particle.style.top = heart.style.top;
const angle = (i / config.explosionParticles) * Math.PI * 2;
const x = Math.cos(angle) * config.explosionDistance;
const y = Math.sin(angle) * config.explosionDistance;
particle.style.animation = `explode 0.5s ease-out forwards`;
particle.style.setProperty("--x", `${x}px`);
particle.style.setProperty("--y", `${y}px`);
document.body.appendChild(particle);
setTimeout(() => particle.remove(), 500);
}
}
// Explosion d'un cœur
function explodeHeart(heart) {
createExplosionParticles(heart);
heart.remove();
}
// Création de cœurs flottants
function createFloatingHearts() {
const hearts = Array.from(document.querySelectorAll(".floating-heart"));
if (hearts.length >= config.maxHearts) {
// Calculer combien de cœurs sont en trop
const heartsToRemove = hearts.length - config.maxHearts;
// Mélanger le tableau des cœurs
for (let i = hearts.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[hearts[i], hearts[j]] = [hearts[j], hearts[i]];
}
// Supprimer les cœurs en trop
for (let i = 0; i < heartsToRemove; i++) {
explodeHeart(hearts[i]);
state.activeHearts--;
}
}
for (let i = 0; i < 5; i++) {
if (state.activeHearts >= config.maxHearts) break;
const heart = createHeart();
document.body.appendChild(heart);
state.activeHearts++;
heart.addEventListener("animationend", () => {
heart.remove();
state.activeHearts--;
if (state.isActive) {
createFloatingHearts();
}
});
}
}
// Création de cœurs au clic
function createClickHearts(e) {
if (!state.isActive) return;
// Cœur principal au point de clic
const mainHeart = createHeart(e.clientX, e.clientY);
document.body.appendChild(mainHeart);
state.activeHearts++;
// Cœurs supplémentaires dans un rayon
for (let i = 0; i < 5; i++) {
if (state.activeHearts >= config.maxHearts) break;
const angle = Math.random() * Math.PI * 2;
const radius = Math.random() * 100;
const x = e.clientX + Math.cos(angle) * radius;
const y = e.clientY + Math.sin(angle) * radius;
const heart = createHeart(x, y);
document.body.appendChild(heart);
state.activeHearts++;
}
// Gestion de la limite de cœurs
const hearts = Array.from(document.querySelectorAll(".floating-heart"));
if (hearts.length > config.maxHearts) {
const heartsToRemove = hearts.length - config.maxHearts;
// Mélanger le tableau des cœurs
for (let i = hearts.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[hearts[i], hearts[j]] = [hearts[j], hearts[i]];
}
// Supprimer les cœurs en trop
for (let i = 0; i < heartsToRemove; i++) {
explodeHeart(hearts[i]);
state.activeHearts--;
}
}
}
// Mise à jour de la position du cœur du curseur
function updateCursorHeart(e) {
if (state.isActive) {
state.cursorHeart.style.display = "block";
state.cursorHeart.style.left = `${e.clientX}px`;
state.cursorHeart.style.top = `${e.clientY}px`;
} else {
state.cursorHeart.style.display = "none";
}
}
// Activation/désactivation du mode Madame
function toggleMadameMode() {
state.isActive = !state.isActive;
document.body.classList.toggle("madame-mode", state.isActive);
localStorage.setItem("madameMode", state.isActive);
state.cursorHeart.style.display = state.isActive ? "block" : "none";
if (state.isActive) {
state.heartInterval = setInterval(createFloatingHearts, 2000);
createFloatingHearts();
} else {
clearInterval(state.heartInterval);
// Supprimer tous les cœurs existants avec effet d'explosion
const hearts = document.querySelectorAll(".floating-heart");
hearts.forEach(explodeHeart);
state.activeHearts = 0;
}
}
// Initialisation du mode Madame
function initMadameMode() {
state.cursorHeart = createCursorHeart();
if (state.isActive) {
document.body.classList.add("madame-mode");
state.cursorHeart.style.display = "block";
createFloatingHearts();
}
// Événements
document.addEventListener("mousemove", updateCursorHeart);
document.addEventListener("click", createClickHearts);
document
.getElementById("madame-mode")
.addEventListener("click", toggleMadameMode);
}
// Gestion du mode plein écran
function handleFullscreenChange() {
const isFullscreen =
document.fullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement ||
document.msFullscreenElement;
if (isFullscreen) {
document.getElementById("video-player").appendChild(state.cursorHeart);
} else {
document.body.appendChild(state.cursorHeart);
}
}
// Initialisation
document.addEventListener("DOMContentLoaded", initMadameMode);
// Événements de plein écran
document.addEventListener("fullscreenchange", handleFullscreenChange);
document.addEventListener("mozfullscreenchange", handleFullscreenChange);
document.addEventListener("webkitfullscreenchange", handleFullscreenChange);
document.addEventListener("MSFullscreenChange", handleFullscreenChange);