feat: 添加预览效果页面并优化交互效果

refactor: 优化代码健壮性和类型安全

style: 更新字体样式和全局CSS

fix: 修复IntersectionObserver潜在空引用问题

chore: 更新依赖和ESLint配置

build: 更新构建ID和路由配置
This commit is contained in:
张翔
2026-02-24 10:24:05 +08:00
parent 64165c4499
commit fecbfd1990
239 changed files with 3403 additions and 5181 deletions
+18 -14
View File
@@ -1,7 +1,7 @@
'use client';
import { useEffect, useRef, useState, useCallback } from 'react';
import { motion, useMotionValue, useTransform } from 'framer-motion';
import { motion, useMotionValue } from 'framer-motion';
interface Particle {
x: number;
@@ -31,7 +31,7 @@ export function ParticleGalaxy({
}: ParticleGalaxyProps) {
const canvasRef = useRef<HTMLCanvasElement>(null);
const particlesRef = useRef<Particle[]>([]);
const animationRef = useRef<number>();
const animationRef = useRef<number | undefined>(undefined);
const [isVisible, setIsVisible] = useState(false);
const mouseX = useMotionValue(0);
@@ -83,8 +83,8 @@ export function ParticleGalaxy({
x += vx;
y += vy;
if (x < 0 || x > width) vx *= -1;
if (y < 0 || y > height) vy *= -1;
if (x < 0 || x > width) {vx *= -1;}
if (y < 0 || y > height) {vy *= -1;}
x = Math.max(0, Math.min(width, x));
y = Math.max(0, Math.min(height, y));
@@ -108,15 +108,19 @@ export function ParticleGalaxy({
for (let i = 0; i < particles.length; i++) {
for (let j = i + 1; j < particles.length; j++) {
const dx = particles[i].x - particles[j].x;
const dy = particles[i].y - particles[j].y;
const p1 = particles[i];
const p2 = particles[j];
if (!p1 || !p2) {continue;}
const dx = p1.x - p2.x;
const dy = p1.y - p2.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < connectionDistance) {
const opacity = (1 - distance / connectionDistance) * 0.3;
ctx.beginPath();
ctx.moveTo(particles[i].x, particles[i].y);
ctx.lineTo(particles[j].x, particles[j].y);
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
ctx.strokeStyle = `rgba(${lineColor}, ${opacity})`;
ctx.lineWidth = 0.5;
ctx.stroke();
@@ -127,10 +131,10 @@ export function ParticleGalaxy({
const animate = useCallback(() => {
const canvas = canvasRef.current;
if (!canvas) return;
if (!canvas) {return;}
const ctx = canvas.getContext('2d');
if (!ctx) return;
if (!ctx) {return;}
drawParticles(ctx, canvas.width, canvas.height);
animationRef.current = requestAnimationFrame(animate);
@@ -138,10 +142,10 @@ export function ParticleGalaxy({
const handleResize = useCallback(() => {
const canvas = canvasRef.current;
if (!canvas) return;
if (!canvas) {return;}
const container = canvas.parentElement;
if (!container) return;
if (!container) {return;}
canvas.width = container.clientWidth;
canvas.height = container.clientHeight;
@@ -151,10 +155,10 @@ export function ParticleGalaxy({
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
if (!canvas) {return;}
const container = canvas.parentElement;
if (!container) return;
if (!container) {return;}
canvas.width = container.clientWidth;
canvas.height = container.clientHeight;