The cool thing with Klipse is that it is 100% client-side.
It means that you can interact freely with the page where the Klipse snippets are hosted. As an example, you can draw on a canvas. All you need to do is to add in your html a <canvas>
element and refer it from your Klipse snippet.
Boring fillRect
Let’s start with a simple fillRect
manipulation:
(let [canvas (js/document.getElementById "canvas-1")
ctx (.getContext canvas "2d")
width (.-width canvas)
height (.-height canvas)]
(set! (.-fillStyle ctx) "red")
(.clearRect ctx 0 0 width height)
(.fillRect ctx 0 0 width height))
Random color
(let [canvas (js/document.getElementById "canvas-2")
ctx (.getContext canvas "2d")
width (.-width canvas)
height (.-height canvas)
colors ["red" "blue" "green" "yellow" "magenta" "purple" "pink"]]
(set! (.-fillStyle ctx) (rand-nth colors))
(.clearRect ctx 0 0 width height)
(.fillRect ctx 0 0 width height))
Each time you press Ctrl-Enter
inside the snippet, the color is randomly picked.
Wouldn’t it be cool to evaluate the snippet automatically every second or so?
Random color in a loop
Let’s run the same Klipse snippet in a loop - by setting data-loop-msec="1000"
attribute of the DOM element that contains the snippet (look at the page source!):
(let [canvas (js/document.getElementById "canvas-3")
ctx (.getContext canvas "2d")
width (.-width canvas)
height (.-height canvas)
colors ["red" "blue" "green" "yellow" "magenta" "purple" "pink"]]
(set! (.-fillStyle ctx) (rand-nth colors))
(.clearRect ctx 0 0 width height)
(.fillRect ctx 0 0 width height))
Core.async
With core.async
you can do really cool stuff - like having a progress bar:
First, let’s require core.async
(It takes a bit of time…):
(ns my.canvas
(:require [cljs.core.async :refer [go go-loop <! timeout]]))
(let [canvas (js/document.getElementById "canvas-4")
ctx (.getContext canvas "2d")
width (.-width canvas)
height (.-height canvas)]
(.clearRect ctx 0 0 width height)
(set! (.-fillStyle ctx) "green")
(go-loop [percentage 0]
(when (<= percentage 100)
(<! (timeout 200))
(.fillRect ctx 0 (/ height 2) (/ (* width percentage) 100) 10)
(recur (+ percentage 10)))))
It’s a bit tricky to use core.async
inside Klipse because once a snippet is evaluated it runs forever. That might cause a lot of confusion if several versions of the snippet run in parallel.
In our core.async
snippet, we have set data-eval-idle-msec="10000000"
which means that the snippets will run automatically only after 10000 seconds of idleness or when you press Ctrl-Enter
.
That’s it! Enjoy your interactive drawings…