开发者问题收集

无法读取未定义的属性(读取‘getContext’)

2022-11-24
1554

我试图用 GSAP 制作滚动动画,但是我似乎无法让 useRef 按照我喜欢的方式工作。

我试图让 canvasRef 等于 HTML 中的画布,但是我收到了错误:无法读取未定义的属性(读取“getContext”)

当我控制台记录 canvasRef 时,我得到了 {current: undefined, width: 1281, height: 800

任何建议帮助都很好,谢谢

function Landing() {
  const canvasRef = useRef();
  canvasRef.width = window.innerWidth;
  canvasRef.height = window.innerHeight;

  console.log(canvasRef);

  const context = canvasRef.current.getContext("2d");
  const frameCount = 230;

  const currentFrame = (index) =>
    `../../assets/landing-animations/${(index + 1).toString()}.jpg`;
  const images = [];
  let ball = { frame: 0 };

  for (let i = 0; i < frameCount; i++) {
    const img = new Image();
    img.src = currentFrame(i);
    images.push(img);
  }

  function render() {
    context.clearRect(0, 0, canvasRef.width, canvasRef.height);
    context.drawImage(images[ball.frame]);
  }

  return (
    <div className="landing">
      <h1 className="landing__header">Welcome to my portfolio</h1>
      <canvas className="landing__canvas" ref={canvasRef}></canvas>;
    </div>
  );
}
1个回答

您的代码在元素呈现之前运行。

将所有代码放入 useEffect 中,它应该可以解决您的问题。

useEffect(()=>{
    // ... your code (except the return and definitions)
}, []);

数组需要为空(但仍在那里),这样 React 就知道只运行一次。
该函数将在 onMount 中运行一次。( React 的文档

确保您将 useRef 和其他定义留在 useEffect 之外,以便您可以从代码中访问 ref。

function Landing() {
  const canvasRef = useRef();
  canvasRef.width = window.innerWidth;
  canvasRef.height = window.innerHeight;

  console.log(canvasRef);
  
  useEffect(() => {
    if (canvasRef.current == null) return;

    const context = canvasRef.current.getContext("2d");
    const frameCount = 230;

    const currentFrame = (index) =>
      `../../assets/landing-animations/${(index + 1).toString()}.jpg`;
    const images = [];
    let ball = { frame: 0 };

    for (let i = 0; i < frameCount; i++) {
    const img = new Image();
      img.src = currentFrame(i);
      images.push(img);
    }

    function render() {
      context.clearRect(0, 0, canvasRef.width, canvasRef.height);
      context.drawImage(images[ball.frame]);
    }
  }, []);

  return (
    <div className="landing">
      <h1 className="landing__header">Welcome to my portfolio</h1>
      <canvas className="landing__canvas" ref={canvasRef}></canvas>;
    </div>
  );
}
Battledash2
2022-11-24