зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1505200 - Part 1: Rewrite the interpolation of Rotate to return correct type. r=birtles
The original implementation always returns Rotate::Rotate3D, but it is not correct, so we have to rewrite it: 1. If both from value and to value are none, we don't have to convert it into identity value, so just return None. 2. If one of the value is none, we replace it with an identity value based on the other one's rotate axis. 3. If we only have 2D rotation, we just animate the <angle>. 4. Otherwise, we do interpolation by 3D rotation. Differential Revision: https://phabricator.services.mozilla.com/D11247 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
97ccc8c012
Коммит
5f3b39da88
|
@ -2108,7 +2108,7 @@ impl ComputedRotate {
|
|||
//
|
||||
// If the axis is unspecified, it defaults to "0 0 1"
|
||||
match *self {
|
||||
Rotate::None => (0., 0., 1., Angle::zero()),
|
||||
Rotate::None => unreachable!("None is handled by the caller"),
|
||||
Rotate::Rotate3D(rx, ry, rz, angle) => (rx, ry, rz, angle),
|
||||
Rotate::Rotate(angle) => (0., 0., 1., angle),
|
||||
}
|
||||
|
@ -2122,41 +2122,58 @@ impl Animate for ComputedRotate {
|
|||
other: &Self,
|
||||
procedure: Procedure,
|
||||
) -> Result<Self, ()> {
|
||||
let (from, to) = (self.resolve(), other.resolve());
|
||||
match (self, other) {
|
||||
(&Rotate::None, &Rotate::None) => Ok(Rotate::None),
|
||||
(&Rotate::Rotate3D(fx, fy, fz, fa), &Rotate::None) => {
|
||||
// No need to normalize `none`, so animate angle directly.
|
||||
Ok(Rotate::Rotate3D(fx, fy, fz, fa.animate(&Angle::zero(), procedure)?))
|
||||
},
|
||||
(&Rotate::None, &Rotate::Rotate3D(tx, ty, tz, ta)) => {
|
||||
// No need to normalize `none`, so animate angle directly.
|
||||
Ok(Rotate::Rotate3D(tx, ty, tz, Angle::zero().animate(&ta, procedure)?))
|
||||
},
|
||||
(&Rotate::Rotate3D(_, ..), _) | (_, &Rotate::Rotate3D(_, ..)) => {
|
||||
let (from, to) = (self.resolve(), other.resolve());
|
||||
let (mut fx, mut fy, mut fz, fa) =
|
||||
transform::get_normalized_vector_and_angle(from.0, from.1, from.2, from.3);
|
||||
let (mut tx, mut ty, mut tz, ta) =
|
||||
transform::get_normalized_vector_and_angle(to.0, to.1, to.2, to.3);
|
||||
|
||||
let (mut fx, mut fy, mut fz, fa) =
|
||||
transform::get_normalized_vector_and_angle(from.0, from.1, from.2, from.3);
|
||||
let (mut tx, mut ty, mut tz, ta) =
|
||||
transform::get_normalized_vector_and_angle(to.0, to.1, to.2, to.3);
|
||||
if fa == Angle::from_degrees(0.) {
|
||||
fx = tx;
|
||||
fy = ty;
|
||||
fz = tz;
|
||||
} else if ta == Angle::from_degrees(0.) {
|
||||
tx = fx;
|
||||
ty = fy;
|
||||
tz = fz;
|
||||
}
|
||||
|
||||
if fa == Angle::from_degrees(0.) {
|
||||
fx = tx;
|
||||
fy = ty;
|
||||
fz = tz;
|
||||
} else if ta == Angle::from_degrees(0.) {
|
||||
tx = fx;
|
||||
ty = fy;
|
||||
tz = fz;
|
||||
if (fx, fy, fz) == (tx, ty, tz) {
|
||||
return Ok(Rotate::Rotate3D(fx, fy, fz, fa.animate(&ta, procedure)?));
|
||||
}
|
||||
|
||||
let fv = DirectionVector::new(fx, fy, fz);
|
||||
let tv = DirectionVector::new(tx, ty, tz);
|
||||
let fq = Quaternion::from_direction_and_angle(&fv, fa.radians64());
|
||||
let tq = Quaternion::from_direction_and_angle(&tv, ta.radians64());
|
||||
|
||||
let rq = Quaternion::animate(&fq, &tq, procedure)?;
|
||||
let (x, y, z, angle) = transform::get_normalized_vector_and_angle(
|
||||
rq.0 as f32,
|
||||
rq.1 as f32,
|
||||
rq.2 as f32,
|
||||
rq.3.acos() as f32 * 2.0,
|
||||
);
|
||||
|
||||
Ok(Rotate::Rotate3D(x, y, z, Angle::from_radians(angle)))
|
||||
},
|
||||
(&Rotate::Rotate(_), _) | (_, &Rotate::Rotate(_)) => {
|
||||
// If this is a 2D rotation, we just animate the <angle>
|
||||
let (from, to) = (self.resolve().3, other.resolve().3);
|
||||
Ok(Rotate::Rotate(from.animate(&to, procedure)?))
|
||||
},
|
||||
}
|
||||
|
||||
if (fx, fy, fz) == (tx, ty, tz) {
|
||||
return Ok(Rotate::Rotate3D(fx, fy, fz, fa.animate(&ta, procedure)?));
|
||||
}
|
||||
|
||||
let fv = DirectionVector::new(fx, fy, fz);
|
||||
let tv = DirectionVector::new(tx, ty, tz);
|
||||
let fq = Quaternion::from_direction_and_angle(&fv, fa.radians64());
|
||||
let tq = Quaternion::from_direction_and_angle(&tv, ta.radians64());
|
||||
|
||||
let rq = Quaternion::animate(&fq, &tq, procedure)?;
|
||||
let (x, y, z, angle) = transform::get_normalized_vector_and_angle(
|
||||
rq.0 as f32,
|
||||
rq.1 as f32,
|
||||
rq.2 as f32,
|
||||
rq.3.acos() as f32 * 2.0,
|
||||
);
|
||||
|
||||
Ok(Rotate::Rotate3D(x, y, z, Angle::from_radians(angle)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +1,8 @@
|
|||
[rotate-interpolation.html]
|
||||
[Animation between "45deg" and "-1 1 0 60deg" at progress 1]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "7 -8 9 400grad" at progress -1]
|
||||
expected: FAIL
|
||||
bug: https://github.com/w3c/csswg-drafts/issues/3290
|
||||
|
||||
[Animation between "none" and "7 -8 9 400grad" at progress 0]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "7 -8 9 400grad" at progress 0.125]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "7 -8 9 400grad" at progress 0.875]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "7 -8 9 400grad" at progress 1]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "7 -8 9 400grad" at progress 2]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "none" at progress -1]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "none" at progress 0]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "none" at progress 0.125]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "none" at progress 0.875]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "none" at progress 1]
|
||||
expected: FAIL
|
||||
|
||||
[Animation between "none" and "none" at progress 2]
|
||||
expected: FAIL
|
||||
|
||||
bug: https://github.com/w3c/csswg-drafts/issues/3290
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
[scale-interpolation.html]
|
||||
[Animation between "26 17 9" and "2" at progress 1]
|
||||
expected: FAIL
|
||||
bug: https://github.com/w3c/csswg-drafts/issues/3290
|
||||
|
||||
[Animation between "none" and "4 3 2" at progress 0]
|
||||
expected: FAIL
|
||||
bug: https://github.com/w3c/csswg-drafts/issues/3290
|
||||
|
||||
[Animation between "26 17 9" and "2 1" at progress 1]
|
||||
expected: FAIL
|
||||
bug: https://github.com/w3c/csswg-drafts/issues/3290
|
||||
|
|
Загрузка…
Ссылка в новой задаче