diff --git a/lib/asciinema/colors.ex b/lib/asciinema/colors.ex index a6f13e96b..50c1928bc 100644 --- a/lib/asciinema/colors.ex +++ b/lib/asciinema/colors.ex @@ -1,15 +1,7 @@ defmodule Asciinema.Colors do - def mix( - <<"#", r1::binary-size(2), g1::binary-size(2), b1::binary-size(2)>>, - <<"#", r2::binary-size(2), g2::binary-size(2), b2::binary-size(2)>>, - ratio - ) do - r1 = String.to_integer(r1, 16) - g1 = String.to_integer(g1, 16) - b1 = String.to_integer(b1, 16) - r2 = String.to_integer(r2, 16) - g2 = String.to_integer(g2, 16) - b2 = String.to_integer(b2, 16) + def mix(c1, c2, ratio) do + {r1, g1, b1} = parse_color(c1) + {r2, g2, b2} = parse_color(c2) r = hex(floor(r1 * ratio + r2 * (1 - ratio))) g = hex(floor(g1 * ratio + g2 * (1 - ratio))) b = hex(floor(b1 * ratio + b2 * (1 - ratio))) @@ -24,5 +16,18 @@ defmodule Asciinema.Colors do int |> Integer.to_string(16) |> String.pad_leading(2, "0") + |> String.downcase() + end + + defp parse_color(<<"#", r::binary-size(2), g::binary-size(2), b::binary-size(2)>>) do + {String.to_integer(r, 16), String.to_integer(g, 16), String.to_integer(b, 16)} + end + + defp parse_color("rgb(" <> rest) do + rest + |> String.slice(0, String.length(rest) - 1) + |> String.split(",", parts: 3) + |> Enum.map(&String.to_integer(String.trim(&1))) + |> List.to_tuple() end end diff --git a/test/asciinema/colors_test.exs b/test/asciinema/colors_test.exs new file mode 100644 index 000000000..a424f2e2e --- /dev/null +++ b/test/asciinema/colors_test.exs @@ -0,0 +1,15 @@ +defmodule Asciinema.ColorsTest do + use ExUnit.Case, async: true + alias Asciinema.Colors + + describe "mix/3" do + test "blends two colors using given ratio" do + assert Colors.mix("#000000", "#222222", 0.5) == "#111111" + assert Colors.mix("#007fff", "#ff7f00", 0.5) == "#7f7f7f" + assert Colors.mix("#007fff", "#ff7f00", 0) == "#ff7f00" + assert Colors.mix("#007fff", "#ff7f00", 1) == "#007fff" + assert Colors.mix("#007fff", "rgb(255,127,0)", 0.5) == "#7f7f7f" + assert Colors.mix("rgb(0,127,255)", "#ff7f00", 0.5) == "#7f7f7f" + end + end +end