aboutsummaryrefslogtreecommitdiff
path: root/src/Color.ml
blob: d2f74c439481de2f3858f3cabe23518b64e4cb23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
let from_sRGB sRGB =
  if sRGB <= 0.03928 then
    sRGB /. 12.92
  else
    ((sRGB +. 0.055) /. 1.055) ** 2.4

type rgb =
  { r: float
  ; g: float
  ; b: float
  }

(* https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef *)
let relativeLuminance (c: rgb) =
  0.2126 *. from_sRGB (c.r /. 255.) +. 0.7152 *. from_sRGB (c.g /. 255.) +. 0.0722 *. from_sRGB (c.b /. 255.)

(* https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrastratio *)
let contrast_ratio (c1: rgb) (c2: rgb) =
  let rl1 = relativeLuminance c1  in
  let rl2 = relativeLuminance c2 in

  if (rl1 > rl2) then
    (rl1 +. 0.05) /. (rl2 +. 0.05)
  else
    (rl2 +. 0.05) /. (rl1 +. 0.05)

let from_raw color =
  let get_opt = function | Some x -> x | None -> raise (Invalid_argument "Option.get") in
  let div = H.div [| HA.style ("color: " ^ color) |] [| |] in
  let body = Document.query_selector_unsafe "body" in
  let () = Element.append_child body div in
  let rgb = [%raw {| window.getComputedStyle(div).color |}] in
  let () = Element.remove_child body div in
  let xs = Js.String.split ", " (get_opt (Js.String.splitByRe [%re "/[()]/"] rgb).(1)) in
  { r = Js.Float.fromString xs.(0)
  ; g = Js.Float.fromString xs.(1)
  ; b = Js.Float.fromString xs.(2)
  }