mirror of
https://github.com/servo/servo.git
synced 2025-06-29 11:33:39 +01:00
style: Cleanup transform animation.
Reviewed-by: hiro But: 1465066 MozReview-Commit-ID: D9rq8CZIgf5
This commit is contained in:
parent
d5e19a146e
commit
92e2adf45f
1 changed files with 50 additions and 74 deletions
|
@ -2501,107 +2501,83 @@ impl Animate for ComputedScale {
|
||||||
/// <https://drafts.csswg.org/css-transforms/#interpolation-of-transforms>
|
/// <https://drafts.csswg.org/css-transforms/#interpolation-of-transforms>
|
||||||
impl Animate for ComputedTransform {
|
impl Animate for ComputedTransform {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn animate(
|
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||||
&self,
|
use std::borrow::Cow;
|
||||||
other_: &Self,
|
|
||||||
procedure: Procedure,
|
|
||||||
) -> Result<Self, ()> {
|
|
||||||
|
|
||||||
let animate_equal_lists = |this: &[ComputedTransformOperation],
|
|
||||||
other: &[ComputedTransformOperation]|
|
|
||||||
-> Result<ComputedTransform, ()> {
|
|
||||||
Ok(Transform(this.iter().zip(other)
|
|
||||||
.map(|(this, other)| this.animate(other, procedure))
|
|
||||||
.collect::<Result<Vec<_>, _>>()?))
|
|
||||||
// If we can't animate for a pair of matched transform lists
|
|
||||||
// this means we have at least one undecomposable matrix,
|
|
||||||
// so we should bubble out Err here, and let the caller do
|
|
||||||
// the fallback procedure.
|
|
||||||
};
|
|
||||||
if self.0.is_empty() && other_.0.is_empty() {
|
|
||||||
return Ok(Transform(vec![]));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let this = &self.0;
|
|
||||||
let other = &other_.0;
|
|
||||||
|
|
||||||
if procedure == Procedure::Add {
|
if procedure == Procedure::Add {
|
||||||
let result = this.iter().chain(other).cloned().collect::<Vec<_>>();
|
let result = self.0.iter().chain(&other.0).cloned().collect::<Vec<_>>();
|
||||||
return Ok(Transform(result));
|
return Ok(Transform(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// For matched transform lists.
|
|
||||||
{
|
|
||||||
if this.len() == other.len() {
|
|
||||||
let is_matched_transforms = this.iter().zip(other).all(|(this, other)| {
|
|
||||||
is_matched_operation(this, other)
|
|
||||||
});
|
|
||||||
|
|
||||||
if is_matched_transforms {
|
|
||||||
return animate_equal_lists(this, other);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For mismatched transform lists.
|
|
||||||
let mut owned_this = this.clone();
|
|
||||||
let mut owned_other = other.clone();
|
|
||||||
|
|
||||||
if this.is_empty() {
|
|
||||||
let this = other_.to_animated_zero()?.0;
|
|
||||||
if this.iter().zip(other).all(|(this, other)| is_matched_operation(this, other)) {
|
|
||||||
return animate_equal_lists(&this, other)
|
|
||||||
}
|
|
||||||
owned_this = this;
|
|
||||||
}
|
|
||||||
if other.is_empty() {
|
|
||||||
let other = self.to_animated_zero()?.0;
|
|
||||||
if this.iter().zip(&other).all(|(this, other)| is_matched_operation(this, other)) {
|
|
||||||
return animate_equal_lists(this, &other)
|
|
||||||
}
|
|
||||||
owned_other = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-transforms-1/#transform-transform-neutral-extend-animation
|
// https://drafts.csswg.org/css-transforms-1/#transform-transform-neutral-extend-animation
|
||||||
fn match_operations_if_possible(
|
fn match_operations_if_possible<'a>(
|
||||||
this: &mut Vec<ComputedTransformOperation>,
|
this: &mut Cow<'a, Vec<ComputedTransformOperation>>,
|
||||||
other: &mut Vec<ComputedTransformOperation>,
|
other: &mut Cow<'a, Vec<ComputedTransformOperation>>,
|
||||||
) -> Result<(), ()> {
|
) -> bool {
|
||||||
if !this.iter().zip(other.iter()).all(|(this, other)| is_matched_operation(this, other)) {
|
if !this.iter().zip(other.iter()).all(|(this, other)| is_matched_operation(this, other)) {
|
||||||
return Err(());
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.len() == other.len() {
|
if this.len() == other.len() {
|
||||||
return Ok(())
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (shorter, longer) = if this.len() < other.len() { (this, other) } else { (other, this) };
|
let (shorter, longer) =
|
||||||
shorter.reserve(longer.len());
|
if this.len() < other.len() {
|
||||||
for op in longer.iter().skip(shorter.len()) {
|
(this.to_mut(), other)
|
||||||
shorter.push(op.to_animated_zero()?);
|
} else {
|
||||||
}
|
(other.to_mut(), this)
|
||||||
Ok(())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if match_operations_if_possible(&mut owned_this, &mut owned_other).is_ok() {
|
shorter.reserve(longer.len());
|
||||||
return animate_equal_lists(&owned_this, &owned_other)
|
for op in longer.iter().skip(shorter.len()) {
|
||||||
|
shorter.push(op.to_animated_zero().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
// The resulting operations won't be matched regardless if the
|
||||||
|
// extended component is already InterpolateMatrix /
|
||||||
|
// AccumulateMatrix.
|
||||||
|
//
|
||||||
|
// Otherwise they should be matching operations all the time.
|
||||||
|
let already_mismatched = matches!(
|
||||||
|
longer[0],
|
||||||
|
TransformOperation::InterpolateMatrix { .. } |
|
||||||
|
TransformOperation::AccumulateMatrix { .. }
|
||||||
|
);
|
||||||
|
|
||||||
|
debug_assert_eq!(
|
||||||
|
!already_mismatched,
|
||||||
|
longer.iter().zip(shorter.iter()).all(|(this, other)| is_matched_operation(this, other)),
|
||||||
|
"ToAnimatedZero should generate matched operations"
|
||||||
|
);
|
||||||
|
|
||||||
|
!already_mismatched
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut this = Cow::Borrowed(&self.0);
|
||||||
|
let mut other = Cow::Borrowed(&other.0);
|
||||||
|
|
||||||
|
if match_operations_if_possible(&mut this, &mut other) {
|
||||||
|
return Ok(Transform(
|
||||||
|
this.iter().zip(other.iter())
|
||||||
|
.map(|(this, other)| this.animate(other, procedure))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
match procedure {
|
match procedure {
|
||||||
Procedure::Add => Err(()),
|
Procedure::Add => Err(()),
|
||||||
Procedure::Interpolate { progress } => {
|
Procedure::Interpolate { progress } => {
|
||||||
Ok(Transform(vec![TransformOperation::InterpolateMatrix {
|
Ok(Transform(vec![TransformOperation::InterpolateMatrix {
|
||||||
from_list: Transform(owned_this),
|
from_list: Transform(this.into_owned()),
|
||||||
to_list: Transform(owned_other),
|
to_list: Transform(other.into_owned()),
|
||||||
progress: Percentage(progress as f32),
|
progress: Percentage(progress as f32),
|
||||||
}]))
|
}]))
|
||||||
},
|
},
|
||||||
Procedure::Accumulate { count } => {
|
Procedure::Accumulate { count } => {
|
||||||
Ok(Transform(vec![TransformOperation::AccumulateMatrix {
|
Ok(Transform(vec![TransformOperation::AccumulateMatrix {
|
||||||
from_list: Transform(owned_this),
|
from_list: Transform(this.into_owned()),
|
||||||
to_list: Transform(owned_other),
|
to_list: Transform(other.into_owned()),
|
||||||
count: cmp::min(count, i32::max_value() as u64) as i32,
|
count: cmp::min(count, i32::max_value() as u64) as i32,
|
||||||
}]))
|
}]))
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue