prizm-0.2.0.0: src/Data/Prizm/Color.hs
module Data.Prizm.Color where
import Control.Applicative
import Data.Prizm.Types
import Data.Prizm.Color.CIE as C
pct :: Integer -> Double
pct = (/100) . fromIntegral . (max 0) . (min 100)
pctClamp :: Integer -> Integer
pctClamp i = max (min i 100) 0
-- | Blend two colors using a 50% weighted average.
blend :: (CIEXYZ Double, CIEXYZ Double) -> CIEXYZ Double
blend = blendWeighted 50
-- | Shade a color by blending it using a weight and the color black.
shade :: CIEXYZ Double -> Percent -> CIEXYZ Double
shade c w = blendWeighted (pctClamp w) (CIEXYZ 0.0 0.0 0.0, c)
-- | Tint a color by blending it using a weight and the color white.
tint :: CIEXYZ Double -> Percent -> CIEXYZ Double
tint c w = blendWeighted (pctClamp w) ((CIEXYZ 95.047 100.0 108.883), c)
darken :: CIEXYZ Double -> Percent -> CIEXYZ Double
darken c w =
let (CIELAB l a b) = C.toLAB c
l' = l - (l*(pct (pctClamp w)))
in C.toXYZ (CIELAB l' a b)
lighten :: CIEXYZ Double -> Percent -> CIEXYZ Double
lighten c w =
let (CIELAB l a b) = C.toLAB c
l' = l + (l*(pct (pctClamp w)))
in C.toXYZ (CIELAB l' a b)
-- | Blend using a weighted average for two XYZ colors.
--
-- Weight are applied left to right, so if a weight of 25% is
-- supplied, then the color on the left will be multiplied by 25% and
-- the second color will be multiplied by 75%.
blendWeighted :: Percent -> (CIEXYZ Double, CIEXYZ Double) -> CIEXYZ Double
blendWeighted w (a,b) =
let w' = (pct (pctClamp w))
a1 = (*w') <$> a
b1 = (*(1.0 - w')) <$> b
in (+) <$> a1 <*> b1