Jake
Jake

Reputation: 119

How to time mutliple CSS events simultaneously?

If anyone can get this simple example to work, I'd be super thankful!

var string = "cat";
var transitions = {0.3 , 0.2 , 0.6};
var timings = {0, 1.0, 1.5};

When I click a button, the clock starts at time = 0.

After all this, "cat" is displayed normally, as if it were typed straight into HTML.

Upvotes: 0

Views: 67

Answers (2)

Intervalia
Intervalia

Reputation: 10945

I probably wouldn't use this without some additional cleanup, but this code works.

It was fun to write. And should meet your requirements.

var transitions = [0.3 , 0.2 , 0.6];
var timings = [0, 1.0, 1.5];


function typeWrite(el, string) {
  return new Promise(
    function(resolve) {
      var i = 0;
      var l = string.length;
      
      function typeOne() {
        var chr = string[i];
        var span = document.createElement('span');
        span.innerHTML = chr;
        span.setAttribute('style', `transition: ${transitions[i]}s; opacity: 0;`); 
        el.appendChild(span);
        setTimeout(function() {span.className = 'typewriter-effect';},0);
        i++;
        if( i < l) {
          setTimeout(typeOne, timings[i]*1000);
        }
        else {
          resolve();
        }
      }
      
      typeOne();
    }
  )
}
      
typeWrite(document.querySelector('.typed-string'), 'cat').then(
  function() {
    console.log('Finished typing');
  }
);
.typewriter-effect {
  opacity: 1 !important;
}
<div class="typed-string"></div>

I normally hate using !important but this was a quick and simple way to allow the CSS class to override the opacity of the style attribute.

What I am doing is walking through the string and the two arrays you provided, then I am creating a new <span> for each letter and adding them into the DOM. Each new <span> indicates how long they take to fade in from opacity:0 to opacity:1.

Then I call setTimeout to wait for the desired time before writing the next letter. This pattern continues until all letters have finished rendering. Then the routine resolves the promise so the calling code knows when the writing routine is finished.

Upvotes: 1

efong5
efong5

Reputation: 526

You want to use steps in your css animation, along with keyframes (From this tutorial)

.typewriter-effect {
    animation: 
        typing 3.5s steps(40, end)
}

/* The typing effect */
@keyframes typing {
   from { width: 0 }
   to { width: 100% }
}

the way this works is your keyframes specify the effect, and the steps function determines how many parts it breaks down into.

Upvotes: 0

Related Questions