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

111 lines
3.6 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 finale, symmetrische Version
document.addEventListener("DOMContentLoaded", () => {
const allElements = document.querySelectorAll(".door, .fluegel, .openfield");
// === Alle Elemente nach data-day gruppieren ===
const groups = {};
allElements.forEach(el => {
const day = el.dataset.day;
if (!groups[day]) groups[day] = [];
groups[day].push(el);
});
// === Für jede Gruppe Hover-Effekt einrichten ===
Object.values(groups).forEach(group => {
group.forEach(elem => {
let canvas, ctx, particles = [], anim, hovering = false;
let cursorX = 0, cursorY = 0;
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");
}
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);
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();
// Alle Elemente mit gleichem Tag (door, flügel, openfield)
// bekommen gleichzeitig hover-proxy
group.forEach(e => e.classList.add("hover-proxy"));
});
// === Hover Ende ===
elem.addEventListener("mouseleave", () => {
hovering = false;
setTimeout(() => {
if (!hovering) {
cancelAnimationFrame(anim);
particles = [];
if (ctx) ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, 300);
group.forEach(e => e.classList.remove("hover-proxy"));
});
});
});
});