From b0604c9be51b1179ad7008dc4ff2278b9c575af6 Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Fri, 7 Sep 2018 22:29:12 +0000 Subject: [PATCH] style: Make offset-path: path() animatable. Here, we change the animation type of offset-path as ComputedValue, so we could do animation on it. Also enable the wpt for offset-path interpolation. In test_transition_per_property.html, we add some basic tests ifor offset-path. ToAnimatedZero for PathCommand will be dropped later. Because the animations of arcs with mismatched flags are fallen back to discrete animations, the result of getComputedValue is not normalized in this case. This makes some wpt failed even though the progress is 100%. Depends on D4786 Differential Revision: https://phabricator.services.mozilla.com/D4787 --- .../style/properties/longhands/box.mako.rs | 2 +- components/style/values/animated/mod.rs | 11 ++++ components/style/values/specified/motion.rs | 4 +- components/style/values/specified/svg_path.rs | 63 ++++++++++++++++++- 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index 7dfc15cd14e2..ed7839360d97 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -379,7 +379,7 @@ ${helpers.predefined_type( "OffsetPath", "computed::OffsetPath::none()", products="gecko", - animation_value_type="none", + animation_value_type="ComputedValue", gecko_pref="layout.css.motion-path.enabled", flags="CREATES_STACKING_CONTEXT FIXPOS_CB", spec="https://drafts.fxtf.org/motion-1/#offset-path-property", diff --git a/components/style/values/animated/mod.rs b/components/style/values/animated/mod.rs index f09e18861702..1d0ccd6904c0 100644 --- a/components/style/values/animated/mod.rs +++ b/components/style/values/animated/mod.rs @@ -406,3 +406,14 @@ where )) } } + +impl ToAnimatedZero for Box<[T]> +where + T: ToAnimatedZero, +{ + #[inline] + fn to_animated_zero(&self) -> Result { + let v = self.iter().map(|v| v.to_animated_zero()).collect::, _>>()?; + Ok(v.into_boxed_slice()) + } +} diff --git a/components/style/values/specified/motion.rs b/components/style/values/specified/motion.rs index 87ff39d9a3ae..762c1dcfdd5f 100644 --- a/components/style/values/specified/motion.rs +++ b/components/style/values/specified/motion.rs @@ -12,7 +12,8 @@ use values::specified::SVGPathData; /// The offset-path value. /// /// https://drafts.fxtf.org/motion-1/#offset-path-property -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] +#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq, + SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, ToCss)] pub enum OffsetPath { // We could merge SVGPathData into ShapeSource, so we could reuse them. However, // we don't want to support other value for offset-path, so use SVGPathData only for now. @@ -20,6 +21,7 @@ pub enum OffsetPath { #[css(function)] Path(SVGPathData), /// None value. + #[animation(error)] None, // Bug 1186329: Implement ray(), , , and . } diff --git a/components/style/values/specified/svg_path.rs b/components/style/values/specified/svg_path.rs index d4583daaad7a..d31d182d9413 100644 --- a/components/style/values/specified/svg_path.rs +++ b/components/style/values/specified/svg_path.rs @@ -13,14 +13,15 @@ use std::slice; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; use style_traits::values::SequenceWriter; use values::CSSFloat; -use values::animated::{Animate, Procedure}; +use values::animated::{Animate, Procedure, ToAnimatedZero}; use values::distance::{ComputeSquaredDistance, SquaredDistance}; /// The SVG path data. /// /// https://www.w3.org/TR/SVG11/paths.html#PathData -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] +#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToAnimatedZero, + ToComputedValue)] pub struct SVGPathData(Box<[PathCommand]>); impl SVGPathData { @@ -336,10 +337,66 @@ impl ToCss for PathCommand { } } +impl ToAnimatedZero for PathCommand { + #[inline] + fn to_animated_zero(&self) -> Result { + use self::PathCommand::*; + let absolute = true; + match self { + &ClosePath => Ok(ClosePath), + &Unknown => Ok(Unknown), + &MoveTo { ref point, .. } => Ok(MoveTo { point: point.to_animated_zero()?, absolute }), + &LineTo { ref point, .. } => Ok(LineTo { point: point.to_animated_zero()?, absolute }), + &HorizontalLineTo { x, .. } => { + Ok(HorizontalLineTo { x: x.to_animated_zero()?, absolute }) + }, + &VerticalLineTo { y, .. } => { + Ok(VerticalLineTo { y: y.to_animated_zero()?, absolute }) + }, + &CurveTo { ref control1, ref control2, ref point, .. } => { + Ok(CurveTo { + control1: control1.to_animated_zero()?, + control2: control2.to_animated_zero()?, + point: point.to_animated_zero()?, + absolute, + }) + }, + &SmoothCurveTo { ref control2, ref point, .. } => { + Ok(SmoothCurveTo { + control2: control2.to_animated_zero()?, + point: point.to_animated_zero()?, + absolute, + }) + }, + &QuadBezierCurveTo { ref control1, ref point, .. } => { + Ok(QuadBezierCurveTo { + control1: control1.to_animated_zero()?, + point: point.to_animated_zero()?, + absolute, + }) + }, + &SmoothQuadBezierCurveTo { ref point, .. } => { + Ok(SmoothQuadBezierCurveTo { point: point.to_animated_zero()?, absolute }) + }, + &EllipticalArc { rx, ry, angle, large_arc_flag, sweep_flag, ref point, .. } => { + Ok(EllipticalArc { + rx: rx.to_animated_zero()?, + ry: ry.to_animated_zero()?, + angle: angle.to_animated_zero()?, + large_arc_flag, + sweep_flag, + point: point.to_animated_zero()?, + absolute, + }) + }, + } + } +} + /// The path coord type. #[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, - SpecifiedValueInfo, ToCss)] + SpecifiedValueInfo, ToAnimatedZero, ToCss)] #[repr(C)] pub struct CoordPair(CSSFloat, CSSFloat);