3

I've followed two aprroaches to animate a Carousel component that I'm building. I'm using React with React hooks.

OPTION #1: with anime.js

  • I change the selected state and a useEffect() hook calls the animation animateScroll() on my component.
  • The animation is done with anime.js as per the code below.
  • What happens: some Javascript runs on background and updates an inline style style="transform: translateX(-200%);" according to the selected easing property.
function animateScroll() {
    anime({
      targets: sliderRef.current,
      translateX: selected * -100 + '%',
      easing: 'cubicBezier(0.19, 1, 0.22, 1)',
      duration: 1000
    });
  }

enter image description here

OPTION #2: regular CSS transitions with styled components

  • I change the selected state and that changes a position prop of my styled-component S.Slider_DIV which should slide with translateX.
  • Styled component then updates the translateX property and updates the CSS class of my S.Slider_DIV component with the new value for the translateX property.
<S.Slider_DIV ref={sliderRef} position={selected}>
  {imageItems}
</S.Slider_DIV>
S.Slider_DIV = styled.div`
  transform: ${props => 'translateX( '+ props.position * -100 +'%)'};
  transition: transform 1.0s cubic-bezier(0.19, 1, 0.22, 1);
`;

enter image description here

THE ISSUE

  • Note that both easing functions are the same.
  • On Desktop browser I can't really tell the difference between the two approaches.
  • But on my phone (Galaxy A5 2017), the Option #1 with anime.js is much smoother.
  • Option #2 "stutters" a little bit specially during the transition phase where the increments are smaller, like in the final part of an 'easeOutExpo', for example.

QUESTION

Why is that? In this simple transition example, shouldn't the regular browser CSS transition be at least as smooth and efficient than one with a JS updating the inline style?

I'll try to make an example on CodeSandBox to reproduce the difference between the two.

EDIT: Here's the CodeSanbox: https://codesandbox.io/s/tx464

Open on your mobile phone and maybe you'll see the difference. Click several times in different click frequencies.

You'll see animeJS completely smooth and the regular one with Styled-components and CSS transitions is stuttering and changing speed.

I don't even know why the one with styled-components and regular transition changes speed when toggled during an ongoing animation.

The GIF below was made on Desktop. You can see the change in speed but you can't see the stuttering effect. Also both look ugly because the GIF sample rate is too low. But test for yourself and you see the animeJS is completely smooth and you'll the issues on the other one.

Both animations have the same duration and same cubicBezier timing.

enter image description here

cbdeveloper
  • 27,898
  • 37
  • 155
  • 336
  • there does seem to be a short circuit there. you can cause the same bug on the mdn page for transitions by quickly moving in and out of the hover target: https://developer.mozilla.org/en-US/docs/Web/CSS/transition – worc May 16 '19 at 17:59
  • i think the reason that anime.js is smoother is that it's pretty strict about the parameters of the animation. no matter what it's going to take 2s to get to its end goal. the native transitions seem to be addressing some other use case where you're trying to quickly undo an animation you didn't mean to trigger? – worc May 16 '19 at 18:04
  • @worc Yeah.. maybe this is it. It's pretty strange. I've always thought that browser would be more efficient. – cbdeveloper May 20 '19 at 07:46
  • it probably is more efficient if you're talking about rendering and painting to the DOM, but the implementation here is definitely a pain with this quick reset as some kind of undocumented "feature" – worc May 20 '19 at 23:29

0 Answers0