I have an html canvas and would like to display a Quil sketch on it. Most of the Quil examples use defsketch
to draw onto a canvas defined on a static html page. I would like to do it onto the canvas within this Reagent component:
(defn my-component []
(reagent/create-class
{:component-did-mount (fn [this]
(let [canvas (reagent/dom-node this)
width (.-width canvas)
height (.-height canvas)]
(u/log (str "On canvas with width, height: " width " " height))))
:component-will-mount #(u/log "component-will-mount")
:display-name "my-component"
:reagent-render (fn [] [:canvas {:width 400}])}))
(defn graph-panel []
[v-box
:gap "1em"
:children [[my-component]]])
The best documentation I've found for doing this sort of thing is here, but I can't quite work out how to go to the next level and apply it to the canvas above. Actual code for say drawing a line on the above canvas would be great.
In fact a static and always running defsketch
would be fine - the difficulty would be having it access this dynamic kind of canvas.
If it can't be done then that would be nice to know, and I'll use Processing.js directly, assuming that's the next best idea.
You should look into Quil's source code and find out how it works. defsketch
is just a macro that creates a function, that calls to quil.sketch/sketch
, which eventually returns js/Processing.Sketch
object. That's the thing you can use with quil.sketch/with-sketch
macro, that just uses binding
. That means, most of Quil's drawing functions use the quil.sketch/*applet*
var.
I suggest the following: Use defsketch
as you would normally do in Quil app, but use :no-start true
option. Also, use some fixed :host
element ID, that you will use in your reagent component, ie. :canvas#wathever
Example repo here: https://github.com/skrat/quil-reagent-test
Run with: lein figwheel dev
then open http://localhost:3449/
(ns ^:figwheel-always kil.core
(:require [reagent.core :as reagent :refer [atom]]
[quil.core :as q :include-macros true]
[quil.middleware :as m]))
(enable-console-print!)
(def w 400)
(def h 400)
(defn setup []
{:t 1})
(defn update [state]
(update-in state [:t] inc))
(defn draw [state]
(q/background 255)
(q/fill 0)
(q/ellipse (rem (:t state) w) 46 55 55))
(q/defsketch foo
:setup setup
:update update
:draw draw
:host "foo"
:no-start true
:middleware [m/fun-mode]
:size [w h])
(defn hello-world []
(reagent/create-class
{:reagent-render (fn [] [:canvas#foo {:width w :height h}])
:component-did-mount foo}))
(reagent/render-component
[hello-world]
(. js/document (getElementById "app")))