Closed Bug 1500820 Opened 2 years ago Closed 2 years ago

Interpolation of rotate(0deg) and rotateX(360deg) fails


(Core :: CSS Transitions and Animations, defect, P3)

64 Branch



Tracking Status
firefox64 --- wontfix
firefox65 --- fixed


(Reporter: karlcow, Assigned: birtles)




(Whiteboard: [webcompat] [css][wptsync upstream])


(1 file)

This is a spin-off of

1. Go to
2. Hover the hat.

at the top the hat disappears

The hat rotates when at the top like it does in Chrome.

CSS is defined with 

.fox:hover .hat {
  animation-name: tip;                /* animation name */
  animation-duration: 2s;             /* how long it lasts */
  animation-delay: 0s;                /* dely before starting */
  animation-iteration-count: 3;       /* how many times to play it */
  animation-timing-function: linear;  /* easing style */
  animation-fill-mode: backwards;     /* apply beginning or end styles when it's over */
  animation-direction: normal;        /* direction it plays in */

.hat {
  transform-origin: center;     /* trasformations are applied from these cooridnates on the hat */

These are the keyframes in the hat tip animation.
Each keyframe includes a percentage and any number of css rules.

@keyframes tip {
  0% {
    /* You can add more rules to each keyframe */
  25% {
    transform: translateY(-100px) rotate(0deg);
  50% {
    transform: translateY(-100px) rotateX(360deg);
  100% {
    transform: translateY(0px) rotate(360deg);

/* You can
I was concerned that I broke this last week but I can see Firefox 63 has the same problem.

Looks like while we're interpolating between 'translateY(-100px) rotate(0deg)' and 'translateY(-100px) rotateX(360deg)' we end up with a computed style of:

  "matrix3d(NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 0, -100, 0, 1)"

I'll look into this later today.
Assignee: nobody → bbirtles
Reproduced with Firefox 62 as well (and the original report was from Firefox 62 too) so if this is a regression, it's not a recent one.
From bug 1499862 comment #13:
> 3. When interpolation quaternions the spec has:
>     if (product == 1.0)
>       quaternionDst = quaternionA
>       return
>    But this fails to account for when product is -1 (which will cause divide
>    by zero). It should probably use abs().
>    Servo also fails to account for this.

Wow, this bug I identified last Friday is precisely this bug -- that is, it's the cause of the NaN values, but not the cause of the failure to flip.
Looks like we fail to interpolate between Quaternion(0.0, 0.0, 0.0, 1.0) and Quaternion(0.00000000000000012246467991473532, 0.0, 0.0, -1.0).

We could either do something a little smarter than just call to_rotate_3d (and actually turn `rotate(0deg)` here into `rotateX(0deg)`) or I could actually try to understand quaternions properly. I guess I should do that latter.
Chromium will treat these two values as having a common axis since the angle of the first is zero:

So, basically, it does the "do something a little smarter" approach.
Strictly speaking, the spec doesn't allow this[1] but it seems like the most useful behavior for the author so I think we should follow suit and file a spec issue for this.

I notice Edge and Safari fail to interpolate this.
Summary: CSS animation rotation of a PNG image is not visible. → Interpolation of rotate(0deg) and rotateX(360deg) fails
I will likely split this into two bugs:

1) (This bug) A simple patch to just handle the dotproduct == -1.0 case (match Edge and Safari, can be uplifted to beta)
2) A separate bug to do the smarter handling of zero rotation angles (needs spec change, no hurry to uplift)
Blocks: 1501176
See the extended commit message for the following spec change:

Basically, by failing to take the absolute value, for certain content we can end
up doing division by zero which will mean that the test included in this patch
will cause an assertion to fail in debug builds and return
"matrix(NaN, NaN....)" in release builds.
Pushed by
Compare absolute dot-product to 1.0 when interpolating quaternions; r=hiro
Created web-platform-tests PR for changes under testing/web-platform/tests
Whiteboard: [webcompat] [css] → [webcompat] [css][wptsync upstream]
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla65
Flags: in-testsuite+
You need to log in before you can comment on or make changes to this bug.