I'm trying to place an element arbitrarily on the page, and then animate it through several sequential transitions. The element starts at 0,0 (top left) and then I move it to its starting place (e.g. 100, 100) via an async/await method; then I follow with the transitions. However, unless I use a setTimeout() in the initial placement function, the subsequent transitions occur immediately based on the elements 0,0 position rather than it's arbitrary starting position (100, 100).
There are a number of work arounds. But, I want to know why is the await not working? Note that the await does work if I include a setTimeout.
addTransition = (el, styleProps, durationMs = 0) => {
return new Promise((resolve, reject) => {
function handleTransitionEnd() { resolve(el);}
el.addEventListener("transitionend", handleTransitionEnd, { once: true });
if (durationMs > 0) el.style.setProperty("transition", `${durationMs}ms`);
Object.entries(styleProps).forEach(([prop, value]) => { el.style.setProperty(prop, value); });
});
}
setCSSProperty = (el, prop, val) => {
return new Promise((resolve, reject) => {
document.styleSheets[0].rules[0].style.removeProperty("transition");
el.style.setProperty(prop, val);
//If I remove the following setTimeout, or set the wait to 0, then in the animate function the code continues to run without waiting for this promise to resolve.
setTimeout(() => {
resolve(el);
}, 1); //********** in codepen I can make this as small as 1. On my i86 desktop I have to make this at least 15
});
}
async function animate() {
const actor = document.getElementById("actor");
let x = ((window.innerWidth - actor.getBoundingClientRect().width) * .5);
await this.setCSSProperty(actor, "left", x + "px");
await this.addTransition(actor, { left: "40px", }, 2000);
}
animate()
.actor {
border-radius: 25px;
width: 50px;
height: 50px;
background: #f80;
position: absolute;
top: 0;
left: 0;
transition: 3000ms ease-out;
}
<div class="actor" id="actor"></div>