1

I'm using GSAP's Flip plugin to animate a loading animation that goes from the corner of the screen to the center, and then back when the page is loaded. I thought a good way to do that would be to use async/await to pause the script until a hide_logo_animation bool is toggled.

This is my attempt (Using squares instead), but it does nothing. No errors so I don't know how to debug it.

What am I doing wrong here? I would expect it to flip the position of the two squares and wait for me to toggle hide_logo_animation before switching back.

<div class="container">
  <div class="square" id="sq1">1</div>
  <div class="square" id="sq2">2</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.7.1/gsap.min.js"></script>
<script src="https://assets.codepen.io/16327/Flip.min.js"></script>
body {
  background-color: #222;
  font-family: "Signika Negative", sans-serif, Arial;
}

.container {
  display: -webkit-box;
  display: flex;
  -webkit-box-pack: justify;
  justify-content: space-between;
}

.square {
  width: 100px;
  height: 100px;
  font-size: 3em;
  display: -webkit-box;
  display: flex;
  -webkit-box-pack: center;
          justify-content: center;
  -webkit-box-align: center;
          align-items: center;
  color: black;
  background-color: #88ce02;
  cursor: pointer;
}
gsap.registerPlugin(Flip);

var hide_logo_animation = false
showLogoAnimation(hide_logo_animation)

async function showLogoAnimation(hide_logo_animation) {
    const logo_state = Flip.getState("#sq1", {})
    Flip.from(logo_state, {
        targets: '#sq2',
        duration: 0.75,
        ease: "power1.inOut"
    })
    await hide_logo_animation
    const logo_animation_state = Flip.getState("#sq2", {})
    Flip.from(logo_animation_state, {
        targets: '#sq1',
        duration: 0.75,
        ease: "power1.inOut"
    })
}

Edit: Here is a Codepen/minimal example showing what I'm trying to do. The div word changes to 'Random' immediately, but I want it wait until I toggle the bool is_word_random.

I'm open to other methods as well. I would prefer to use a global event listener to wait for the value to change, but I couldn't find an example of a way to do that. The only way I found to listen for variable changes is get/set which I'm told is outdated, and that async/await should be used instead?

https://codepen.io/TheNomadicAspie/pen/qBmYEeJ

<div id="word">Word</div>
#word {
  font-size: 50px;
}
var is_word_random = false;
makeWordRandom();
waitFiveSeconds();

async function makeWordRandom() {
  await is_word_random;
  word.innerText = "Random";
}

function waitFiveSeconds() {
  setTimeout(() => {
    is_word_random = true;
  }, 5000);
}

1 Answers1

1

In situations like this it helps to make more minimal demos of the core issue. In this case, perhaps this minimal JS code helps you understand the issue:

let myBool = false;
myFunc(myBool);

async function myFunc(bool) {
  console.log(bool);
  await bool;
  console.log("This fires immediately");
}

As you can see, your await is just waiting on a variable that's a boolean type. await works with a promise (including ones made with Promise.all() or returned from a function). So that's your issue.

If you want to use async/await I recommend calling the wait function from the makeWordRandom function and returning a promise from waitFiveSeconds: Demo.


I'm not sure why you're wanting to use an async function here. I would probably call the first part of the function on load then the second part whenever you were planning on toggling the boolean. Like this:

function showLogoAnimation() {
    const logo_state = Flip.getState("#sq1", {});
    Flip.from(logo_state, {
        targets: '#sq2',
        duration: 0.75,
        ease: "power1.inOut"
    });
}

function hideLogoAnimation() {
  const logo_animation_state = Flip.getState("#sq2", {});
  Flip.from(logo_animation_state, {
      targets: '#sq1',
      duration: 0.75,
      ease: "power1.inOut"
  });
}

showLogoAnimation();

// Whenever you were changing the boolean, just call hideLogoAnimation() instead
Zach Saucier
  • 24,871
  • 12
  • 85
  • 147
  • Thanks but I was debugging line by line and still couldn't figure out why it's happening. Though I've spent days learning about async/await and promises, read literally everything I can find on it, and it's the one concept I've never been able to really understand. I'm reading about them again now to try to understand, and I don't see how it's NOT the right way to do it. I see several people online suggesting async/await to use to wait for variable changes. Thank you though. –  Jul 29 '21 at 17:50
  • @TheNomadicAspie Can you please make a [minimal, complete, and verifiable example](https://stackoverflow.com/help/minimal-reproducible-example)? You don't even need to include GSAP/the Flip plugin at all – Zach Saucier Jul 29 '21 at 20:03
  • Sure I edited my original post to show. I'm open to using other methods, and I would prefer to use a global event listener as in my actual code I have a state_dict object that contains several bools. Ideally I would like to call a function when state_dict changes and to use that to control my animations, but again I can't find a way to do that in Javscript so tried async/await since it's often suggested. Most of the posts about listening for variable changes are outdated, and recent comments warn not to use those methods but don't provide a clear example of how it should be done now. –  Jul 29 '21 at 21:46
  • @TheNomadicAspie Thanks for trying, but your minimal example never changes the state of the boolean. Can you please include that as a part of your recreation as well? – Zach Saucier Jul 29 '21 at 22:37
  • Sorry about that, I updated the example with a setTimeout to wait five seconds before toggling the bool. –  Jul 29 '21 at 23:33
  • Thank you @ZachSaucier I understand now. I appreciate the help. –  Jul 31 '21 at 17:40