Skip to content

Commit 96b8ccf

Browse files
committed
Support blending of N colours at once
1 parent 6cdf468 commit 96b8ccf

File tree

2 files changed

+32
-19
lines changed

2 files changed

+32
-19
lines changed

docs/src/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,6 @@ StyledStrings.SimpleColor
341341
StyledStrings.parse(::Type{StyledStrings.SimpleColor}, ::String)
342342
StyledStrings.tryparse(::Type{StyledStrings.SimpleColor}, ::String)
343343
StyledStrings.merge(::StyledStrings.Face, ::StyledStrings.Face)
344-
StyledStrings.blend(::StyledStrings.SimpleColor, ::StyledStrings.SimpleColor, ::Real)
344+
StyledStrings.blend
345345
StyledStrings.recolor
346346
```

src/faces.jl

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -920,9 +920,11 @@ julia> blend(:green, SimpleColor(0xffffff), 0.3)
920920
SimpleColor(■ #74be93)
921921
```
922922
"""
923-
function blend(c1::SimpleColor, c2::SimpleColor, α::Real)
924-
function oklab(rgb::RGBTuple)
925-
r, g, b = (Tuple(rgb) ./ 255) .^ 2.2
923+
function blend end
924+
925+
function blend(primaries::Pair{RGBTuple, <:Real}...)
926+
function oklab(rgb::RGBTuple)
927+
r, g, b = (rgb.r / 255)^2.2, (rgb.g / 255)^2.2, (rgb.b / 255)^2.2
926928
l = cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b)
927929
m = cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b)
928930
s = cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b)
@@ -941,22 +943,33 @@ function blend(c1::SimpleColor, c2::SimpleColor, α::Real)
941943
b = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
942944
(r = tohex(r), g = tohex(g), b = tohex(b))
943945
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))
946+
L′, a′, b′ = 0.0, 0.0, 0.0
947+
for (color, α) in primaries
948+
lab = oklab(color)
949+
L′ += lab.L * α
950+
a′ += lab.a * α
951+
b′ += lab.b * α
952+
end
953+
mix = (L = L′, a = a′, b = b′)
954+
rgb(mix)
950955
end
951956

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
957+
blend(base::RGBTuple, primaries::Pair{RGBTuple, <:Real}...) =
958+
blend(base => 1.0 - sum(last, primaries), primaries...)
959+
960+
function blend(primaries::Pair{<:Union{Symbol, SimpleColor}, <:Real}...)
961+
function facecolor(color)
962+
rgbcolor(if color isa SimpleColor
963+
color
964+
else
965+
getface(color).foreground
966+
end)
959967
end
960-
face_or_color(c::SimpleColor) = c
961-
blend(face_or_color(f1), face_or_color(f2), α)
968+
SimpleColor(blend((facecolor(c) => w for (c, w) in primaries)...))
962969
end
970+
971+
blend(base::Union{Symbol, SimpleColor}, primaries::Pair{<:Union{Symbol, SimpleColor}, <:Real}...) =
972+
SimpleColor(blend(rgbcolor(base), (rgbcolor(c) => w for (c, w) in primaries)...))
973+
974+
blend(a::Union{Symbol, SimpleColor}, b::Union{Symbol, SimpleColor}, α::Real) =
975+
blend(a => 1 - α, b => α)

0 commit comments

Comments
 (0)