javascriptweb-animationsweb-animations-api

Read style information from JavaScript Web Animations API, mid state


Given a web animation, such as the one over here: https://codepen.io/arxpoetica/pen/aXqEwe

How do I get CSS or style information based on state between keyframes at any given point and time?

Sample code:

<div class="thing"></div>

<style>
html {
  height: 100%;
}
body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  background-color: #0a2933;
}
.thing {
  height: 100px;
  width: 100px;
  background-color: orange;
}
</style>

<script>
document.querySelector('.thing').animate([
    { transform: 'rotate(0) scale(1)', backgroundColor: 'orange' },
    { transform: 'rotate(180deg) scale(3)', backgroundColor: 'blue' },
    { transform: 'rotate(360deg) scale(1)', backgroundColor: 'orange' }
], {
    duration: 3000,
    iterations: Infinity
})
</script>

NOTE: this API only works in limited browsers / platforms.


Solution

  • WAAPI method .animate returns Animation object which includes all you need:

    Run the snippet below:

    var keyframes = [{
        transform: 'rotate(0) scale(1)',
        backgroundColor: 'orange'
      },
      {
        transform: 'rotate(180deg) scale(3)',
        backgroundColor: 'blue'
      },
      {
        transform: 'rotate(360deg) scale(1)',
        backgroundColor: 'orange'
      }
    ];
    
    var options = {
      duration: 3000,
      iterations: Infinity
    };
    
    var thing = document.querySelector('.thing');
    
    var A = thing.animate(keyframes, options);
    
    console.clear();
    
    
    function getState() {
      if (A.playState === 'running') {
        document.querySelector('section').innerHTML += `<p>
          progress: ${getProgress()*100|0}% <br>
          transform: ${getComputedStyle(thing).transform} <br>
          backgroundColor: ${getComputedStyle(thing).backgroundColor}
        </p>`;
        //A.startTime = 0;
        A.pause();
      } else {
        A.play();
        document.querySelector('section p:last-of-type').remove();
      }
    }
    
    function getProgress() {
      return A.effect ?
        A.effect.getComputedTiming().progress :
        A.currentTime % options.duration / options.duration
    }
    html {
      height: 100%;
    }
    
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100%;
      background-color: #0a2933;
    }
    
    section {
      position: absolute;
      z-index: 1;
      top: 0;
      left: 1em;
      color: silver
    }
    
    .thing {
      height: 100px;
      width: 100px;
      background-color: orange;
    }
    <!-- polyfill -->
    <script src="https://rawgit.com/web-animations/web-animations-js/master/web-animations.min.js"></script>
    
    <section>
      <p>How do I get CSS or style information based on state between keyframes at any given point and time?</p>
      <button onclick="getState()">Click here</button>
    </section>
    
    <div class="thing"></div>

    Also, WAAPI has a nice polyfill.

    Hope it helps.