mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Implement Animate trait for individual transforms
This commit is contained in:
parent
9a62c0bf02
commit
8a4661b829
5 changed files with 130 additions and 40 deletions
|
@ -46,7 +46,10 @@ use values::computed::ToComputedValue;
|
|||
use values::computed::transform::{DirectionVector, Matrix, Matrix3D};
|
||||
use values::computed::transform::TransformOperation as ComputedTransformOperation;
|
||||
use values::computed::transform::Transform as ComputedTransform;
|
||||
use values::generics::transform::{self, Transform, TransformOperation};
|
||||
use values::computed::transform::Rotate as ComputedRotate;
|
||||
use values::computed::transform::Translate as ComputedTranslate;
|
||||
use values::computed::transform::Scale as ComputedScale;
|
||||
use values::generics::transform::{self, Rotate, Translate, Scale, Transform, TransformOperation};
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
#[cfg(feature = "gecko")] use values::generics::FontSettings as GenericFontSettings;
|
||||
#[cfg(feature = "gecko")] use values::generics::FontSettingTag as GenericFontSettingTag;
|
||||
|
@ -2269,6 +2272,129 @@ impl Matrix3D {
|
|||
}
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-transforms-2/#propdef-rotate>
|
||||
impl ComputedRotate {
|
||||
fn fill_unspecified(rotate: &ComputedRotate) -> Result<(Number, Number, Number, Angle), ()> {
|
||||
// According to the spec:
|
||||
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
|
||||
//
|
||||
// If the axis is unspecified, it defaults to "0 0 1"
|
||||
match *rotate {
|
||||
Rotate::None =>
|
||||
Ok((0., 0., 1., Angle::zero())),
|
||||
Rotate::Rotate3D(rx, ry, rz, angle) => Ok((rx, ry, rz, angle)),
|
||||
Rotate::Rotate(angle) => Ok((0., 0., 1., angle)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Animate for ComputedRotate {
|
||||
#[inline]
|
||||
fn animate(
|
||||
&self,
|
||||
other: &Self,
|
||||
procedure: Procedure,
|
||||
) -> Result<Self, ()> {
|
||||
let from = ComputedRotate::fill_unspecified(self)?;
|
||||
let to = ComputedRotate::fill_unspecified(other)?;
|
||||
|
||||
let (fx, fy, fz, fa) = transform::get_normalized_vector_and_angle(from.0, from.1, from.2, from.3);
|
||||
let (tx, ty, tz, ta) = transform::get_normalized_vector_and_angle(to.0, to.1, to.2, to.3);
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-transforms-2/#propdef-translate>
|
||||
impl ComputedTranslate {
|
||||
fn fill_unspecified(translate: &ComputedTranslate)
|
||||
-> Result<(LengthOrPercentage, LengthOrPercentage, Length), ()> {
|
||||
// According to the spec:
|
||||
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
|
||||
//
|
||||
// Unspecified translations default to 0px
|
||||
match *translate {
|
||||
Translate::None => {
|
||||
Ok((LengthOrPercentage::Length(Length::zero()),
|
||||
LengthOrPercentage::Length(Length::zero()),
|
||||
Length::zero()))
|
||||
},
|
||||
Translate::Translate3D(tx, ty, tz) => Ok((tx, ty, tz)),
|
||||
Translate::Translate(tx, ty) => Ok((tx, ty, Length::zero())),
|
||||
Translate::TranslateX(tx) => Ok((tx, LengthOrPercentage::Length(Length::zero()), Length::zero())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Animate for ComputedTranslate {
|
||||
#[inline]
|
||||
fn animate(
|
||||
&self,
|
||||
other: &Self,
|
||||
procedure: Procedure,
|
||||
) -> Result<Self, ()> {
|
||||
let from = ComputedTranslate::fill_unspecified(self)?;
|
||||
let to = ComputedTranslate::fill_unspecified(other)?;
|
||||
|
||||
Ok(Translate::Translate3D(from.0.animate(&to.0, procedure)?,
|
||||
from.1.animate(&to.1, procedure)?,
|
||||
from.2.animate(&to.2, procedure)?))
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-transforms-2/#propdef-scale>
|
||||
impl ComputedScale {
|
||||
fn fill_unspecified(scale: &ComputedScale)
|
||||
-> Result<(Number, Number, Number), ()> {
|
||||
// According to the spec:
|
||||
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
|
||||
//
|
||||
// Unspecified scales default to 1
|
||||
match *scale {
|
||||
Scale::None => Ok((1.0, 1.0, 1.0)),
|
||||
Scale::Scale3D(sx, sy, sz) => Ok((sx, sy, sz)),
|
||||
Scale::Scale(sx, sy) => Ok((sx, sy, 1.)),
|
||||
Scale::ScaleX(sx) => Ok((sx, 1., 1.)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Animate for ComputedScale {
|
||||
#[inline]
|
||||
fn animate(
|
||||
&self,
|
||||
other: &Self,
|
||||
procedure: Procedure,
|
||||
) -> Result<Self, ()> {
|
||||
let from = ComputedScale::fill_unspecified(self)?;
|
||||
let to = ComputedScale::fill_unspecified(other)?;
|
||||
|
||||
if procedure == Procedure::Add {
|
||||
// scale(x1,y1,z1)*scale(x2,y2,z2) = scale(x1*x2, y1*y2, z1*z2)
|
||||
return Ok(Scale::Scale3D(from.0 * to.0, from.1 * to.1, from.2 * to.2));
|
||||
}
|
||||
|
||||
Ok(Scale::Scale3D(animate_multiplicative_factor(from.0, to.0, procedure)?,
|
||||
animate_multiplicative_factor(from.1, to.1, procedure)?,
|
||||
animate_multiplicative_factor(from.2, to.2, procedure)?))
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-transforms/#interpolation-of-transforms>
|
||||
impl Animate for ComputedTransform {
|
||||
#[inline]
|
||||
|
|
|
@ -669,7 +669,7 @@ pub fn get_normalized_vector_and_angle<T: Zero>(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Animate, ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)]
|
||||
#[derive(ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)]
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
/// A value of the `Rotate` property
|
||||
///
|
||||
|
@ -683,7 +683,7 @@ pub enum Rotate<Number, Angle> {
|
|||
Rotate3D(Number, Number, Number, Angle),
|
||||
}
|
||||
|
||||
#[derive(Animate, ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)]
|
||||
#[derive(ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)]
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
/// A value of the `Scale` property
|
||||
///
|
||||
|
@ -699,7 +699,7 @@ pub enum Scale<Number> {
|
|||
Scale3D(Number, Number, Number),
|
||||
}
|
||||
|
||||
#[derive(Animate, ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)]
|
||||
#[derive(ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)]
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
/// A value of the `Translate` property
|
||||
///
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue