【问题标题】:How to attach multiple react-spring springs on a single component?如何在单个组件上附加多个反应弹簧?
【发布时间】:2020-11-22 13:22:36
【问题描述】:

我正在尝试学习如何使用 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 上实现相同类型的动画的最佳方法是什么?如何制作同一个弹簧的多个实例以用于多个 Dom 对象而不同时触发它们?我当然不想为每个项目复制一整套代码,对吧?

我是否需要创建一个函数来接受可以在配置中即时切换参数的参数? ??????????‍♂️ 任何帮助表示赞赏。

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

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

【问题讨论】:

    标签: react-spring


    【解决方案1】:

    第一种可能性是分离样式并将其分配给多个 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>
      )
    

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

    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

    【讨论】:

    • 啊!我并没有以模块化的方式思考。太感谢了。完全有道理。 ?
    猜你喜欢
    • 2019-09-18
    • 2019-02-18
    • 2019-09-30
    • 2010-10-06
    • 1970-01-01
    • 2022-10-20
    • 2020-08-22
    • 2011-07-13
    • 1970-01-01
    相关资源
    最近更新 更多