Some fun generating wallpapers with the HTML Canvas & Clojurescript
(defn draw-pixel! [canvas x y color]
(let [ctx (.getContext canvas "2d")
scale 2]
(set! (.-fillStyle ctx) color)
(.fillRect ctx (* scale x) (* scale y) scale scale)))
When we want to erase the canvas
(defn reset-canvas! [canvas]
(let [ctx (.getContext canvas "2d")]
(set! (.-fillStyle ctx) "white")
(.fillRect ctx 0 0 (.-width canvas) (.-height canvas))))
The algorithm is controlled by the geometry of a square:
its x-position named a its y-position named b the side of the square named side
(defn draw-bw-wallpaper! [canvas a b side] (let [points 200] (dotimes [i points] (dotimes [j points] (let [x (+ a (* i (/ side points))) y (+ b (* j (/ side points))) c (int (+ (* x x) (* y y)))] (when (even? c) (draw-pixel! canvas i j "black"))))))) (draw-bw-wallpaper! canvas 5 5 9)
The cool thing about this algorithm is that when we modify the side of the square, we get a completely different pattern:
(draw-bw-wallpaper! canvas 5 5 100)
(defn draw-color-wallpaper! [canvas a b side]
(let [points 200]
(dotimes [i points]
(dotimes [j points]
(let [x (+ a (* i (/ side points)))
y (+ b (* j (/ side points)))
c (int (+ (* x x) (* y y)))
color (case (mod c 4)
0 "red"
1 "green"
2 "blue"
"white")]
(draw-pixel! canvas i j color))))))
(draw-color-wallpaper! canvas 5 7 101)
Again, when we modify the side of the square, we get a completely different pattern:
(draw-color-wallpaper! canvas 5 7 57)
Someone in reddit suggested looping over the value of side
in order to watch all the generated wallpapers like a movie.
Here is the result:
(defonce interval (atom nil))
(defonce side (atom 0))
(def delta 0.5)
(defn step [canvas container]
(set! (.-innerHTML container) (str "side: " @side) )
(reset-canvas! canvas)
(draw-color-wallpaper! canvas 5 5 (swap! side + delta)))
(.clearInterval js/window @interval)
(reset! side 0)
(reset! interval (.setInterval js/window step 500 canvas js/klipse-container))