This commit is contained in:
ryan
2026-07-13 15:17:45 +08:00
parent 08e61ce833
commit e0eb4e5975
334 changed files with 17212 additions and 12321 deletions
+52 -52
View File
@@ -1,37 +1,37 @@
"use client"
'use client';
import { useEffect, useRef } from "react"
import { useEffect, useRef } from 'react';
interface Snowflake {
x: number
y: number
radius: number
speed: number
opacity: number
drift: number
x: number;
y: number;
radius: number;
speed: number;
opacity: number;
drift: number;
}
export function SnowEffect() {
const canvasRef = useRef<HTMLCanvasElement>(null)
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current
if (!canvas) return
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d")
if (!ctx) return
const ctx = canvas.getContext('2d');
if (!ctx) return;
let animationFrameId: number
let snowflakes: Snowflake[] = []
let animationFrameId: number;
let snowflakes: Snowflake[] = [];
const resizeCanvas = () => {
canvas.width = window.innerWidth
canvas.height = window.innerHeight
}
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};
const createSnowflakes = () => {
const count = Math.floor(window.innerWidth / 4)
snowflakes = []
const count = Math.floor(window.innerWidth / 4);
snowflakes = [];
for (let i = 0; i < count; i++) {
snowflakes.push({
x: Math.random() * canvas.width,
@@ -39,58 +39,58 @@ export function SnowEffect() {
radius: Math.random() * 3 + 1,
speed: Math.random() * 2 + 0.5,
opacity: Math.random() * 0.5 + 0.3,
drift: Math.random() * 1 - 0.5
})
drift: Math.random() * 1 - 0.5,
});
}
}
};
const drawSnowflakes = () => {
if (!ctx || !canvas) return
ctx.clearRect(0, 0, canvas.width, canvas.height)
if (!ctx || !canvas) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
snowflakes.forEach((flake) => {
ctx.beginPath()
ctx.arc(flake.x, flake.y, flake.radius, 0, Math.PI * 2)
ctx.fillStyle = `rgba(255, 255, 255, ${ flake.opacity })`
ctx.fill()
ctx.beginPath();
ctx.arc(flake.x, flake.y, flake.radius, 0, Math.PI * 2);
ctx.fillStyle = `rgba(255, 255, 255, ${flake.opacity})`;
ctx.fill();
flake.y += flake.speed
flake.x += flake.drift
flake.y += flake.speed;
flake.x += flake.drift;
if (flake.y > canvas.height) {
flake.y = -flake.radius
flake.x = Math.random() * canvas.width
flake.y = -flake.radius;
flake.x = Math.random() * canvas.width;
}
if (flake.x > canvas.width) {
flake.x = 0
flake.x = 0;
} else if (flake.x < 0) {
flake.x = canvas.width
flake.x = canvas.width;
}
})
});
animationFrameId = requestAnimationFrame(drawSnowflakes)
}
animationFrameId = requestAnimationFrame(drawSnowflakes);
};
resizeCanvas()
createSnowflakes()
drawSnowflakes()
resizeCanvas();
createSnowflakes();
drawSnowflakes();
window.addEventListener("resize", () => {
resizeCanvas()
createSnowflakes()
})
window.addEventListener('resize', () => {
resizeCanvas();
createSnowflakes();
});
return () => {
cancelAnimationFrame(animationFrameId)
window.removeEventListener("resize", resizeCanvas)
}
}, [])
cancelAnimationFrame(animationFrameId);
window.removeEventListener('resize', resizeCanvas);
};
}, []);
return (
<canvas
ref={canvasRef}
className="fixed inset-0 pointer-events-none z-50"
style={{ background: "transparent" }}
className='fixed inset-0 pointer-events-none z-50'
style={{ background: 'transparent' }}
/>
)
);
}