Как прикрепить несколько пружин реактивной пружины к одному компоненту?

Я пытаюсь научиться использовать реактивную пружину. Допустим, у меня есть три элемента 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

Как сделать так, чтобы левая и правая стороны анимировались по одной, не создавая дублирующийся код?


person Selino    schedule 02.08.2020    source источник


Ответы (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>
  )

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

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

person Peter Ambruzs    schedule 02.08.2020
comment
Ах! Я не думал модульными терминами. Большое спасибо. Имеет смысл. ???? - person Selino; 02.08.2020