Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript and css animation keep getting out of sync

So basically my CSS animation is supposed to emulate some text being typed, un-typed and finally changed to another word. Normally the CSS keyframe and JavaScript setInterval are in sync but on mobile devices they sometimes get out of sync or if I go to a new tab they de-synchronize.

<center style="display: flex; width:70vw">
     <h1 style="padding-right:20px;">We</h1>
     <h1 id="terminal-text">innovate.</h1>
</center>
<script type="text/javascript">
    var i = 0;
    words = ['architect.','build.','design.','code.','develop.','innovate.'];
    setInterval(function() {
      $("#terminal-text").text(words[i]);
      i++;
      if (i > words.length) {
        i=0;
      }
    },3000);
</script>
#header .banner h1 {
  margin: 1em 0 .5em -10%;
  padding: 0;
  color: white;
  text-align: left;
}
@keyframes terminal {
  0% {max-width:0}
  50% {max-width:100%}
  55% {max-width:100%}
  100% {max-width:0}
}
#header #terminal-text {
  font-weight: bold;
  margin: 1em 0 .5em 0;
  padding: 0;
  animation: terminal 3s infinite;
  overflow: hidden;
  white-space: nowrap;
  border-right: 4px solid white;
  text-align: left;
}

1 Answers

instead of having a setInterval() in javascript you could listen for animation end event. The problem with your approach is that you can not start both "timers" (css/js) at the same time (you could with another approach) but this could solve your issue

var wordIndex = 0;
words = ['architect.','build.','design.','code.','develop.','innovate.'];

var changeWord = function() {
  $("#terminal-text").text(words[wordIndex++]);
};

var element = document.querySelector("#terminal-text");
element.addEventListener("animationiteration", changeWord, false);

// you could also do something special on start event
// replace changeWord with whatever functionality you need
// element.addEventListener("animationstart", changeWord, false);

// animationend will never be triggered in your code at the moment
// but maybe you want to do something with it somewhen
// element.addEventListener("animationend", function() {console.log('animation ended')}, false);
#header .banner h1 {
  margin: 1em 0 .5em -10%;
  padding: 0;
  color: white;
  text-align: left;
}
@keyframes terminal {
  0% {max-width:0}
  50% {max-width:100%}
  55% {max-width:100%}
  100% {max-width:0}
}
#header #terminal-text {
  font-weight: bold;
  margin: 1em 0 .5em 0;
  padding: 0;
  animation: terminal 3s infinite;
  overflow: hidden;
  white-space: nowrap;
  border-right: 4px solid white;
  text-align: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
  <center style="display: flex; width:70vw">
    <h1 style="padding-right:20px;">We</h1>
    <h1 id="terminal-text">innovate.</h1>
  </center>
</div>
like image 172
caramba Avatar answered May 15 '26 18:05

caramba



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!