module NanoUI.Animatable
( Animatable (..)
) where
import Data.Word (Word8)
import NanoUI.Types (Color, V2 (..), clamp01, colorA, colorB, colorG, colorR, colorRGBA)
class Animatable a where
toComponents :: a -> [Float]
fromComponents :: [Float] -> a
instance Animatable Float where
toComponents :: Float -> [Float]
toComponents Float
v = [Float
v]
fromComponents :: [Float] -> Float
fromComponents (Float
v : [Float]
_) = Float
v
fromComponents [] = Float
0
instance Animatable Double where
toComponents :: Double -> [Float]
toComponents Double
v = [Double -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
v]
fromComponents :: [Float] -> Double
fromComponents (Float
v : [Float]
_) = Float -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
v
fromComponents [] = Double
0
instance Animatable V2 where
toComponents :: V2 -> [Float]
toComponents (V2 Float
x Float
y) = [Float
x, Float
y]
fromComponents :: [Float] -> V2
fromComponents (Float
x : Float
y : [Float]
_) = Float -> Float -> V2
V2 Float
x Float
y
fromComponents [Float
x] = Float -> Float -> V2
V2 Float
x Float
0
fromComponents [] = Float -> Float -> V2
V2 Float
0 Float
0
instance Animatable Color where
toComponents :: Color -> [Float]
toComponents Color
c =
[Word8 -> Float
chan (Color -> Word8
colorR Color
c), Word8 -> Float
chan (Color -> Word8
colorG Color
c), Word8 -> Float
chan (Color -> Word8
colorB Color
c), Word8 -> Float
chan (Color -> Word8
colorA Color
c)]
fromComponents :: [Float] -> Color
fromComponents (Float
r : Float
g : Float
b : Float
a : [Float]
_) =
Word8 -> Word8 -> Word8 -> Word8 -> Color
colorRGBA (Float -> Word8
byte Float
r) (Float -> Word8
byte Float
g) (Float -> Word8
byte Float
b) (Float -> Word8
byte Float
a)
fromComponents [Float]
xs = [Float] -> Color
forall a. Animatable a => [Float] -> a
fromComponents (Int -> [Float] -> [Float]
forall a. Int -> [a] -> [a]
take Int
3 ([Float]
xs [Float] -> [Float] -> [Float]
forall a. [a] -> [a] -> [a]
++ Float -> [Float]
forall a. a -> [a]
repeat Float
0) [Float] -> [Float] -> [Float]
forall a. [a] -> [a] -> [a]
++ [Float
1])
chan :: Word8 -> Float
chan :: Word8 -> Float
chan Word8
w = Word8 -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
255
byte :: Float -> Word8
byte :: Float -> Word8
byte Float
x = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Float -> Int
forall b. Integral b => Float -> b
forall a b. (RealFrac a, Integral b) => a -> b
round (Float -> Float
clamp01 Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
255) :: Int)