-
Notifications
You must be signed in to change notification settings - Fork 5
/
Stairs.fr
51 lines (33 loc) · 1.63 KB
/
Stairs.fr
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
39
40
41
42
43
44
45
46
module Stairs where
import org.frege.SketchBook (paint)
import fregefx.JavaFxAll (GraphicsContext)
import fregefx.JavaFxUtils (withUI)
import Data.List
--- A point on the canvas.
data Point = P {x, y :: Double}
--- The last four points that we have drawn a line to, latest first.
type Trail = (Point, Point, Point, Point)
--- The initial trail.
--- Note that the starting point is tugged in a little to make the first bearing landing at the right point.
start = ( P (-10) 10, P (-10) (-10), P 10 (-10), P 9.5 9.5 )
--- Return the point that we reach when drawing a line from _start_ to _over_ and extend by 5%.
bearing:: Point -> Point -> Point
bearing start over = P ((over.x - start.x) * 1.05 + start.x ) ((over.y - start.y) * 1.05 + start.y)
--- How to move the trails one step forward.
step :: Trail -> Trail
step (first, second, third, last) = (bearing first last, first, second, third)
--- The infinite production of trails.
trails :: [Trail]
trails = iterate step start
--- Given a trail with a new head, paint the line that connects it to its body (= old head).
connect :: GraphicsContext -> Trail -> IO ()
connect ctx (nextHead,head,_,_) = withUI $ ctx.strokeLine head.x head.y nextHead.x nextHead.y
--- A doodle contains all actions that when applied in sequence make up the picture.
doodle :: GraphicsContext -> [IO ()]
doodle ctx = map (connect ctx) trails
--- Play any function _f_ that returns a list of IO actions
play f = paint $ sequence_ . f
--- Sample usage: paint the doodle at once.
fast = play $ take 300 . doodle
--- Sample usage: make every second action a sleep.
slow = play $ intersperse (Thread.sleep 100) . take 300 . doodle