Skip to content

Commit a6ab8fa

Browse files
hecrjhojjatabdollahi
authored andcommitted
Merge pull request iced-rs#3274 from janTatesa/interpolate_color
feat(color): implement Interpolated
1 parent 8f2aec3 commit a6ab8fa

2 files changed

Lines changed: 34 additions & 25 deletions

File tree

core/src/color.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::animation::Interpolable;
2+
13
/// A color in the `sRGB` color space.
24
///
35
/// # String Representation
@@ -146,6 +148,22 @@ impl Color {
146148
}
147149
}
148150

151+
/// Mixes the current [`Color`] with another one by the given factor.
152+
pub fn mix(self, b: Color, factor: f32) -> Color {
153+
let b_amount = factor.clamp(0.0, 1.0);
154+
let a_amount = 1.0 - b_amount;
155+
156+
let a_linear = self.into_linear().map(|c| c * a_amount);
157+
let b_linear = b.into_linear().map(|c| c * b_amount);
158+
159+
Color::from_linear_rgba(
160+
a_linear[0] + b_linear[0],
161+
a_linear[1] + b_linear[1],
162+
a_linear[2] + b_linear[2],
163+
a_linear[3] + b_linear[3],
164+
)
165+
}
166+
149167
/// Returns the relative luminance of the [`Color`].
150168
/// <https://www.w3.org/TR/WCAG21/#dfn-relative-luminance>
151169
#[must_use]
@@ -330,6 +348,13 @@ impl From<Color> for palette::Srgba<f32> {
330348
}
331349
}
332350

351+
impl Interpolable for Color {
352+
/// Interpolates the color. Equivalent to [`Color::mix`].
353+
fn interpolated(&self, other: Self, ratio: f32) -> Self {
354+
self.mix(other, ratio)
355+
}
356+
}
357+
333358
/// Creates a [`Color`] with shorter and cleaner syntax.
334359
///
335360
/// # Examples

core/src/theme/palette.rs

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ pub struct Primary {
510510
impl Primary {
511511
/// Generates a set of [`Primary`] colors from the base, background, and text colors.
512512
pub fn generate(base: Color, background: Color, text: Color) -> Self {
513-
let weak = mix(base, background, 0.4);
513+
let weak = base.mix(background, 0.4);
514514
let strong = deviate(base, 0.1);
515515

516516
Self {
@@ -537,9 +537,9 @@ impl Secondary {
537537
pub fn generate(base: Color, text: Color) -> Self {
538538
let factor = if is_dark(base) { 0.2 } else { 0.4 };
539539

540-
let weak = mix(deviate(base, 0.1), text, factor);
541-
let strong = mix(deviate(base, 0.3), text, factor);
542-
let base = mix(deviate(base, 0.2), text, factor);
540+
let weak = deviate(base, 0.1).mix(text, factor);
541+
let strong = deviate(base, 0.3).mix(text, factor);
542+
let base = deviate(base, 0.2).mix(text, factor);
543543

544544
Self {
545545
base: Pair::new(base, text),
@@ -563,7 +563,7 @@ pub struct Success {
563563
impl Success {
564564
/// Generates a set of [`Success`] colors from the base, background, and text colors.
565565
pub fn generate(base: Color, background: Color, text: Color) -> Self {
566-
let weak = mix(base, background, 0.4);
566+
let weak = base.mix(background, 0.4);
567567
let strong = deviate(base, 0.1);
568568

569569
Self {
@@ -588,7 +588,7 @@ pub struct Warning {
588588
impl Warning {
589589
/// Generates a set of [`Warning`] colors from the base, background, and text colors.
590590
pub fn generate(base: Color, background: Color, text: Color) -> Self {
591-
let weak = mix(base, background, 0.4);
591+
let weak = base.mix(background, 0.4);
592592
let strong = deviate(base, 0.1);
593593

594594
Self {
@@ -613,7 +613,7 @@ pub struct Danger {
613613
impl Danger {
614614
/// Generates a set of [`Danger`] colors from the base, background, and text colors.
615615
pub fn generate(base: Color, background: Color, text: Color) -> Self {
616-
let weak = mix(base, background, 0.4);
616+
let weak = base.mix(background, 0.4);
617617
let strong = deviate(base, 0.1);
618618

619619
Self {
@@ -677,22 +677,6 @@ pub fn deviate(color: Color, amount: f32) -> Color {
677677
}
678678
}
679679

680-
/// Mixes two colors by the given factor.
681-
pub fn mix(a: Color, b: Color, factor: f32) -> Color {
682-
let b_amount = factor.clamp(0.0, 1.0);
683-
let a_amount = 1.0 - b_amount;
684-
685-
let a_linear = a.into_linear().map(|c| c * a_amount);
686-
let b_linear = b.into_linear().map(|c| c * b_amount);
687-
688-
Color::from_linear_rgba(
689-
a_linear[0] + b_linear[0],
690-
a_linear[1] + b_linear[1],
691-
a_linear[2] + b_linear[2],
692-
a_linear[3] + b_linear[3],
693-
)
694-
}
695-
696680
/// Computes a [`Color`] from the given text color that is
697681
/// readable on top of the given background color.
698682
pub fn readable(background: Color, text: Color) -> Color {
@@ -719,9 +703,9 @@ pub fn readable(background: Color, text: Color) -> Color {
719703
let black_contrast = background.relative_contrast(Color::BLACK);
720704

721705
if white_contrast >= black_contrast {
722-
mix(Color::WHITE, background, 0.05)
706+
Color::WHITE.mix(background, 0.05)
723707
} else {
724-
mix(Color::BLACK, background, 0.05)
708+
Color::BLACK.mix(background, 0.05)
725709
}
726710
}
727711

0 commit comments

Comments
 (0)