snowflake rewrite

This commit is contained in:
z0x 2024-11-17 01:11:58 -05:00
parent 39c53b1bd1
commit b2b7360a65
11 changed files with 428 additions and 361 deletions

12
src/js/index.ts Normal file
View file

@ -0,0 +1,12 @@
import { animate, stagger } from "motion";
const elements = document.querySelectorAll("img, h1");
animate(
elements,
{ opacity: [0, 1] },
{
duration: 0.6,
delay: stagger(0.6, { startDelay: 0.2 }),
ease: "easeIn",
},
);

View file

@ -1,27 +1,79 @@
function createSnowflakes() {
const numSnowflakes = 50;
const maxSize = 0.2;
const maxTranslate = 10;
const container = document.getElementById('snowflake-container');
function randomBetween(min, max) {
return (Math.random() * max) + min;
class SnowEffect {
private canvas: HTMLCanvasElement;
private ctx: CanvasRenderingContext2D;
private flakes: Array<[number, number, number, number, number]>; // [x, y, radius, drop, sway]
constructor(flakeCount = 320) {
this.canvas = document.createElement("canvas");
this.ctx = this.canvas.getContext("2d")!;
this.flakes = [];
this.initCanvas();
this.initFlakes(flakeCount);
this.animate = this.animate.bind(this);
window.addEventListener("resize", () => this.updateCanvasSize());
requestAnimationFrame(this.animate);
}
if (container) {
for (let i = 0; i < numSnowflakes; i++) {
let randomSize = randomBetween(5, 25) + "px";
let randomLeft = randomBetween(0, window.innerWidth) + "px";
let randomDuration = randomBetween(3, 10);
const snowflake = document.createElement('div');
snowflake.classList.add('snowflake');
snowflake.style.width = randomSize;
snowflake.style.height = randomSize;
snowflake.style.left = randomLeft;
snowflake.style.animationDuration = randomDuration + "s";
snowflake.style.animationDelay = randomBetween(0, 5) + "s";
private initCanvas(): void {
this.canvas.style.cssText =
"position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:999";
document.body.appendChild(this.canvas);
this.updateCanvasSize();
}
container.appendChild(snowflake);
private updateCanvasSize(): void {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
}
private initFlakes(count: number): void {
const { width, height } = this.canvas;
this.flakes = Array.from({ length: count }, () => [
Math.random() * width, // x
Math.random() * height, // y
Math.random() * 1.75 + 0.25, // radius
Math.random() * 1.5 + 0.5, // drop speed
Math.random() * 0.6 - 0.3, // sway
]);
}
private animate(): void {
const { width, height } = this.canvas;
// Clear canvas
this.ctx.clearRect(0, 0, width, height);
// Draw flakes
this.ctx.fillStyle = "rgba(255, 255, 255, 0.4)";
this.ctx.beginPath();
// Update and draw flakes
for (const flake of this.flakes) {
// Update position
flake[1] += flake[3]; // y += drop
flake[0] += flake[4]; // x += sway
// Wrap horizontally
if (flake[0] > width) flake[0] -= width;
else if (flake[0] < 0) flake[0] += width;
// Reset when below screen
if (flake[1] > height) {
flake[1] = -flake[2];
flake[0] = Math.random() * width;
}
// Draw flake
this.ctx.moveTo(flake[0], flake[1]);
this.ctx.arc(flake[0], flake[1], flake[2], 0, Math.PI * 2);
}
this.ctx.fill();
requestAnimationFrame(this.animate);
}
}
createSnowflakes();
// start
new SnowEffect();