Skip to content

Commit

Permalink
feat: implement oklch
Browse files Browse the repository at this point in the history
  • Loading branch information
sandydoo committed Aug 24, 2024
1 parent ee872b7 commit e0e1b0d
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 20 deletions.
33 changes: 26 additions & 7 deletions src/Color/Interpolate.elm
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,38 @@ float start end time =


hue : Float -> Float -> Float -> Float
hue a b =
hue a b t =
let
ha =
normalizeHue a

hb =
normalizeHue b

-- Calculate the shortest distance between hues
d =
if b > a && b - a > 180 then
b - a + 360
if abs (hb - ha) <= 180 then
hb - ha

else if b < a && a - b > 180 then
b + 360 - a
else if hb > ha then
(hb - 360) - ha

else
b - a
(hb + 360) - ha
in
linear a d
normalizeHue (linear a d t)


normalizeHue : Float -> Float
normalizeHue h =
if h < 0 then
normalizeHue (h + 360)

else if h > 360 then
normalizeHue (h - 360)

else
h


scaleProgress : Int -> Float -> ( Int, Int, Float )
Expand Down
55 changes: 55 additions & 0 deletions src/Color/OkLch.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module Color.OkLch exposing (..)

import Color.Interpolate as Interpolate


type alias OkLch =
{ l : Float
, c : Float
, h : Float
, a : Maybe Float
}



-- Interpolate


interpolate : OkLch -> OkLch -> Float -> OkLch
interpolate a b time =
{ l = Interpolate.float a.l b.l time
, c = Interpolate.float a.c b.c time
, h = Interpolate.hue a.h b.h time
, a = Maybe.map2 (\aa ba -> Interpolate.float aa ba time) a.a b.a
}


interpolateLong : OkLch -> OkLch -> Float -> OkLch
interpolateLong a b time =
{ l = Interpolate.float a.l b.l time
, c = Interpolate.float a.c b.c time
, h = Interpolate.normalizeHue (Interpolate.float a.h b.h time)
, a = Maybe.map2 (\aa ba -> Interpolate.float aa ba time) a.a b.a
}



-- Serialize


toString : OkLch -> String
toString { l, c, h, a } =
"oklch("
++ String.fromFloat l
++ "% "
++ String.fromFloat c
++ " "
++ String.fromFloat h
++ (case a of
Just aa ->
" / " ++ String.fromFloat aa

Nothing ->
""
)
++ ")"
2 changes: 2 additions & 0 deletions src/Color/Rgb.elm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ interpolate rgb1 rgb2 time =
-- Serialize


toString : RGB -> String
toString { r, g, b } =
"rgb("
++ String.fromFloat r
Expand All @@ -33,6 +34,7 @@ toString { r, g, b } =
++ ")"


toP3String : RGB -> String
toP3String { r, g, b } =
"color(display-p3 "
++ String.fromFloat (r / 255)
Expand Down
22 changes: 9 additions & 13 deletions src/Draw.elm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Clock
import Color.Interpolate as Interpolate
import Color.Lab as Lab exposing (Lab)
import Color.Lch as Lch exposing (Lch)
import Color.OkLch as OkLch
import Color.Rgb as Rgb
import Cons exposing (cons)
import Svg exposing (Svg)
Expand Down Expand Up @@ -135,11 +136,13 @@ groupOfTicks clockArms =
List.concatMap ticksAlongTrack clockArms


colorFill : Float -> Lch
colorFill =
Lch.interpolateLong
{ l = 92.991667, c = 47.85505, h = -30 }
{ l = 92.991667, c = 47.85505, h = 330 }
colorFill : Float -> String
colorFill progress =
OkLch.toString <|
OkLch.interpolateLong
{ l = 98.0, c = 0.13, h = 60.0, a = Nothing }
{ l = 98.0, c = 0.13, h = 320.0, a = Nothing }
progress


singleArm : Clock.Arm -> Bool -> Float -> Svg msg
Expand All @@ -151,9 +154,6 @@ singleArm { radius, armRadius, animatedAngle } supportsP3Color delta =
progress =
newAngle / 360

fill =
(Lch.toLab >> Lab.toRgb) <| colorFill progress

( cx, cy ) =
pointOnArc 0 0 radius newAngle
in
Expand All @@ -170,11 +170,7 @@ singleArm { radius, armRadius, animatedAngle } supportsP3Color delta =
++ dotPath radius (newAngle - (armRadius / radius)) (0.8 * armRadius)
++ "Z"
, SA.fill <|
if supportsP3Color then
Rgb.toP3String fill

else
Rgb.toString fill
colorFill progress
, SA.fillRule "evenodd"
]
[]
Expand Down

0 comments on commit e0e1b0d

Please sign in to comment.