color.rs (3036B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 //! Animated types for CSS colors. 6 7 use crate::color::mix::ColorInterpolationMethod; 8 use crate::color::AbsoluteColor; 9 use crate::values::animated::{Animate, Procedure, ToAnimatedZero}; 10 use crate::values::computed::Percentage; 11 use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; 12 use crate::values::generics::color::{ColorMixFlags, GenericColor, GenericColorMix}; 13 14 impl Animate for AbsoluteColor { 15 #[inline] 16 fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> { 17 let (left_weight, right_weight) = procedure.weights(); 18 Ok(crate::color::mix::mix( 19 ColorInterpolationMethod::best_interpolation_between(self, other), 20 self, 21 left_weight as f32, 22 other, 23 right_weight as f32, 24 ColorMixFlags::empty(), 25 )) 26 } 27 } 28 29 impl ComputeSquaredDistance for AbsoluteColor { 30 #[inline] 31 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> { 32 let start = [ 33 self.alpha, 34 self.components.0 * self.alpha, 35 self.components.1 * self.alpha, 36 self.components.2 * self.alpha, 37 ]; 38 let end = [ 39 other.alpha, 40 other.components.0 * other.alpha, 41 other.components.1 * other.alpha, 42 other.components.2 * other.alpha, 43 ]; 44 start 45 .iter() 46 .zip(&end) 47 .map(|(this, other)| this.compute_squared_distance(other)) 48 .sum() 49 } 50 } 51 52 /// An animated value for `<color>`. 53 pub type Color = GenericColor<Percentage>; 54 55 /// An animated value for `<color-mix>`. 56 pub type ColorMix = GenericColorMix<Color, Percentage>; 57 58 impl Animate for Color { 59 #[inline] 60 fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> { 61 let (left_weight, right_weight) = procedure.weights(); 62 Ok(Self::from_color_mix(ColorMix { 63 interpolation: ColorInterpolationMethod::srgb(), 64 left: self.clone(), 65 left_percentage: Percentage(left_weight as f32), 66 right: other.clone(), 67 right_percentage: Percentage(right_weight as f32), 68 // See https://github.com/w3c/csswg-drafts/issues/7324 69 flags: ColorMixFlags::empty(), 70 })) 71 } 72 } 73 74 impl ComputeSquaredDistance for Color { 75 #[inline] 76 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> { 77 let current_color = AbsoluteColor::TRANSPARENT_BLACK; 78 self.resolve_to_absolute(¤t_color) 79 .compute_squared_distance(&other.resolve_to_absolute(¤t_color)) 80 } 81 } 82 83 impl ToAnimatedZero for Color { 84 #[inline] 85 fn to_animated_zero(&self) -> Result<Self, ()> { 86 Ok(Color::Absolute(AbsoluteColor::TRANSPARENT_BLACK)) 87 } 88 }