110 lines
2.8 KiB
TypeScript
110 lines
2.8 KiB
TypeScript
const renderSurface = document.createElement("canvas");
|
|
renderSurface.style.position = "absolute";
|
|
renderSurface.style.left = "0px";
|
|
renderSurface.style.top = "0px";
|
|
renderSurface.style.pointerEvents = "none";
|
|
renderSurface.style.width = "100%";
|
|
renderSurface.height = document.documentElement.scrollHeight;
|
|
|
|
document.body.insertBefore(renderSurface, document.body.firstElementChild);
|
|
|
|
const renderSurfaceContext = renderSurface.getContext("2d")!;
|
|
|
|
let particles: Particle[] = [];
|
|
|
|
function getRandomArbitrary(min: number, max: number) {
|
|
return Math.random() * (max - min) + min;
|
|
}
|
|
|
|
class Particle {
|
|
x: number;
|
|
y: number;
|
|
id: number;
|
|
|
|
angle: number;
|
|
color: string;
|
|
style: string;
|
|
|
|
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 ? "+" : "*";
|
|
}
|
|
|
|
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(renderLoop);
|
|
}
|
|
|
|
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();
|
|
const particle = new Particle(event.pageX, event.pageY);
|
|
particles.push(particle);
|
|
});
|
|
|
|
document.documentElement.addEventListener("touchmove", function(e) {
|
|
for(let i = 0; i < e.touches.length; i++) {
|
|
if (Date.now() - lastMoveTimestamp < 50) {
|
|
return;
|
|
}
|
|
|
|
lastMoveTimestamp = Date.now();
|
|
const touch = e.touches.item(i);
|
|
if(!touch) return;
|
|
|
|
const particle = new Particle(touch.pageX, touch.pageY);
|
|
particles.push(particle);
|
|
}
|
|
}, false);
|