UNPKG

leumas-private-shared

Version:

Private React JSX Package For Leumas Shared Components, Headers, Footers, Asides, Login Pages, API Key Manager and much more. Styles and everything reusable to avoid DRY code across all of our subdomains

164 lines (139 loc) 4.85 kB
import React, { useEffect } from 'react'; import { styled } from '@mui/system'; const FireworksWrapper = styled('div')` position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; background: transparent; overflow: hidden; `; const FireworksBackground = ({ children }) => { useEffect(() => { const canvas = document.getElementById('fireworksCanvas'); const ctx = canvas.getContext('2d'); const fireworks = []; const particles = []; canvas.width = window.innerWidth; canvas.height = window.innerHeight; function Firework(x, y, targetX, targetY) { this.x = x; this.y = y; this.targetX = targetX; this.targetY = targetY; this.distanceToTarget = Math.sqrt((targetX - x) ** 2 + (targetY - y) ** 2); this.distanceTraveled = 0; this.coordinates = []; this.coordinateCount = 3; while (this.coordinateCount--) { this.coordinates.push([this.x, this.y]); } this.angle = Math.atan2(targetY - y, targetX - x); this.speed = 2; this.acceleration = 1.05; this.brightness = Math.random() * 30 + 50; this.targetRadius = 1; } Firework.prototype.update = function(index) { this.coordinates.pop(); this.coordinates.unshift([this.x, this.y]); this.targetRadius = Math.sin(this.distanceTraveled / this.distanceToTarget * Math.PI) * 5; this.speed *= this.acceleration; const vx = Math.cos(this.angle) * this.speed; const vy = Math.sin(this.angle) * this.speed; this.distanceTraveled = Math.sqrt((this.x + vx - this.startX) ** 2 + (this.y + vy - this.startY) ** 2); if (this.distanceTraveled >= this.distanceToTarget) { createParticles(this.targetX, this.targetY); fireworks.splice(index, 1); } else { this.x += vx; this.y += vy; } }; Firework.prototype.draw = function() { ctx.beginPath(); ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]); ctx.lineTo(this.x, this.y); ctx.strokeStyle = `hsl(${Math.random() * 360}, 100%, ${this.brightness}%)`; ctx.stroke(); }; function Particle(x, y) { this.x = x; this.y = y; this.coordinates = []; this.coordinateCount = 5; while (this.coordinateCount--) { this.coordinates.push([this.x, this.y]); } this.angle = Math.random() * Math.PI * 2; this.speed = Math.random() * 10 + 1; this.friction = 0.95; this.gravity = 1; this.hue = Math.random() * 360; this.brightness = Math.random() * 50 + 50; this.alpha = 1; this.decay = Math.random() * 0.015 + 0.015; } Particle.prototype.update = function(index) { this.coordinates.pop(); this.coordinates.unshift([this.x, this.y]); this.speed *= this.friction; this.x += Math.cos(this.angle) * this.speed; this.y += Math.sin(this.angle) * this.speed + this.gravity; this.alpha -= this.decay; if (this.alpha <= this.decay) { particles.splice(index, 1); } }; Particle.prototype.draw = function() { ctx.beginPath(); ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]); ctx.lineTo(this.x, this.y); ctx.strokeStyle = `hsla(${this.hue}, 100%, ${this.brightness}%, ${this.alpha})`; ctx.stroke(); }; function createParticles(x, y) { let particleCount = 30; while (particleCount--) { particles.push(new Particle(x, y)); } } function loop() { requestAnimationFrame(loop); ctx.globalCompositeOperation = 'destination-out'; ctx.fillStyle = `rgba(0, 0, 0, 0.5)`; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.globalCompositeOperation = 'lighter'; let i = fireworks.length; while (i--) { fireworks[i].draw(); fireworks[i].update(i); } i = particles.length; while (i--) { particles[i].draw(); particles[i].update(i); } } function random(min, max) { return Math.random() * (max - min) + min; } canvas.addEventListener('click', (e) => { const x = e.clientX; const y = e.clientY; const targetX = random(0, canvas.width); const targetY = random(0, canvas.height / 2); fireworks.push(new Firework(x, y, targetX, targetY)); }); loop(); }, []); return ( <FireworksWrapper> <canvas id="fireworksCanvas"></canvas> {children} </FireworksWrapper> ); }; export default FireworksBackground;