Commit a4f9eea8 authored by Emilio Cobos Álvarez's avatar Emilio Cobos Álvarez
Browse files

Bug 1488414 - Use decomposition to interpolate matched perspective transform operations. r=birtles

Looks like this produces sensible results for interpolation with 0, though I'm
not really convinced about the results from, let's say, 1px to 2000px in the
attached test-case, I would've expected a linear interpolation from that to go
through normal length interpolation.

css-transforms-1 says:

  > Two transform functions with the same name and the same number of arguments
  > are interpolated numerically without a former conversion. The calculated
  > value will be of the same transform function type with the same number of
  > arguments.
  >
  > Special rules apply to <matrix()>.

Which is what we do... I was going to file a spec issue but turns out that it's
already addressed in css-transforms-2:

  https://drafts.csswg.org/css-transforms-2/#interpolation-of-transform-functions

Which says:

  > The transform functions <matrix()>, matrix3d() and perspective() get
  > converted into 4x4 matrices first and interpolated as defined in section
  > Interpolation of Matrices afterwards.

Differential Revision: https://phabricator.services.mozilla.com/D4942

--HG--
extra : moz-landing-system : lando
parent bce574c7
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -1296,9 +1296,27 @@ impl Animate for ComputedTransformOperation {
                &TransformOperation::Perspective(ref fd),
                &TransformOperation::Perspective(ref td),
            ) => {
                Ok(TransformOperation::Perspective(
                    fd.animate(td, procedure)?
                ))
                use values::computed::CSSPixelLength;
                use values::generics::transform::create_perspective_matrix;

                // From https://drafts.csswg.org/css-transforms-2/#interpolation-of-transform-functions:
                //
                //    The transform functions matrix(), matrix3d() and
                //    perspective() get converted into 4x4 matrices first and
                //    interpolated as defined in section Interpolation of
                //    Matrices afterwards.
                //
                let from = create_perspective_matrix(fd.px());
                let to = create_perspective_matrix(td.px());

                let interpolated =
                    Matrix3D::from(from).animate(&Matrix3D::from(to), procedure)?;

                let decomposed = decompose_3d_matrix(interpolated)?;
                let perspective_z = decomposed.perspective.2;
                let used_value =
                    if perspective_z == 0. { 0. } else { -1. / perspective_z };
                Ok(TransformOperation::Perspective(CSSPixelLength::new(used_value)))
            },
            _ if self.is_translate() && other.is_translate() => {
                self.to_translate_3d().animate(&other.to_translate_3d(), procedure)
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ impl TransformOrigin {

/// computed value of matrix3d()
pub type Matrix3D = generic::Matrix3D<Number>;

/// computed value of matrix()
pub type Matrix = generic::Matrix<Number>;