【问题标题】:Canvas in react not rerendering every props update反应中的画布不会重新渲染每个道具更新
【发布时间】:2020-02-18 18:02:53
【问题描述】:

我一直在尝试实现受Apple's landing page启发的滚动视频视差效果 在 React.js 中。我已经非常接近这些参考:

https://codepen.io/ollieRogers/pen/lfeLc/

http://www.petecorey.com/blog/2019/08/19/animating-a-canvas-with-react-hooks/

但是在滚动时,框架只会在我停止滚动时更新。我对画布的期望结果是在滚动时以流畅的方式呈现。换句话说,每次我的props.scrollPos 更新时,框架都应该更新。

了解父级的所有重要信息是它使用scrollTop 传递滚动位置。这个组件应该是可重用的,并且相对于它的父级工作,这就是我选择不在内部保持滚动状态的原因。

您可以在 CodeSandbox 上查看我的代码 here 的工作示例

ParallaxVideo.js

...

// request animation frame
// when scrollpos updates the current frame needs to change and cause rerender
// frame = (scrollPos - offset) / playbackConst

const ParallaxVideo = props => {
  ...

  useEffect(() => {
    let requestId;
    const context = canvasRef.current.getContext("2d")
    const offset = heightRef.current.offsetTop
    videoRef.current.currentTime = (props.scrollPos - offset) / playbackConst
    console.log(props.scrollPos)

    const render = () => {
      context.drawImage(videoRef.current, 0, 0)
      requestId = requestAnimationFrame(render)
    }

    render()


    return () => cancelAnimationFrame(requestId)
  })


  return (
    <div 
      style={{height: scrollHeight}}
      ref={heightRef}
    >
      <VideoWrap>
        <Video
          muted
          preload={preload}
          autoPlay={autoPlay} 
          loop={loop} 
          ref={videoRef}
          fitToScreen={fitToScreen}
          onLoadedMetadata={updateHeight}
          playsInline
        >
          {props.children}
        </Video>
        <Canvas ref={canvasRef}/>
      </VideoWrap>
    </div>
  )
}

【问题讨论】:

    标签: javascript reactjs canvas html5-video react-hooks


    【解决方案1】:

    肯定不会改变 useEffect 应该有一个输入集来监听变化,

    useEffect(() => {
        let requestId;
        const context = canvasRef.current.getContext("2d")
        const offset = heightRef.current.offsetTop
        videoRef.current.currentTime = (props.scrollPos - offset) / playbackConst
        console.log(props.scrollPos)
    
        const render = () => {
          context.drawImage(videoRef.current, 0, 0)
          requestId = requestAnimationFrame(render)
        }
    
        render()
    
    
        return () => cancelAnimationFrame(requestId)
      },[props.scrollPos])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-01
      • 2021-01-19
      • 2019-03-14
      • 1970-01-01
      • 1970-01-01
      • 2021-01-22
      相关资源
      最近更新 更多