如何在单个组件上附加多个 react-spring springs?

How to attach multiple react-spring springs on a single component?

我正在尝试学习如何使用 react-spring。假设我有三个要设置动画的 div。

<a.div style={trans1}>
<a.div style={trans2}>
<a.div style={trans3}>

而 trans1 具有以下配置…

  const [clicked, toggle] = useState(null)
  const { x } = useSpring({
    from: { x: 0 },
    x: clicked ? 1 : 0,
    config: { duration: 500 },
  })

  const trans1 = {
    transform: x
      .interpolate({
        range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
        output: [1, 0.97, 0.9, 1.1, 0.9, 1.1, 1.03, 1],
      })
      .interpolate((x) => `scale(${x})`),
  }

在第二个和第三个 div 上实现相同类型的动画而不复制所有代码的最佳方法是什么?如何使相同 spring 的多个实例用于多个 Dom 对象而不同时触发它们?我当然不想为每个项目复制一整套代码,对吗?

我是否需要创建一个接受参数的函数,该参数可以动态切换配置中的参数? ‍♂️ 感谢任何帮助。

这是一个活生生的例子:https://codesandbox.io/s/optimistic-bassi-brnle

如何在不创建重复代码的情况下让左右两侧一次设置一个动画?

第一种可能是将样式分开并给多个div。它的缺点是,它们在同一时间的行为完全相同。

  const style = {
    opacity: x.interpolate({ range: [0, 1], output: [0.3, 1] }),
    transform: x
      .interpolate({
        range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
        output: [1, 0.97, 0.9, 1.1, 0.9, 1.1, 1.03, 1]
      })
      .interpolate(x => `scale(${x})`)
  };
  return (
    <div onClick={() => toggle(!state)}>
      <animated.div
        style={style}>
        click
      </animated.div>
      <animated.div
        style={style}>
        click
      </animated.div>
    </div>
  )

第二个选项是,您使用点击和 spring 逻辑创建一个新组件。这样你写一次逻辑就​​可以多次使用它。我还引入了一个文本属性来为组件制作不同的文本。

const AnimText = ({text}) => {
  const [state, toggle] = useState(true)
  const { x } = useSpring({ from: { x: 0 }, x: state ? 1 : 0, config: { duration: 1000 } })
  return (
    <div onClick={() => toggle(!state)}>
      <animated.div
        style={{
          opacity: x.interpolate({ range: [0, 1], output: [0.3, 1] }),
          transform: x
            .interpolate({
              range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
              output: [1, 0.97, 0.9, 1.1, 0.9, 1.1, 1.03, 1]
            })
            .interpolate(x => `scale(${x})`)
        }}>
        {text}
      </animated.div>
    </div>
  )
}

function Demo() {
  return (
    <div>
      <AnimText text={'click1'}/>
      <AnimText text={'click2'}/>
      <AnimText text={'click3'}/>
    </div>
  )
}

示例如下:https://codesandbox.io/s/divine-water-n1b6x