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

95 lines
2.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 Explosion folgt dem Cursor
document.querySelectorAll(".door").forEach(door => {
let canvas, ctx, particles = [], anim, hovering = false;
let cursorX = 0, cursorY = 0;
// Canvas vorbereiten
function setupCanvas() {
if (canvas) return;
canvas = document.createElement("canvas");
canvas.width = door.offsetWidth * 1.4;
canvas.height = door.offsetHeight * 1.4;
canvas.style.position = "absolute";
canvas.style.top = "-20%";
canvas.style.left = "-20%";
canvas.style.pointerEvents = "none";
canvas.style.zIndex = "10";
door.appendChild(canvas);
ctx = canvas.getContext("2d");
}
// Cursorposition innerhalb des Türchens erfassen
door.addEventListener("mousemove", e => {
const rect = door.getBoundingClientRect();
cursorX = (e.clientX - rect.left) * 1.4 - (door.offsetWidth * 0.2);
cursorY = (e.clientY - rect.top) * 1.4 - (door.offsetHeight * 0.2);
});
// Partikel hinzufügen (Explosion folgt Cursor)
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(255, 235, 160, ${p.alpha})`);
grad.addColorStop(0.3, `rgba(255, 220, 120, ${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();
// Bewegung Explosion + leichte Gravitation
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 starten
door.addEventListener("mouseenter", () => {
setupCanvas();
hovering = true;
cancelAnimationFrame(anim);
draw();
});
// Hover beenden
door.addEventListener("mouseleave", () => {
hovering = false;
setTimeout(() => {
if (!hovering) {
cancelAnimationFrame(anim);
particles = [];
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, 300);
});
});