snow mod, font removal

This commit is contained in:
z0x 2025-01-01 12:40:14 -05:00
parent 1eeb7a105f
commit b60ee587e1
8 changed files with 95 additions and 103 deletions

BIN
bun.lockb

Binary file not shown.

View file

@ -17,9 +17,7 @@
"@astrojs/check": "^0.9.4",
"@biomejs/biome": "1.9.4",
"@tailwindcss/vite": "^4.0.0-beta.8",
"prettier": "^3.3.3",
"tailwindcss": "^4.0.0-beta.8",
"typescript": "^5.6.3"
},
"trustedDependencies": ["@biomejs/biome", "@parcel/watcher", "@tsparticles/engine", "esbuild", "sharp"]
}
}

Binary file not shown.

View file

@ -1,13 +1 @@
@import "tailwindcss";
@theme {
--font-sfpro: "sf-pro", sans-serif;
}
@font-face {
font-family: "sf-pro";
src: url("/fonts/SF-Pro.woff2") format("woff2");
font-weight: normal;
font-style: normal;
font-display: block;
}

89
src/js/snow.ts Normal file
View file

@ -0,0 +1,89 @@
interface Snowflake {
x: number;
y: number;
size: number;
opacity: number;
speedY: number;
speedX: number;
}
function createSnowfall() {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d")!;
document.body.style.margin = "0";
document.body.style.overflow = "hidden";
canvas.style.position = "fixed";
canvas.style.top = "0";
canvas.style.left = "0";
canvas.style.zIndex = "-1";
document.body.appendChild(canvas);
const resizeCanvas = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};
resizeCanvas();
window.addEventListener("resize", resizeCanvas);
const NUM_SNOWFLAKES = 320;
const snowflakes: Snowflake[] = [];
let windStrength = 0;
for (let i = 0; i < NUM_SNOWFLAKES; i++) {
snowflakes.push(createSnowflake());
}
function createSnowflake(): Snowflake {
const size = Math.random() * 3 + 1;
return {
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size,
opacity: Math.random() * 0.2 + 0.2,
speedY: Math.random() * size * 0.6 + 0.4,
speedX: Math.random() * 0.5 - 0.25,
};
}
function updateWind() {
windStrength += (Math.random() - 0.5) * 0.01;
windStrength = Math.max(-0.5, Math.min(0.5, windStrength));
}
function updateSnowflakes() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
updateWind();
for (const flake of snowflakes) {
flake.x += flake.speedX + windStrength;
flake.y += flake.speedY;
if (flake.y > canvas.height) {
flake.y = -flake.size;
flake.x = Math.random() * canvas.width;
flake.speedY = Math.random() * flake.size * 0.5 + 0.5;
flake.speedX = Math.random() * 0.5 - 0.25;
}
if (flake.x < -flake.size) {
flake.x = canvas.width + flake.size;
} else if (flake.x > canvas.width + flake.size) {
flake.x = -flake.size;
}
ctx.beginPath();
ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
ctx.fillStyle = `rgba(255, 255, 255, ${flake.opacity})`;
ctx.fill();
}
requestAnimationFrame(updateSnowflakes);
}
updateSnowflakes();
}
createSnowfall();

View file

@ -1,79 +0,0 @@
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);
}
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();
}
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);
}
}
// start
new SnowEffect();

View file

@ -11,16 +11,14 @@ import "/src/css/app.css";
<link rel="icon" type="image/x-icon" href="/src/img/logo_bg.svg" />
<link rel="icon" type="image/png" sizes="192x192" href="/src/img/logo_bg.svg" />
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="/src/img/logo_bg.svg" />
<link rel="preload" href="/fonts/SF-Pro.woff2" as="font" type="font/woff2" crossorigin />
</head>
<body class="bg-linear-to-b/oklch from-neutral-700 to-black text-white overflow-hidden">
<div class="flex items-center justify-center min-h-screen">
<div class="flex flex-col items-center justify-center w-full h-full max-w-[60vmin] max-h-[60vmin] md:max-w-[35vmin] md:max-h-[35vmin]">
<h1 class="text-4xl opacity-0 font-sfpro font-semibold">404</h1>
<h1 class="text-4xl opacity-0 font-semibold">404</h1>
</div>
</div>
<div id="snowflake-container"></div>
<script src="/src/js/snowflakes.ts"></script>
<script src="/src/js/snow.ts"></script>
<script src="/src/js/index.ts"></script>
</body>
</html>

View file

@ -14,17 +14,15 @@ import "/src/css/app.css";
<link rel="icon" type="image/x-icon" href="/src/img/logo_bg.svg" />
<link rel="icon" type="image/png" sizes="192x192" href="/src/img/logo_bg.svg" />
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="/src/img/logo_bg.svg" />
<link rel="preload" href="/fonts/SF-Pro.woff2" as="font" type="font/woff2" crossorigin />
</head>
<body class="bg-linear-to-b/oklch from-neutral-700 to-black text-white overflow-hidden">
<div class="flex items-center justify-center min-h-screen">
<div class="flex flex-col items-center justify-center w-full h-full max-w-[60vmin] max-h-[60vmin] md:max-w-[35vmin] md:max-h-[35vmin]">
<Image src={logo} alt="logo" class="w-2/3 opacity-0" loading="eager" />
<h1 class="text-4xl opacity-0 font-sfpro font-semibold">z0x</h1>
<h1 class="text-4xl opacity-0 font-semibold">z0x</h1>
</div>
</div>
<div id="snowflake-container"></div>
<script src="/src/js/snowflakes.ts"></script>
<script src="/src/js/snow.ts"></script>
<script src="/src/js/index.ts"></script>
</body>
</html>