snow mod, font removal
This commit is contained in:
parent
1eeb7a105f
commit
b60ee587e1
8 changed files with 95 additions and 103 deletions
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
@ -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.
|
@ -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
89
src/js/snow.ts
Normal 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();
|
|
@ -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();
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue