Files
Bratonien-Adventskalender/adventskalender/shared/js/glitter.js

120 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Bratonien Glitter Hover Effekt für .door und .openfield
document.querySelectorAll(".door, .openfield").forEach(elem => {
let canvas, ctx, particles = [], anim, hovering = false;
let cursorX = 0, cursorY = 0;
const day = elem.dataset.day;
let partner = null;
if (elem.classList.contains("door")) {
partner = document.querySelector(`.openfield[data-day="${day}"]`);
} else if (elem.classList.contains("openfield")) {
partner = document.querySelector(`.door[data-day="${day}"]`);
} else if (elem.classList.contains("fluegel")) {
const isLeft = elem.classList.contains("left");
const isRight = elem.classList.contains("right");
// Finde den gegenüberliegenden Flügel
if (isLeft) {
partner = document.querySelector(`.fluegel.right[data-day="${day}"]`);
} else if (isRight) {
partner = document.querySelector(`.fluegel.left[data-day="${day}"]`);
}
}
function setupCanvas() {
if (canvas) return;
canvas = document.createElement("canvas");
canvas.width = elem.offsetWidth * 1.4;
canvas.height = elem.offsetHeight * 1.4;
canvas.style.position = "absolute";
canvas.style.top = "-20%";
canvas.style.left = "-20%";
canvas.style.pointerEvents = "none";
canvas.style.zIndex = "10";
elem.appendChild(canvas);
ctx = canvas.getContext("2d");
}
// Cursor in Element
elem.addEventListener("mousemove", e => {
const rect = elem.getBoundingClientRect();
cursorX = (e.clientX - rect.left) * 1.4 - (elem.offsetWidth * 0.2);
cursorY = (e.clientY - rect.top) * 1.4 - (elem.offsetHeight * 0.2);
});
function addParticles() {
const cx = cursorX || canvas.width / 2;
const cy = cursorY || canvas.height / 2;
for (let i = 0; i < 4; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = Math.random() * 1.5 + 0.3;
particles.push({
x: cx,
y: cy,
r: Math.random() * 1.3 + 0.2,
alpha: Math.random() * 0.7 + 0.3,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
life: Math.random() * 120 + 60,
decay: Math.random() * 0.015 + 0.008
});
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (hovering) addParticles();
particles.forEach(p => {
ctx.beginPath();
const grad = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, p.r * 3);
// Bratonien-Gold
grad.addColorStop(0, `rgba(200, 170, 73, ${p.alpha})`);
grad.addColorStop(0.3, `rgba(255, 240, 200, ${p.alpha * 0.8})`);
grad.addColorStop(1, "transparent");
ctx.fillStyle = grad;
ctx.arc(p.x, p.y, p.r * 3, 0, Math.PI * 2);
ctx.fill();
p.x += p.vx;
p.y += p.vy + 0.05;
p.vx *= 0.98;
p.vy *= 0.98;
p.alpha -= p.decay;
p.life--;
});
particles = particles.filter(p => p.life > 0 && p.alpha > 0);
anim = requestAnimationFrame(draw);
}
// HOVER START
elem.addEventListener("mouseenter", () => {
setupCanvas();
hovering = true;
cancelAnimationFrame(anim);
draw();
// wichtigen Teil: bestehenden Hover-Style beim Partner auslösen
if (partner) {
// wir setzen KEINE neuen Styles, nur die Trigger-Klasse
partner.classList.add("hover-proxy");
}
});
// HOVER ENDE
elem.addEventListener("mouseleave", () => {
hovering = false;
setTimeout(() => {
if (!hovering) {
cancelAnimationFrame(anim);
particles = [];
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, 300);
if (partner) {
partner.classList.remove("hover-proxy");
}
});
});