Happy Holidays
Happy Holidays
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)))))