Холст в реакции не рендерит каждый реквизит обновления - PullRequest
0 голосов
/ 18 февраля 2020

Я пытался реализовать эффект параллакса для прокрутки видео, вдохновленный целевой страницей Apple в 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.

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>
  )
}

1 Ответ

0 голосов
/ 20 февраля 2020

точно не изменит 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])
...