snowflake rewrite
This commit is contained in:
parent
39c53b1bd1
commit
b2b7360a65
11 changed files with 428 additions and 361 deletions
12
src/js/index.ts
Normal file
12
src/js/index.ts
Normal 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",
|
||||
},
|
||||
);
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue