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

125 lines
3.8 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, .openfield und .fluegel
document.querySelectorAll(".door, .openfield, .fluegel").forEach(elem => {
let canvas, ctx, particles = [], anim, hovering = false;
let cursorX = 0, cursorY = 0;
const day = elem.dataset.day;
const partners = new Set();
// === PARTNERLOGIK ===
if (elem.classList.contains("door")) {
const of = document.querySelector(`.openfield[data-day="${day}"]`);
if (of) partners.add(of);
}
else if (elem.classList.contains("openfield")) {
const door = document.querySelector(`.door[data-day="${day}"]`);
if (door) partners.add(door);
const left = document.querySelector(`.fluegel.left[data-day="${day}"]`);
const right = document.querySelector(`.fluegel.right[data-day="${day}"]`);
if (left) partners.add(left);
if (right) partners.add(right);
}
else if (elem.classList.contains("fluegel")) {
const opposite = document.querySelector(`.fluegel.${elem.classList.contains("left") ? "right" : "left"}[data-day="${day}"]`);
if (opposite) partners.add(opposite);
const of = document.querySelector(`.openfield[data-day="${day}"]`);
if (of) partners.add(of);
}
// === CANVAS SETUP ===
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");
}
// === MAUSPOSITION FÜR EFFEKT ===
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 ERZEUGEN ===
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();
partners.forEach(p => p.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);
partners.forEach(p => p.classList.remove("hover-proxy"));
});
});