0

I have started playing around with react-spring and I am loving the concept but I am struggling to work out how to build the animation that I want.

I would like to make a div move to the right, then back to start, then to the right, but not as far, back to start, to the right, but not as far again and finally back to start. Just like a spring, that is pulled and when released goes boingoingoing back to it's resting place.

I can see from the documentation how to adjust the feel of the spring and how to trigger the animation, but I have never made an animation before so knowing which properties to change and how to make it loop properly are what I am looking for help on.

Edit: I have this animation so far, and it works, but it feels very disjointed.

const shake = useSpring({ 
    from: { "margin-left": 0 },
    to: [
        { "margin-left": 30 },
        { "margin-left": 0 },
        { "margin-left": 20 },
        { "margin-left": 0 },
        { "margin-left": 10 },
        { "margin-left": 0 }
    ],
    config: {
        mass: 1,
        tension: 500,
        friction: 10
    }
});

Currently it is clearly three movements, can I decrease the delay between the movements so that it looks like one movement?

Is margin left the best CSS property to use?

Exitialis
  • 411
  • 6
  • 26
  • The question is too broad... As SO isn't a coding service, you should try building some layout, show some attempts and ask how to animate a specific div, please refer to [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) – Dennis Vash Sep 24 '19 at 16:53
  • Sorry, I have added what I have so far – Exitialis Sep 25 '19 at 08:44

1 Answers1

1

UPDATE START

I just came across a simple solution for this problem. It I way better than the one I tried to achieve with configuration. It uses interpolation with range. It is using transform now but can easily adopted to margin.

export default function App() {
  const { x } = useSpring({
    from: { x: 0 },
    to: { x: 1 }
  });

  return (
    <div className="App">
      <animated.div
        style={{
          transform: x
            .interpolate({
              range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
              output: [180, 220, 180, 220, 180, 220, 180, 200]
            })
            .interpolate(x => `translate3d(${x}px, 0px, 0px)`)
        }}
      >
        Shake
      </animated.div>
    </div>
  );
}

https://codesandbox.io/s/awesome-framework-go5oh?file=/src/App.js:103-609

UPDATE END*

You can achieve the bouncy effect. There are 3 variable controlling the spring based animation:

  • mass
  • friction
  • tension

You can play with the pink square here: https://www.react-spring.io/docs/hooks/api I recommend low mass and friction and high tension. You can set these variable in every animation type. For example:

useSpring({ ..., config: {mass: 1, tension: 500, friction: 10} });
Peter Ambruzs
  • 7,763
  • 3
  • 30
  • 36
  • Thank you, that has made it look better, I have updated the question with what I have so far. Do you know what I could change to make it feel like one movement and less disjointed? – Exitialis Sep 25 '19 at 08:45
  • What about changing the 'to' value to a single parameter instead of array. In my solution the back and forth movement is caused by the spring animation. You have to define only the two extreme position. And you should use the inline styles with camelCase eg: `from: { marginLeft: 0 }` – Peter Ambruzs Sep 25 '19 at 09:19