I need to execute an animation on a div for properties scaleZ()
and translateZ()
using CSS Animations.
The following code works fine when initial and last keyframes values in the animation for transform
property are in a similar "format":
transform: rotateY(-179deg) scaleZ(2) translateZ(200px);
transform: rotateY(179deg) scaleZ(2) translateZ(200px);
console.clear();
document.addEventListener('DOMContentLoaded', () => {
let content1 = document.querySelector('#content1');
var computedTransform = window.getComputedStyle(content1).transform;
console.log(computedTransform);
});
@-webkit-keyframes animation {
0% {
/*works*/
-webkit-transform: rotateY(-179deg) scaleZ(2) translateZ(200px);
transform: rotateY(-179deg) scaleZ(2) translateZ(200px);
/*issue*/
/*transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);*/
}
100% {
-webkit-transform: rotateY(179deg) scaleZ(2) translateZ(200px);
transform: rotateY(179deg) scaleZ(2) translateZ(200px);
}
}
@keyframes animation {
0% {
/*works*/
-webkit-transform: rotateY(-179deg) scaleZ(2) translateZ(200px);
transform: rotateY(-179deg) scaleZ(2) translateZ(200px);
/*issue*/
/*transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);*/
}
100% {
-webkit-transform: rotateY(179deg) scaleZ(2) translateZ(200px);
transform: rotateY(179deg) scaleZ(2) translateZ(200px);
}
}
#content1 {
-webkit-animation: animation 2s;
animation: animation 2s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
/*works*/
-webkit-transform: rotateY(-179deg) scaleZ(2) translateZ(200px);
transform: rotateY(-179deg) scaleZ(2) translateZ(200px);
/*issue*/
/*transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);*/
}
<div id="wrapper1" style="position:fixed; top: 100px; left:300px; perspective: 1000px; width: 250px; height:250px; border: dotted 1px blue">
<div id="content1" style="width: 250px; height:250px; background-color:lightsalmon; opacity:0.2;">
</div>
</div>
The same animation with transform
for key-frame 0% written as matrix3D
returned from Window.getComputedStyle()
does not make the animation work properly:
transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
transform: rotateY(179deg) scaleZ(2) translateZ(200px);
console.clear();
document.addEventListener('DOMContentLoaded', () => {
let content1 = document.querySelector('#content1');
var computedTransform = window.getComputedStyle(content1).transform;
console.log(computedTransform);
});
@-webkit-keyframes animation {
0% {
/*works*/
/*transform: rotateY(-179deg) scaleZ(2) translateZ(200px);*/
/*issue*/
-webkit-transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
}
100% {
-webkit-transform: rotateY(179deg) scaleZ(2) translateZ(200px);
transform: rotateY(179deg) scaleZ(2) translateZ(200px);
}
}
@keyframes animation {
0% {
/*works*/
/*transform: rotateY(-179deg) scaleZ(2) translateZ(200px);*/
/*issue*/
-webkit-transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
}
100% {
-webkit-transform: rotateY(179deg) scaleZ(2) translateZ(200px);
transform: rotateY(179deg) scaleZ(2) translateZ(200px);
}
}
#content1 {
-webkit-animation: animation 2s;
animation: animation 2s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
/*works*/
/*transform: rotateY(-179deg) scaleZ(2) translateZ(200px);*/
/*issue*/
-webkit-transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
}
<div id="wrapper1" style="position:fixed; top: 100px; left:300px; perspective: 1000px; width: 250px; height:250px; border: dotted 1px blue">
<div id="content1" style="width: 250px; height:250px; background-color:lightsalmon; opacity:0.2;">
</div>
</div>
For technical reasons I need to use as key-frame 0% a value for transformation
properly returned from a computed style in the DOM, using Window.getComputedStyle()
or another function if available.
My questions:
Window.getComputedStyle()
?transform
?Notes: I see this issue on latest Chrome (55.0.2883.87 m) and FireFox (50.1.0).
Any solutions or ideas is welcome.
EDIT:
I have created few new examples (for Chrome) for further investigation.
Basically the two example rotate
from rotateY(20deg)
to rotateY(90deg)
Using transform with one type of "notation", works as expected
Desired effect https://jsbin.com/bodaxefake/edit?html,output
When the values are instead taken by a computed CSS style and reapplied to the animation using matrix3d, the animation has a slight distortion.
Instead I would expect to reproduce the animation which exactly the same result, as for my understanding the matrix3d from Window.getComputedStyle()
should return the same value.
Incorrect effect https://jsbin.com/luhikahexi/edit?html,output
Each keyframe describes how the animated element should render at a given time during the animation sequence. Since the timing of the animation is defined in the CSS style that configures the animation, keyframes use a <percentage> to indicate the time during the animation sequence at which they take place.
The animation-fill-mode property specifies a style for the element when the animation is not playing (before it starts, after it ends, or both).
To use keyframes, create a @keyframes rule with a name that is then used by the animation-name property to match an animation to its keyframe declaration.
Your problem is point number 4. But it isn't really a bug, it 's a complex algorithm trying to figure out what do you want to do.
When you make an animation move from rotate(0deg) to rotate(360deg), have you ever wondered that the 2 matrices are just the same ? If only the initial an final states are specified, the animation would not exist.
When you set the animation the way you did, the algorithm is clueless about what to do, and so the behaviour is not what you expect. But I wouldn't say this is a bug.
I have set an animation that does what you want. The trick is to leave the matrix constant, add an initial rotation that is what we will change, and just add another rotation opposite to this one to keep the original state.
Since this snippet is a little bit extense, I have removed webkit prefixes. (on the other hand, nor really needed nowadays)
console.clear();
document.addEventListener('DOMContentLoaded', () => {
let content1 = document.querySelector('#content1');
var computedTransform = window.getComputedStyle(content1).transform;
console.log(computedTransform);
});
@keyframes animation {
0% {
transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
}
0.1% {
transform: rotateY(-179deg) rotateY(179deg) matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
}
100% {
transform: rotateY(179deg) rotateY(179deg) matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
}
}
#content1 {
animation: animation 2s;
animation-fill-mode: forwards;
transform: matrix3d(-0.999848, 0, 0.0174524, 0, 0, 1, 0, 0, -0.0349048, 0, -1.9997, 0, -6.98096, 0, -399.939, 1);
}
<div id="wrapper1" style="position:fixed; top: 100px; left:300px; perspective: 1000px; width: 250px; height:250px; border: dotted 1px blue">
<div id="content1" style="width: 250px; height:250px; background-color:lightsalmon; opacity:0.2;">
</div>
</div>
The real problem is that there is not enough information in the beginning and end point of an animation to reconstruct it. The matrices of the transforms don't have the information that you are giving in a series of individual transforms
See the snippet (in 2D): the begin and end states are the same, the animation isn't. In 3D, there are even more posibilities
.test {
width: 50px;
height: 50px;
position: absolute;
top: 400px;
left: 100px;
}
#one {
background-color: lightgreen;
transform: translateX(200px);
animation: tr1 6s infinite;
}
@keyframes tr1 {
0% {
transform: rotate(0deg) translateX(200px)
}
33%,
100% {
transform: rotate(-90deg) translateX(200px)
}
}
#two {
background-color: lightblue;
transform: translate(200px, 0px);
animation: tr2 6s infinite;
}
@keyframes tr2 {
0%, 33% {
transform: translate(200px, 0px) rotate(0deg)
}
66%,
100% {
transform: translate(0px, -200px) rotate(-90deg)
}
}
#three {
background-color: tomato;
transform: translate(200px, -200px) rotate(0deg) translateY(200px);
animation: tr3 6s infinite;
}
@keyframes tr3 {
0%, 66% {
transform: translate(200px, -200px) rotate(0deg) translateY(200px) rotate(0deg);
}
100% {
transform: translate(200px, -200px) rotate(-270deg) translateY(200px) rotate(180deg);
}
}
<div class="test" id="one">1</div>
<div class="test" id="two">2</div>
<div class="test" id="three">3</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With