the code
(ns index)
(defn prep-canvas []
(let [can (js/document.createElement "canvas")
ctx (.getContext can "2d")
width js/window.innerWidth
height js/window.innerHeight]
(set! can.style "position: absolute; top: 0px; left: 0px;")
(set! can.width width)
(set! can.height height)
(js/document.body.appendChild can)
{:canvas can
:context ctx
:width width
:height height}))
(defn rand [n]
(js/Math.floor (* (js/Math.random) n)))
(defn render-snowflake [{:keys [context]} {:keys [x y size]}]
(set! context.fillStyle "#fff")
(set! context.font (str size "px serif"))
(.fillText context "*" x y))
(defn snowflake-step [{:keys [height]} {:keys [x y dy] :as snowflake}]
(set! snowflake.y (if (> y height) (- 20) (+ y dy)))
(set! snowflake.x (+ x (- (js/Math.random) 0.5))))
(defn gen-snowflakes [n {:keys [width height]}]
(->>
(range n)
(map
(fn [_]
(let [size (+ (rand 10) 2)
x (rand width)
y (rand height)]
{:size size
:x x
:y y
:dy (inc (js/Math.random 10))})))
(doall)))
(defn animation-loop [step-fn]
(step-fn)
(js/window.requestAnimationFrame (partial animation-loop step-fn)))
(defn draw-text [{:keys [context width height]} text]
(set! context.fillStyle "#fff")
(set! context.font "100px serif")
(context.fillText text (* width 0.3) (* height 2/6) (* width 7/8)))
(defn draw-terrain [{:keys [context width height]} fill growing?]
(set! context.fillStyle fill)
(context.beginPath)
(context.moveTo -500 (if growing? height height))
(loop [x 0
y (if growing?
(- height 100)
(- height 400))]
(if (< x width)
(let [x (+ x (+ 10 (rand 20)))
y (if growing?
(- y (rand 10))
(+ y (rand 10)))]
(context.lineTo x y)
(recur x y))
(context.lineTo (+ x 100) height)))
(context.fill))
(let [background (prep-canvas)
text-layer (prep-canvas)
{:keys [context width height] :as snow} (prep-canvas)
terrain (prep-canvas)
snowflakes (gen-snowflakes 800 snow)]
(background.context.fillRect 0 0 width height)
(draw-text text-layer "Happy Holidays!")
(draw-terrain terrain "#fff" true)
(draw-terrain terrain "#ddd" false)
(animation-loop
(fn []
(set! context.fillStyle "#000")
(context.clearRect 0 0 width height)
(doseq [sf snowflakes]
(render-snowflake snow sf)
(snowflake-step snow sf)))))
You must log in or register to comment.