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
This commit is contained in:
Emilio Cobos Álvarez 2018-09-05 13:35:06 +00:00
parent bce574c7a1
commit a4f9eea8e5
2 changed files with 22 additions and 3 deletions

View File

@ -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)

View File

@ -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>;