Radiant and Simple

canvasanimation

A clojurescript implementation of http://www.openprocessing.org/sketch/137835 (originally by Ramiz Midani using _processing.js_). Used to test missing arc and ellipse methods from monet.

13 Sept 2014 by rm-hull
rm-hull/896d4599eff07b7493e0
radiant-and-simple.cljs
(ns big-bang.examples.radiant-simple
  (:require
    [cljs.core.async :as async]
    [dommy.core :refer [insert-after!]]
    [jayq.core :refer [show]]
    [big-bang.core :refer [big-bang]]
    [big-bang.components :refer [slider]]
    [enchilada :refer [ctx canvas canvas-size value-of]]
    [monet.canvas :refer [translate rotate scale save restore
                          stroke-width stroke-style stroke
                          fill fill-rect fill-style ellipse
                          begin-path ]])
  (:require-macros
    [dommy.macros :refer [sel1 node]]))

(defn box [content]
  [:span {:style "width: 250px;
display: inline-block;
border: 1px solid lightgrey;
margin-right: 5px;
margin-bottom: 5px;
padding-left: 5px;
border-radius: 3px;
background: whitesmoke;"} content])

(def dimensions
  (let [[width height] (canvas-size)]
    {:x 0 :y 0 :w width :h height}))

(def initial-state {
  :o 0.0
  :r 0.0
  :m (value-of :m 3)
  :clear? true})

(defn update-state [event {:keys [o r m]}]
  {:o (+ o (/ Math/PI 180))
   :r (Math/cos (* m o))
   :m m
   :clear? false})

(defn handle-incoming [event world-state]
  (merge world-state event {:o 0.0 :r 0.0 :clear? true}))

(defn clear-bg [ctx]
  (->
    ctx
    (fill-style :lightgrey)
    (fill-rect dimensions)))

(defn render [{:keys [o r clear?]}]
  (if clear?
    (clear-bg ctx)
    (->
      ctx
      (save)
      (translate (/ (:w dimensions) 2) (/ (:h dimensions) 2))
      (rotate o)
      (fill-style :white)
      (stroke-style :black)
      (translate (* r 250) 0)
      (ellipse {:x 0 :y 0 :rw 20 :rh 30})
      (fill)
      (stroke)
      (restore))))

(let [chan (async/chan)]
  (show canvas)
  (->>
    (sel1 :#canvas-area)
    (insert-after! (node
                    [:div
                     (box (slider
                       :id :m
                       :label-text "Multiplier:"
                       :min-value 0
                       :max-value 8
                       :step 0.1
                       :initial-value (initial-state :m)
                       :send-channel chan))])))

  (big-bang
    :initial-state initial-state
    :on-tick update-state
    :receive-channel chan
    :on-receive handle-incoming
    :to-draw render))