I have a GSAP animation like this:
window.addEventListener('keydown', ()=>{
GSAP.to(this.box, {
x: this.box.position.x 4,
duration: 1,
}
});
I want to increment the box's x
position by multiples of 4, and my current code above works, but only if the user waits until 1 second has passed before pressing another key. Then it goes 0 -> 4 -> 8
etc.
If they don't wait a second, what happens is something like 0 -> 3.76 -> 6.45
. These numbers change depending on how long a user waits before they press another key. This makes sense because I'm effectively cancelling the animation and using the current position (since 1 second hasn't passed yet, it wouldn't get to 4 yet) and then just rerunning the animation with the current position (that wasn't 4).
Essentially, I want to prevent the 'keydown' event listener from triggered until the 1 second animation has been fully completed.
How would I do that?
CodePudding user response:
This should work:
class Test {
constructor(el) {
this.box = el
window.addEventListener('keydown', () => {
if (!this.tl || !this.tl.isActive()) {
this.tl = gsap.to(this.box, {
x: " =4",
duration: 1,
})
console.log("Moving to:", Math.floor(this.box.getBoundingClientRect().x))
}
});
}
}
const test = new Test(box)
#box {
width: 25px;
height: 25px;
background: blue;
}
<div id="box"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/CSSRulePlugin.min.js"></script>
Probably not the cleanest solution, gsap is a great tool and surely has some better way to handle this scenario, but this is the first brutal approach that came to my mind.
EDIT:
Using isActive()
method is already a tiny bit better.
CodePudding user response:
I never used GSAP, but can you try something like this?
this.box.finalPosition = this.box.position.x
window.addEventListener('keydown', ()=>{
this.box.finalPosition = this.box.finalPosition 4
GSAP.to(this.box, {
x: this.box.finalPosition,
duration: 1,
}
});