diff --git a/src/Autoload/Palettes.gd b/src/Autoload/Palettes.gd index aee7ff6b2..4aa1c8588 100644 --- a/src/Autoload/Palettes.gd +++ b/src/Autoload/Palettes.gd @@ -4,7 +4,7 @@ signal palette_selected(palette_name: String) signal new_palette_created signal new_palette_imported -enum SortOptions { NEW_PALETTE, REVERSE, HUE, SATURATION, VALUE, RED, GREEN, BLUE, ALPHA } +enum SortOptions {NEW_PALETTE, REVERSE, HUE, SATURATION, VALUE, LIGHTNESS, RED, GREEN, BLUE, ALPHA} ## Presets for creating a new palette enum NewPalettePresetType {EMPTY, FROM_CURRENT_PALETTE, FROM_CURRENT_SPRITE, FROM_CURRENT_SELECTION} ## Color options when user creates a new palette from current sprite or selection diff --git a/src/Palette/Palette.gd b/src/Palette/Palette.gd index 3fda63a60..e2f480f78 100644 --- a/src/Palette/Palette.gd +++ b/src/Palette/Palette.gd @@ -287,6 +287,38 @@ func sort(option: Palettes.SortOptions) -> void: sort_method = func(a: PaletteColor, b: PaletteColor): return a.color.s < b.color.s Palettes.SortOptions.VALUE: sort_method = func(a: PaletteColor, b: PaletteColor): return a.color.v < b.color.v + Palettes.SortOptions.LIGHTNESS: + # Code inspired from: + # gdlint: ignore=max-line-length + # https://github.com/bottosson/bottosson.github.io/blob/master/misc/colorpicker/colorconversion.js#L519 + sort_method = func(a: PaletteColor, b: PaletteColor): + # function that returns OKHSL lightness + var lum: Callable = func(c: Color): + var l = 0.4122214708 * (c.r) + 0.5363325363 * (c.g) + 0.0514459929 * (c.b) + var m = 0.2119034982 * (c.r) + 0.6806995451 * (c.g) + 0.1073969566 * (c.b) + var s = 0.0883024619 * (c.r) + 0.2817188376 * (c.g) + 0.6299787005 * (c.b) + var l_cr = pow(l, 1 / 3.0) + var m_cr = pow(m, 1 / 3.0) + var s_cr = pow(s, 1 / 3.0) + var oklab_l = 0.2104542553 * l_cr + 0.7936177850 * m_cr - 0.0040720468 * s_cr + # calculating toe + var k_1 = 0.206 + var k_2 = 0.03 + var k_3 = (1 + k_1) / (1 + k_2) + return ( + 0.5 + * ( + k_3 * oklab_l + - k_1 + + sqrt( + ( + (k_3 * oklab_l - k_1) * (k_3 * oklab_l - k_1) + + 4 * k_2 * k_3 * oklab_l + ) + ) + ) + ) + return lum.call(a.color.srgb_to_linear()) < lum.call(b.color.srgb_to_linear()) Palettes.SortOptions.RED: sort_method = func(a: PaletteColor, b: PaletteColor): return a.color.r < b.color.r Palettes.SortOptions.GREEN: diff --git a/src/Palette/PalettePanel.gd b/src/Palette/PalettePanel.gd index 50ee1a9e5..7cc64c42d 100644 --- a/src/Palette/PalettePanel.gd +++ b/src/Palette/PalettePanel.gd @@ -49,6 +49,8 @@ func _ready() -> void: sort_button_popup.add_item("Sort by saturation", Palettes.SortOptions.SATURATION) sort_button_popup.add_item("Sort by value", Palettes.SortOptions.VALUE) sort_button_popup.add_separator() + sort_button_popup.add_item("Sort by lightness", Palettes.SortOptions.LIGHTNESS) + sort_button_popup.add_separator() sort_button_popup.add_item("Sort by red", Palettes.SortOptions.RED) sort_button_popup.add_item("Sort by green", Palettes.SortOptions.GREEN) sort_button_popup.add_item("Sort by blue", Palettes.SortOptions.BLUE)