How do I give an Anime.js element an opening animation first, and then a looping animation?

Viewed 1141

I'm trying to animate an object with Anime.js. It has an opening animation (rotate) that plays once, and after that it should have a different rotate animation which loops indefinitely. I put both thesse animations in a timeline, but it won't loop the second animation.

Javascript:

var tl = anime.timeline({

  easing: 'easeOutExpo',
  targets: '.fles',
});

tl

.add({
  rotate: 20,
  duration: 750,
  loop: false,
})

.add({
    duration: 6000,
    loop: true,
    easing: 'easeInOutQuad',
    keyframes: [
        {rotate: '+=1'},
        {rotate: '-=1'},
        {rotate: '+=1.5'},
        {rotate: '-=2'},
        {rotate: '+=1.5'},
    ],
})

Is this possible with Anime.js, and how?

Thanks in advance!

2 Answers

It is not possible to do it with timelines, timeline just loops when you pass loop: true on its creation. From source code it seems that loop property in added objects is ignored.

However you can use promise .finished on anime instance:

anime({/*first animation*/}).finished.then(()=>
anime({/*next animation*/}))

and to mimic inheriting properties:

let base = {
  easing: 'easeOutExpo',
  targets: '.fles',
}

anime(Object.assign({}, base, {
  rotate: 20,
  duration: 750,
  loop: false,
}))
.finished.then(()=>
  anime(Object.assign({}, base, {
    duration: 6000,
    loop: true,
    easing: 'easeInOutQuad',
    keyframes: [
      {rotate: '+=1'},
      {rotate: '-=1'},
      {rotate: '+=1.5'},
      {rotate: '-=2'},
      {rotate: '+=1.5'},
    ],
  })));

This may be solved by using an inner and an outer <div>. Place the looping animation on one of them, and the opening animation on the other.

<div id="outer">
  <div id="inner">
    Foo
  </div>
</div>
// opening animation
anime({
  targets: '#outer',
  scale: [0, 1],
  loop: false
});

// looping animation
anime({
  targets: '#inner',
  rotate: [-5, 5],
  loop: true,
  direction: 'alternate'
});

Related