Как выполнить две анимации последовательно, используя React-Spring?

Я попытался связать две пружины (используя useChain), так что одна запускается только после того, как другая заканчивается, но они анимируются одновременно. Что я делаю неправильно?

import React, { useRef, useState } from 'react'
import { render } from 'react-dom'
import { useSpring, animated, useChain } from 'react-spring'

function App() {
  const [counter, setCounter] = useState(0)
  const topRef = useRef()
  const leftRef = useRef()
  const { top } = useSpring({ top: (window.innerHeight * counter) / 10, ref: topRef })
  const { left } = useSpring({ left: (window.innerWidth * counter) / 10, ref: leftRef })

  useChain([topRef, leftRef])

  return (
    <div id="main" onClick={() => setCounter((counter + 1) % 10)}>
      Click me!
      <animated.div id="movingDiv" style={{ top, left }} />
    </div>
  )
}

render(<App />, document.getElementById('root'))

Вот кодовый ящик, демонстрирующий проблему: https://codesandbox.io/s/react-spring-usespring-hook-m4w4t


person eduter    schedule 10.04.2020    source источник


Ответы (2)


Я немного покопался, так как это тоже меня озадачило, и наткнулся на этот чат спектра.

Я не уверен, что полностью понимаю, что происходит, но кажется, что значение current ссылок в вашем коде читается только один раз, и поэтому, когда компонент монтируется, цепочка завершается мгновенно и никогда не сбрасывается. Ваш код действительно работает, если вы вводите жестко запрограммированные значения для двух пружин, а затем управляете ими с помощью поворотников, но, очевидно, вы ищете динамическое решение.

Я протестировал это, и, похоже, он работает:

const topCurrent = !topRef.current ? topRef : {current: topRef.current};
const leftCurrent = !leftRef.current ? leftRef : {current: leftRef.current};

useChain([topCurrent, leftCurrent]);

Это заставляет цепочку каждый раз ссылаться на текущее значение ref. Поворот здесь, потому что значение ref на mount равно undefined - может быть более элегантный способ учесть это.

person lawrence-witt    schedule 11.04.2020
comment
По-видимому, достаточно использовать этот обходной путь только в одной из ссылок. Я даже пробовал добавить третью пружину, и она все еще работает: codesandbox.io/ s / react-spring-usechain-hook-xww20 - person eduter; 11.04.2020

Я только что узнал, что есть гораздо более простое решение, использующее только useSpring:

function App() {
  const [counter, setCounter] = useState(0)

  const style = useSpring({
    to: [
      { top: (window.innerHeight * counter) / 5 },
      { left: (window.innerWidth * counter) / 5 }
    ]
  })

  return (
    <div id="main" onClick={() => setCounter((counter + 1) % 5)}>
      Click me!
      <animated.div id="movingDiv" style={style} />
    </div>
  )
}

Пример: https://codesandbox.io/s/react-spring-chained-animations-8ibpi

person eduter    schedule 13.04.2020