I use Anime.js v 3.2.2.
An object should move by a complex path - an array of {x, y} coordinates.
The problem: The "easing" is not applied to the whole animation. Instead easing applies for each "step" from point to point.
Question: How to apply easing for whole animation with curved path (more that 2 {x,y} coordinates)?
// This works well
anime({
targets: simpleStateProxy,
x: 250,
duration: 1000,
round: 1,
easing: 'easeInCubic'
});
//This doesn't work as expected (animation is not smooth, easing is not applied for whole animation
anime({
targets: complexStateProxy,
x: [
{ value: 50 },
{ value: 100 },
{ value: 150 },
{ value: 200 },
{ value: 250 },
],
y: [
{ value: 20 },
{ value: 30 },
{ value: 30 },
{ value: 20 },
{ value: 0 },
],
duration: 1000,
round: 1,
easing: 'easeInCubic', //
complete: () => console.log('complex done')
});
Please check code snippet or jsfiddle.
Thanks.
P.S. If that's not possible in AnimeJS, maybe you could propose any other library which can do that? Preferably with an open license.
P.P.S: a link to the issue on github.
const simple = document.getElementById('simple');
const complex = document.getElementById('complex');
const simpleState = { x: 0, y: 0 } //x - left, y - top
const complexState = { x: 0, y: 0 } //x - left, y - top
// do not pay attention to this
const simpleStateProxy = new Proxy(simpleState, {
set: (target, key, value) => {
target[key] = value;
simple.style.left = `${value}px`;
return true;
},
});
// do not pay attention to this
const complexStateProxy = new Proxy(complexState, {
set: (target, key, value) => {
target[key] = value;
if (key === 'x') complex.style.left = `${value}px`;
if (key === 'y') complex.style.top = `${value}px`;
return true;
},
});
// Animation of a "simple" box
anime({
targets: simpleStateProxy,
x: 250,
duration: 1000,
round: 1,
easing: 'easeInCubic',
complete: () => console.log('simple done')
});
// Animation of a "complex" box
anime({
targets: complexStateProxy,
x: [
{ value: 50 },
{ value: 100 },
{ value: 150 },
{ value: 200 },
{ value: 250 },
],
y: [
{ value: 20 },
{ value: 30 },
{ value: 30 },
{ value: 20 },
{ value: 0 },
],
duration: 1000,
round: 1,
easing: 'easeInCubic',
});
.container {
position: relative;
}
.container:last-of-type {
top: 60px;
}
.box {
display: flex;
position: relative;
left: 0px;
width: 50px;
height: 50px;
background-color: red;
font-size: 14px;
font-weight: 500;
align-items: center;
flex-direction: column;
justify-content: center;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.2/anime.min.js"></script>
<div class="container">
<div id="simple" class="box">simple</div>
</div>
<div class="container">
<div id="complex" class="box">complex</div>
</div>
Update Dec 2023: There is a workaround how to do that in v3: you can create 2 animations: the first animation with
autoplay: false
andeasing: linear
, and the second one with the easing you want that controls the progress of the first animation. (based on this answer).(jsfiddle)
===========================
Old answer:
After some research I found out that it's probably not possible with Animejs (at least version 3).
At the moment of posting (dec 2023) the related issue is still open and unattended.
Here is examples how to achieve that with some other libs:
P.S. Pay attention that GSAP is not free for commercial usage, and motion.dev is feels a bit abandoned, so I hardly can recommend both.