You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Typescript实现HTML5 Canvas星空穿梭动画报错如何解决

React + TypeScript 星空穿梭动画修复方案

以下是可直接运行的修复后代码:

import React, { useRef, useEffect } from 'react';

const Canvas = () => {
  const canvasRef = useRef<HTMLCanvasElement | null>(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    // 获取URL参数工具函数
    const getUrlParameter = (sParam: string) => {
      const sPageURL = decodeURIComponent(window.location.search.substring(1));
      const sURLVariables = sPageURL.split('&');
      for (let i = 0; i < sURLVariables.length; i++) {
        const sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] === sParam) {
          return sParameterName[1] === undefined ? true : sParameterName[1];
        }
      }
      return null;
    };

    // 定义Star类
    class Star {
      X: number;
      Y: number;
      SX: number;
      SY: number;
      W: number;
      H: number;
      age: number;
      dies: number;
      ID: number;
      C: string;

      constructor() {
        this.X = canvas.width / 2;
        this.Y = canvas.height / 2;

        this.SX = Math.random() * 10 - 5;
        this.SY = Math.random() * 10 - 5;

        const start = Math.max(canvas.width, canvas.height);
        this.X += this.SX * start / 10;
        this.Y += this.SY * start / 10;

        this.W = 1;
        this.H = 1;
        this.age = 0;
        this.dies = 500;

        starIndex++;
        stars[starIndex] = this;
        this.ID = starIndex;
        this.C = "#ffffff";
      }

      Draw() {
        this.X += this.SX;
        this.Y += this.SY;

        this.SX += this.SX / (50 / acceleration);
        this.SY += this.SY / (50 / acceleration);

        this.age++;

        if (
          this.age == Math.floor(50 / acceleration) || 
          this.age == Math.floor(150 / acceleration) || 
          this.age == Math.floor(300 / acceleration)
        ) {
          this.W++;
          this.H++;
        }

        if (
          this.X + this.W < 0 || this.X > canvas.width ||
          this.Y + this.H < 0 || this.Y > canvas.height
        ) {
          delete stars[this.ID];
          numStars--;
        }

        ctx.fillStyle = this.C;
        ctx.fillRect(this.X, this.Y, this.W, this.H);
      }
    }

    const stars: Record<number, Star> = {};
    let starIndex = 0;
    let numStars = 0;
    let acceleration: number = 1;
    let starsToDraw: number = (canvas.width * canvas.height) / 200;

    // 处理URL参数,转成数字类型
    const customStars = getUrlParameter("stars");
    if (customStars) starsToDraw = Number(customStars);
    const customAccel = getUrlParameter("accel");
    if (customAccel) acceleration = Number(customAccel);

    // 初始化画布尺寸
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    const draw = () => {
      // 同步窗口尺寸
      if (canvas.width !== window.innerWidth) canvas.width = window.innerWidth;
      if (canvas.height !== window.innerHeight) canvas.height = window.innerHeight;

      // 绘制背景蒙层
      ctx.fillStyle = "rgba(0, 0, 0, 0.8)";
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      // 补充缺失的星星
      for (let i = numStars; i < starsToDraw; i++) {
        new Star();
        numStars++;
      }

      // 绘制所有星星
      for (const starId in stars) {
        stars[starId].Draw();
      }
    };

    // 启动定时器,存储id用于清理
    const intervalId = setInterval(draw, 40);

    // 组件卸载时清理定时器
    return () => clearInterval(intervalId);
  }, []);

  return <canvas 
    ref={canvasRef} 
    style={{ position: 'fixed', top: 0, left: 0, width: '100vw', height: '100vh', zIndex: -1 }}
  />;
}

export default Canvas;

核心修改点

  • 替换传统函数构造的Star为TS Class,显式定义每个属性的类型,解决构造函数this指向和类型识别的报错
  • 新增canvas实例和context的非空判断,跳过空值执行分支,消除类型报错同时避免运行时异常
  • 对URL参数获取的自定义配置做强制数值转换,避免字符串类型参与数值运算导致的逻辑错误
  • 补充定时器清理逻辑,组件卸载时自动清除动画定时器,避免内存泄漏和重复执行问题
  • 给canvas元素补充全屏固定定位样式,确保动画默认占满整个浏览器视口,无需额外父容器适配

内容的提问来源于stack exchange,提问作者Rushikesh Gadekar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 14:36:04