Search code examples
javascriptcssanimationweb-animations

Simulating additive animations using Web Animations API issue with getComputedStyle(element).transform


I need to "simulate" additive animations using Web Animations API.

As described in the documentation additive animations are not supported yet and the use of getComputedStyle(element) is suggested.

The problem I am facing is that the matrix3d returned by getComputedStyle(element).transform probably does not contain enough information on perspective, so if I am using as start keyframe, animations are not the same (issue with Red box).

In this example, the blue box has the desired animation, red box animation is not correct:

I would like to know: - If a solution to this problem exists - If the implementation of additive animations would support transform with perspective.

Thanks for your time.

var elem = document.getElementById('target');
var style = window.getComputedStyle(elem);

elem.animate([{
  transform: style.transform // using matrix3d returned from getComputedStyle()
}, {
  transform: 'rotateY(179deg) scaleZ(2) translateZ(200px)'
}], {
  duration: 3000
});

var elem2 = document.getElementById('target2');
elem2.animate([{
  transform: 'rotateY(-179deg) scaleZ(2) translateZ(200px)'
}, {
  transform: 'rotateY(179deg) scaleZ(2) translateZ(200px)'
}], {
  duration: 3000
});
#wrapper,
#wrapper2 {
  perspective: 1000px;
}

#target,
#target2 {
  position: absolute;
  top: 100px;
  width: 200px;
  height: 300px;
}

#target {
  left: 100px;
  background-color: red;
  transform: rotateY(-179deg) scaleZ(2) translateZ(200px);
}

#target2 {
  left: 400px;
  background-color: blue;
  transform: rotateY(-179deg) scaleZ(2) translateZ(200px);
}
<div id="wrapper">
  <div id="target">wrong animation</div>
</div>

<div id="wrapper2">
  <div id="target2">correct animation</div>
</div>


Solution

  • You have some different problems in the snippet.

    The main one is that the target elements are positioned different respect to the parent. (One has a left value higher than the other). Since the perspective value is in the wrapper, the perspective origin is also, and so it's very difficult to make them match.

    I have redone the snippet that show that there is not a real issue with the perspective, when this problems are solved.

    But there is still the problem with the missing information, as discussed in a previous question, that as I said is unsolvable.

    var elem2 = document.getElementById('target2');
    var style = window.getComputedStyle(elem2);
    
    
    var elem = document.getElementById('target');
    elem.style.transform = style;
    #wrapper,
    #wrapper2 {
      width: 200px;
      height: 300px;
      border: solid 1px blue;
      top: 100px;
      position: absolute;
    }
    #wrapper {
      left: 400px;
    }
    #wrapper2 {
      perspective: 1000px;
      left: 600px;
    }
    #target,
    #target2 {
      width: 200px;
      height: 300px;
      position: absolute;
    }
    #target {
      background-color: red;
      transform: perspective(1000px) rotateY(-45deg) scaleZ(2) translateZ(200px);
    }
    #target2 {
      background-color: blue;
      transform: rotateY(-45deg) scaleZ(2) translateZ(200px);
    }
    <div id="wrapper">
      <div id="target">wrong animation</div>
    </div>
    
    <div id="wrapper2">
      <div id="target2">correct animation</div>
    </div>