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

123 lines
3.9 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 final, voll bidirektional
document.addEventListener("DOMContentLoaded", () => {
// === 1. Elemente nach Tagen gruppieren ===
const groups = {};
document.querySelectorAll(".door, .fluegel, .openfield").forEach(elem => {
const day = elem.dataset.day;
if (!groups[day]) groups[day] = [];
groups[day].push(elem);
});
console.table(Object.entries(groups).map(([day, arr]) => ({
day,
types: arr.map(e => e.className)
})));
document.querySelectorAll(".door, .fluegel, .openfield").forEach(elem => {
const day = elem.dataset.day;
if (!groups[day]) groups[day] = [];
groups[day].push(elem);
});
// === 2. Hoverlogik für jede Gruppe ===
Object.values(groups).forEach(elems => {
elems.forEach(elem => {
let canvas, ctx, particles = [], anim, hovering = false;
let cursorX = 0, cursorY = 0;
// Canvas für Glitzereffekt
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 verfolgen (für Partikel)
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);
});
// Partikel hinzufügen
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
});
}
}
// Zeichnen
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 des gleichen Tages gleichzeitig hervorheben
elems.forEach(el => el.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);
elems.forEach(el => el.classList.remove("hover-proxy"));
});
});
});
});