Skip to main content

gpui_kit_material_color/dynamic/
blend.rs

1// Copyright 2021 Google LLC
2// SPDX-License-Identifier: Apache-2.0
3// Ported to Rust from material-color-utilities (typescript/blend), modified for
4// this crate. See licenses/material-color-utilities.txt.
5
6//! Blending in HCT and CAM16.
7use super::hct::{Cam16, Hct};
8use super::utils::{
9    difference_degrees, lstar_from_argb, rotation_direction, sanitize_degrees_double,
10};
11
12/// `design_color`'s hue shifted toward `source_color`'s: at most half their
13/// distance and at most 15 degrees, so it stays recognizable.
14pub fn harmonize(design_color: u32, source_color: u32) -> u32 {
15    let from = Hct::from_argb(design_color);
16    let to = Hct::from_argb(source_color);
17    let rotation = (difference_degrees(from.hue(), to.hue()) * 0.5).min(15.);
18    let hue =
19        sanitize_degrees_double(from.hue() + rotation * rotation_direction(from.hue(), to.hue()));
20    Hct::from_hct(hue, from.chroma(), from.tone()).argb()
21}
22
23/// `from` with its hue blended toward `to`; chroma and tone are kept.
24pub fn hct_hue(from: u32, to: u32, amount: f64) -> u32 {
25    let blended = Cam16::from_argb(cam16_ucs(from, to, amount));
26    Hct::from_hct(
27        blended.hue,
28        Cam16::from_argb(from).chroma,
29        lstar_from_argb(from),
30    )
31    .argb()
32}
33
34/// `from` blended toward `to` in CAM16-UCS; hue, chroma and tone all change.
35pub fn cam16_ucs(from: u32, to: u32, amount: f64) -> u32 {
36    let from = Cam16::from_argb(from);
37    let to = Cam16::from_argb(to);
38    Cam16::from_ucs(
39        from.jstar + (to.jstar - from.jstar) * amount,
40        from.astar + (to.astar - from.astar) * amount,
41        from.bstar + (to.bstar - from.bstar) * amount,
42    )
43    .to_argb()
44}