///|
/// Palette utilities for animated gradients, posterized effects, and export
/// previews.
pub struct Palette2 {
colors : Array[Rgba]
name : String
} derive(Debug)
///|
pub fn palette2(name : String, colors : Array[Rgba]) -> Palette2 {
{ colors: colors.copy(), name }
}
///|
pub fn Palette2::name(self : Palette2) -> String {
self.name
}
///|
pub fn Palette2::colors(self : Palette2) -> Array[Rgba] {
self.colors.copy()
}
///|
pub fn Palette2::length(self : Palette2) -> Int {
self.colors.length()
}
///|
pub fn Palette2::sample(self : Palette2, ratio : Double) -> Rgba {
palette_lerp(self.colors, ratio)
}
///|
pub fn Palette2::nearest(self : Palette2, color : Rgba) -> Rgba {
palette_nearest(self.colors, color)
}
///|
pub fn Palette2::reverse(self : Palette2) -> Palette2 {
let colors : Array[Rgba] = []
let mut index = self.colors.length()
while index > 0 {
index = index - 1
colors.push(self.colors[index])
}
palette2(self.name, colors)
}
///|
pub fn Palette2::lerp(
self : Palette2,
other : Palette2,
ratio : Double,
) -> Palette2 {
let count = self.colors.length().max(other.colors.length())
let colors : Array[Rgba] = []
for index in 0.. Palette2 {
let colors : Array[Rgba] = []
for color in self.colors {
colors.push(color.with_alpha(alpha))
}
palette2(self.name, colors)
}
///|
pub fn Palette2::map(self : Palette2, mapper : (Rgba) -> Rgba) -> Palette2 {
let colors : Array[Rgba] = []
for color in self.colors {
colors.push(mapper(color))
}
palette2(self.name, colors)
}
///|
pub struct PaletteQuantization2 {
index : Int
color : Rgba
error : Double
} derive(Debug)
///|
pub fn PaletteQuantization2::index(self : PaletteQuantization2) -> Int {
self.index
}
///|
pub fn PaletteQuantization2::color(self : PaletteQuantization2) -> Rgba {
self.color
}
///|
pub fn PaletteQuantization2::error(self : PaletteQuantization2) -> Double {
self.error
}
///|
pub fn Palette2::quantize(
self : Palette2,
color : Rgba,
) -> PaletteQuantization2 {
if self.colors.length() == 0 {
return { index: -1, color, error: 0.0 }
}
let mut best_index = 0
let mut best_error = self.colors[0].distance(color)
for index in 1.. Array[PaletteQuantization2] {
let result : Array[PaletteQuantization2] = []
for color in colors {
result.push(palette.quantize(color))
}
result
}
///|
pub fn palette_average(colors : Array[Rgba]) -> Rgba {
if colors.length() == 0 {
return rgba(r=0.0, g=0.0, b=0.0, a=0.0)
}
let mut red = 0.0
let mut green = 0.0
let mut blue = 0.0
let mut alpha = 0.0
for color in colors {
red = red + color.red()
green = green + color.green()
blue = blue + color.blue()
alpha = alpha + color.alpha()
}
let count = colors.length().to_double()
rgba(r=red / count, g=green / count, b=blue / count, a=alpha / count)
}
///|
pub fn palette_variance(colors : Array[Rgba]) -> Double {
let average = palette_average(colors)
if colors.length() == 0 {
return 0.0
}
let mut sum = 0.0
for color in colors {
let distance = color.distance(average)
sum = sum + distance * distance
}
sum / colors.length().to_double()
}
///|
pub fn palette_gradient2(start : Rgba, end : Rgba, count : Int) -> Palette2 {
let colors : Array[Rgba] = []
let actual = count.max(1)
for index in 0..