diff --git a/website/scripts/particles.ts b/website/scripts/particles.ts index fc574b4..d31b091 100644 --- a/website/scripts/particles.ts +++ b/website/scripts/particles.ts @@ -1,88 +1,90 @@ -class Particle { - x: number; - y: number; - timeExisting: number = 0; - element: HTMLSpanElement; +const renderSurface = document.createElement("canvas"); +renderSurface.style.position = "absolute"; +renderSurface.style.left = "0px"; +renderSurface.style.top = "0px"; +renderSurface.style.pointerEvents = "none"; +renderSurface.width = document.documentElement.scrollWidth; +renderSurface.height = document.documentElement.scrollHeight; - constructor(x: number, y: number) { - this.x = x; - this.y = y; - const element = document.createElement("span"); - element.style.position = "absolute"; - element.style.left = this.x + "px"; - element.style.top = this.y + "px"; - element.style.color = "white"; - element.style.fontSize = "30px"; - element.style.transform = `rotate(${getRandomArbitrary(-90, 90)}deg)`; - element.style.userSelect = "none"; - element.style.pointerEvents = "none"; - element.innerText = - Math.random() < 0.5 ? "-" : Math.random() < 0.5 ? "+" : "*"; - element.id = "particle_" + Math.random(); - document.body.appendChild(element); - this.element = document.getElementById(element.id)!; - particles.push(this); - } +document.body.insertBefore(renderSurface, document.body.firstElementChild); - render() { - this.y += 2; - this.x -= getRandomArbitrary(-4, 4); - this.element.style.left = this.x + "px"; - this.element.style.top = this.y + "px"; - this.timeExisting += 1; +const renderSurfaceContext = renderSurface.getContext("2d")!; - if (document.body.scrollHeight < this.y) { - this.kill(true); - } - if (this.timeExisting > 20) { - this.kill(); - } - } - kill(forceKill = false) { - if (forceKill) { - document.body.removeChild(this.element); - particles = particles.filter((z) => z.element.id !== this.element.id); - } else { - const opacity = Math.abs(this.timeExisting - 30); - this.element.style.opacity = (opacity / 10) + ""; - this.element.style.fontSize = (opacity * 3)+"px"; - - if (opacity <= 0) { - document.body.removeChild(this.element); - particles = particles.filter((z) => z.element.id !== this.element.id); - } - } - } -} +let particles: Particle[] = []; function getRandomArbitrary(min: number, max: number) { return Math.random() * (max - min) + min; } -let particles: Particle[] = []; +class Particle { + x: number; + y: number; + id: number; -let lastRenderTimestamp = 0; -let lastMoveTimestamp = 0; + angle: number; + color: string; + style: string; -function particleRenderLoop(timestamp: number) { - if (timestamp - lastRenderTimestamp < 100) { - window.requestAnimationFrame(particleRenderLoop); - return; + constructor(x: number, y: number) { + this.x = x; + this.y = y; + this.id = Math.random(); + this.angle = 2*Math.PI*this.id; + this.color = "hsl(" + 360 * Math.random() + ',' + + (25 + 70 * Math.random()) + '%,' + + (85 + 10 * Math.random()) + '%)'; + this.style = Math.random() < 0.5 ? "-" : Math.random() > 0.5 ? "+" : "*"; } - lastRenderTimestamp = timestamp; + + render() { + this.y += 2; + this.x -= getRandomArbitrary(-1, 1); + + var width2=renderSurfaceContext.measureText("+").width; + + renderSurfaceContext.save(); + renderSurfaceContext.fillStyle = this.color; + renderSurfaceContext.font = Math.floor(this.id*60)+"px Arial"; + renderSurfaceContext.translate(this.x, this.y); + renderSurfaceContext.rotate(2*Math.PI*this.id); + renderSurfaceContext.fillText(this.style, -width2/2,4); + renderSurfaceContext.restore(); + + if (renderSurface.height < this.y) { + particles = particles.filter(z=>z.id !== this.id) + } + } +} + +function renderLoop(timestamp: number) { + renderSurfaceContext?.clearRect( + 0, + 0, + renderSurface.width, + renderSurface.height + ); for (const particle of particles) { particle.render(); } - window.requestAnimationFrame(particleRenderLoop); + + window.requestAnimationFrame(renderLoop); } -document.addEventListener("mousemove", (event) => { - if (Date.now() - lastMoveTimestamp < 50) { + +window.requestAnimationFrame(renderLoop); + +setInterval((e) => { + renderSurface.width = document.documentElement.scrollWidth; + renderSurface.height = document.documentElement.scrollHeight; +}, 1000); + +let lastMoveTimestamp = 0; + +document.documentElement.addEventListener("mousemove", (event) => { + if (Date.now() - lastMoveTimestamp < 20) { return; } + lastMoveTimestamp = Date.now(); - new Particle( - event.pageX + (Math.random() * 10 - 20), - event.pageY + (Math.random() * 10 - 20) - ); + const particle = new Particle(event.pageX, event.pageY); + particles.push(particle); }); -window.requestAnimationFrame(particleRenderLoop);