Color Vortex

canvaswebgl3danimation

Faux rotating torus testing alpha channels with HSV->RGB color conversion in https://github.com/rm-hull/inkspot. Click the canvas area to toggle between solid color and wireframe. Inspiration: Jerome Herr's http://openprocessing.org/sketch/160303

6 Dec 2014 by rm-hull
rm-hull/a7f33553c4aaf97a8162
color-vortex.cljs
(ns enchilada.color-vortex
  (:require
    [jayq.core :refer [show css]]
    [enchilada :refer [ctx canvas canvas-size]]
    [inkspot.color :refer [coerce red green blue]]
    [inkspot.converter :refer [hsv->rgb]]
    [big-bang.core :refer [big-bang]]
    [big-bang.events.browser :refer [offset-coords]]
    [monet.canvas :refer [stroke-style stroke fill-style fill fill-rect
                          ellipse save restore translate]]))

(def screen-area
  (let [[w h] (canvas-size)]
    {:x 0 :y 0 :w w :h h}))

(def steps 150)
(def angle (/ (* 2 Math/PI) steps))
(def initial-state { :theta 0 :style :solid })

(defn toggle-style [event world-state]
  (assoc world-state
    :style (if (= (:style world-state) :wireframe) :solid :wireframe)))

(defn update-state [event world-state]
  (update-in world-state [:theta] (partial + (/ 0.0523 3))))

(defn remap [value mina maxa minb maxb]
   (+ minb (* (- maxb minb) (/ (- value mina) (- maxa mina)))))

(def color-cache
  (mapv #(hsv->rgb [% 0.9 1.0 0.25]) (range 360)))

(def draw-func {
  :solid (fn [ctx i shape]
           (let [hue (int (remap i 0 steps 0 360))
                 rgba (color-cache hue)]
             (-> ctx (fill-style rgba) (ellipse shape) fill)))

  :wireframe (fn [ctx i shape]
               (-> ctx (stroke-style "rgba(255,255,255,0.4)") (ellipse shape) stroke)) })

(defn render [{:keys [theta style] :as world-state}]
  (->
    ctx
    (fill-style :black)
    (fill-rect screen-area)
    (save)
    (translate 400 300))

  (dotimes [i steps]
    (let [offset (* i angle)
          x (* 240 (Math/sin (+ theta offset)))
          y (* 240 (Math/sin (- theta offset)))
          sz (remap (Math/sin (+ theta (* offset 2))) -1 1 30 75)]
      ((draw-func style) ctx i {:x x :y y :rw (* sz 1.5) :rh sz})))

  (restore ctx))

(-> canvas (css :cursor "pointer") (show))
(big-bang
  :tick-rate 50
  :event-target canvas
  :initial-state initial-state
  :on-tick update-state
  :on-mousedown toggle-style
  :to-draw render)