Skip to content

Instantly share code, notes, and snippets.

@paf31
Last active December 17, 2015 16:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paf31/5638822 to your computer and use it in GitHub Desktop.
Save paf31/5638822 to your computer and use it in GitHub Desktop.
Juggling in Elm
pauseTime = 0.35
timePerThrow = 300
handMovement = 0.2
pattern = [5]
rotatePattern : Int -> [a] -> [a]
rotatePattern n xs =
if | n < length xs -> drop n xs ++ take n xs
| otherwise -> rotatePattern (n - length xs) xs
heightAtTime : [Int] -> Float -> Int
heightAtTime hs t =
let h = head hs in
if | t < toFloat h -> h
| otherwise -> heightAtTime (rotatePattern h hs) (t - toFloat h)
xAtTime : [Int] -> Float -> Float
xAtTime hs t =
let h = head hs in
if | t < pauseTime -> t / pauseTime * handMovement
| (t < toFloat h) && (h `mod` 2 == 0) -> handMovement * (toFloat h - t) / (toFloat h - pauseTime)
| t < toFloat h -> handMovement + (1 - handMovement) * (t - pauseTime) / (toFloat h - pauseTime)
| h `mod` 2 == 0 -> xAtTime (rotatePattern h hs) (t - toFloat h)
| otherwise -> 1 + xAtTime (rotatePattern h hs) (t - toFloat h)
yAtTime : [Int] -> Float -> Float
yAtTime hs t =
let h = head hs in
if | t < pauseTime -> 0
| t < toFloat h -> (t - pauseTime) / (toFloat h - pauseTime)
| otherwise -> yAtTime (rotatePattern h hs) (t - toFloat h)
clip : Float -> Float
clip x =
if | x > 1 -> 1 - clip (x - 1)
| x < 0 -> clip (0 - x)
| otherwise -> x
project : Float -> Float -> Int -> Int -> (Float, Float)
project x y h maxHeight =
let
xProj = 280.0 * x - 140.0
yProj = 280.0 * (4.0 * toFloat h * y * (1.0 - y) / toFloat maxHeight) - 140.0
in
(xProj, yProj)
positionOfBallAt : [Int] -> Int -> Float -> Int -> (Float, Float)
positionOfBallAt heights maxHeight time index =
let
x = xAtTime heights time
y = yAtTime heights time
cx = clip (toFloat index + x)
h = heightAtTime heights time
in
project cx y (h - 1) maxHeight
frameFor : [Int] -> Int -> Int -> Int -> Int -> Form
frameFor heights timePeriod maxHeight millis index =
let
startMillis = index * timePerThrow
relativeTime = toFloat ((millis - startMillis) `mod` timePeriod) / toFloat timePerThrow
rotatedPattern = rotatePattern index heights
position = positionOfBallAt rotatedPattern maxHeight relativeTime index
in
circle 10 |> filled black |> move position
frame : [Int] -> Int -> Element
frame heights millis =
let
period = 2 * sum heights
timePeriod = timePerThrow * period
maxHeight = maximum heights
in
[0 .. period - 1] |> List.map (frameFor heights timePeriod maxHeight millis) |> collage 300 300
main : Signal Element
main = lift (frame pattern . round) (every millisecond)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment