1

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.

arxpoetica
  • 4,841
  • 3
  • 30
  • 35

2 Answers2

3

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.

Kosh
  • 16,966
  • 2
  • 19
  • 34
  • Currently only implemented at Mozilla browsers. – guest271314 Feb 09 '19 at 02:21
  • @guest271314, thanks for your note! I've updated my answer. – Kosh Feb 09 '19 at 02:43
  • @KoshVery thanks for the answer. I wish there was a way other than getComputedProperty, since it comes through as `matrix` and `rgb`, which I'd have to convert if I want it back in named color format and `rotate` and `scale`, but this still answers the question. Bonus points for anyone who can figure out how to get at that `rotate` and `scale` easier... – arxpoetica Feb 09 '19 at 18:39
  • @ArxPoetica, `matrix` is [convertible](https://stackoverflow.com/questions/13454420/css3-transform-matrix-to-full-transform-conversion). – Kosh Feb 09 '19 at 18:57
  • @KoshVery I'm also excited about CSS Typed OM (part of Houdini) https://developers.google.com/web/updates/2018/03/cssom but it's not nearly ready. – arxpoetica Feb 10 '19 at 04:31
  • @ArxPoetica, looks promising. – Kosh Feb 10 '19 at 04:56
0

You can use requestAnimationFrame to achieve the expected result, see How to detect changes made by CSS3 animation or web animations API?

guest271314
  • 1
  • 15
  • 104
  • 177
  • One of the reasons I'm not using rAF is because of potential future performance gains with the web animations API. But you're right, it can be used as an alternative approach. – arxpoetica Feb 09 '19 at 18:41
  • @ArxPoetica Not sure what you mean by _"I'm not using rAF is because of potential future performance gains with the web animations API"_ – guest271314 Feb 09 '19 at 18:43
  • As outlined in this article (http://danielcwilson.com/blog/2015/07/animations-intro/) requestAnimationFrame ties performance to the event loop and browser / screen performance rate, which might actually be less perf than available by any given machine. Web Animations API breaks free of these constraints. The polyfill https://github.com/web-animations/web-animations-js however uses rAF as a fallback as far as I understand. – arxpoetica Feb 09 '19 at 19:17