@@ -900,13 +900,15 @@ function rgbcolor(color::SimpleColor)
900900end
901901
902902"""
903- blend(a::Union{Symbol, SimpleColor}, b::Union{Symbol, SimpleColor}, α::Real)
903+ blend(a::Union{Symbol, SimpleColor}, [ b::Union{Symbol, SimpleColor} => α::Real]... )
904904
905905Blend colors `a` and `b` in Oklab space, with mix ratio `α` (0–1).
906906
907907The colors `a` and `b` can either be `SimpleColor`s, or `Symbol`s naming a face
908908or base color. The mix ratio `α` combines `(1 - α)` of `a` with `α` of `b`.
909909
910+ Multiple colors can be blended at once by providing multiple `b => α` pairs.
911+
910912# Examples
911913
912914```julia-repl
@@ -920,9 +922,11 @@ julia> blend(:green, SimpleColor(0xffffff), 0.3)
920922SimpleColor(■ #74be93)
921923```
922924"""
923- function blend (c1:: SimpleColor , c2:: SimpleColor , α:: Real )
924- function oklab (rgb:: RGBTuple )
925- r, g, b = (Tuple (rgb) ./ 255 ) .^ 2.2
925+ function blend end
926+
927+ function blend (primaries:: Pair{RGBTuple, <:Real} ...)
928+ function oklab (rgb:: RGBTuple )
929+ r, g, b = (rgb. r / 255 )^ 2.2 , (rgb. g / 255 )^ 2.2 , (rgb. b / 255 )^ 2.2
926930 l = cbrt (0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b)
927931 m = cbrt (0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b)
928932 s = cbrt (0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b)
@@ -941,22 +945,33 @@ function blend(c1::SimpleColor, c2::SimpleColor, α::Real)
941945 b = - 0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
942946 (r = tohex (r), g = tohex (g), b = tohex (b))
943947 end
944- lab1 = oklab (rgbcolor (c1))
945- lab2 = oklab (rgbcolor (c2))
946- mix = (L = (1 - α) * lab1. L + α * lab2. L,
947- a = (1 - α) * lab1. a + α * lab2. a,
948- b = (1 - α) * lab1. b + α * lab2. b)
949- SimpleColor (rgb (mix))
948+ L′, a′, b′ = 0.0 , 0.0 , 0.0
949+ for (color, α) in primaries
950+ lab = oklab (color)
951+ L′ += lab. L * α
952+ a′ += lab. a * α
953+ b′ += lab. b * α
954+ end
955+ mix = (L = L′, a = a′, b = b′)
956+ rgb (mix)
950957end
951958
952- function blend (f1:: Union{Symbol, SimpleColor} , f2:: Union{Symbol, SimpleColor} , α:: Real )
953- function face_or_color (name:: Symbol )
954- c = getface (name). foreground
955- if c. value === :foreground && haskey (FACES. basecolors, name)
956- c = SimpleColor (name)
957- end
958- c
959+ blend (base:: RGBTuple , primaries:: Pair{RGBTuple, <:Real} ...) =
960+ blend (base => 1.0 - sum (last, primaries), primaries... )
961+
962+ function blend (primaries:: Pair{<:Union{Symbol, SimpleColor}, <:Real} ...)
963+ function facecolor (color)
964+ rgbcolor (if color isa SimpleColor
965+ color
966+ else
967+ getface (color). foreground
968+ end )
959969 end
960- face_or_color (c:: SimpleColor ) = c
961- blend (face_or_color (f1), face_or_color (f2), α)
970+ SimpleColor (blend ((facecolor (c) => w for (c, w) in primaries). .. ))
962971end
972+
973+ blend (base:: Union{Symbol, SimpleColor} , primaries:: Pair{<:Union{Symbol, SimpleColor}, <:Real} ...) =
974+ SimpleColor (blend (rgbcolor (base), (rgbcolor (c) => w for (c, w) in primaries). .. ))
975+
976+ blend (a:: Union{Symbol, SimpleColor} , b:: Union{Symbol, SimpleColor} , α:: Real ) =
977+ blend (a => 1 - α, b => α)
0 commit comments