Add add() method to Animatable interface

This commit is contained in:
Brian Birtles 2017-05-15 12:53:14 +09:00
parent 2f07b29296
commit 49bc7b9e69
2 changed files with 73 additions and 10 deletions

View file

@ -118,6 +118,10 @@
self.0.add_weighted(&other.0, self_portion, other_portion).map(T)
}
fn add(&self, other: &Self) -> Result<Self, ()> {
self.0.add(&other.0).map(T)
}
#[inline]
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
self.0.compute_distance(&other.0)

View file

@ -608,6 +608,30 @@ impl Animatable for AnimationValue {
}
}
fn add(&self, other: &Self) -> Result<Self, ()> {
match (self, other) {
% for prop in data.longhands:
% if prop.animatable:
% if prop.animation_value_type == "discrete":
(&AnimationValue::${prop.camel_case}(_),
&AnimationValue::${prop.camel_case}(_)) => {
Err(())
}
% else:
(&AnimationValue::${prop.camel_case}(ref from),
&AnimationValue::${prop.camel_case}(ref to)) => {
from.add(to).map(AnimationValue::${prop.camel_case})
}
% endif
% endif
% endfor
_ => {
panic!("Expected weighted addition of computed values of the same \
property, got: {:?}, {:?}", self, other);
}
}
}
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
match (self, other) {
% for prop in data.longhands:
@ -648,6 +672,13 @@ pub trait Animatable: Sized {
self.add_weighted(other, 1.0 - progress, progress)
}
/// Returns the [sum][animation-addition] of this value and |other|.
///
/// [animation-addition]: https://w3c.github.io/web-animations/#animation-addition
fn add(&self, other: &Self) -> Result<Self, ()> {
self.add_weighted(other, 1.0, 1.0)
}
/// Compute distance between a value and another for a given property.
fn compute_distance(&self, _other: &Self) -> Result<f64, ()> { Err(()) }
@ -791,16 +822,12 @@ impl Animatable for Visibility {
#[inline]
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
match (*self, *other) {
(Visibility::visible, _) | (_, Visibility::visible) => {
Ok(if self_portion >= 0.0 && self_portion <= 1.0 &&
other_portion >= 0.0 && other_portion <= 1.0 {
Visibility::visible
} else if self_portion > other_portion {
*self
} else {
*other
})
}
(Visibility::visible, _) => {
Ok(if self_portion > 0.0 { *self } else { *other })
},
(_, Visibility::visible) => {
Ok(if other_portion > 0.0 { *other } else { *self })
},
_ => Err(()),
}
}
@ -1498,6 +1525,21 @@ impl Animatable for ClipRect {
Ok(${item}List(result))
}
fn add(&self, other: &Self) -> Result<Self, ()> {
let len = self.0.len() + other.0.len();
let mut result = if len > 1 {
SmallVec::from_vec(Vec::with_capacity(len))
} else {
SmallVec::new()
};
result.extend(self.0.iter().cloned());
result.extend(other.0.iter().cloned());
Ok(${item}List(result))
}
}
</%def>
@ -2439,6 +2481,23 @@ impl Animatable for TransformList {
Ok(result)
}
fn add(&self, other: &Self) -> Result<Self, ()> {
match (&self.0, &other.0) {
(&Some(ref from_list), &Some(ref to_list)) => {
Ok(TransformList(Some([&from_list[..], &to_list[..]].concat())))
}
(&Some(_), &None) => {
Ok(self.clone())
}
(&None, &Some(_)) => {
Ok(other.clone())
}
_ => {
Ok(TransformList(None))
}
}
}
}
impl<T, U> Animatable for Either<T, U>