Hey folks 👋. I've been able to embed a Quil canvas sketch in a reagent component. The sketch doesn't have any animation, rather I want to drive the sketch via state changes from reagent (reframe in my case). Currently when the state of the canvas component changes, the whole sketch is torn down and recreated which results in awful flickering. Is there a way to work around this?
I don’t know where I can say this but, those of us who uses MaterialUI should be ready for a crazy ride when they switch to 5.0. The maintainers decided to make some random breaking change just for fun...
Hi Casey, you may want to prevent the canvas element from being re-rendered. You could remove any reagent atom references in the canvas holder, and use a ref to redraw the quil scene (this could be hooked up to a normal atom with a watcher to get the reactive experience when data changes)
> use a ref to redraw the quil scene How does one do this? (i'm ctrl-f-ing in the quil api docs, but not finding anything)
Hm even the :update
opt doesn't seem to be documented in defsketch
My component looks like:
(defn canvas [state]
(r/create-class
{:component-did-mount
(fn [component]
(let [node (r/dom-node component)
width (/ (.-innerWidth js/window) 2)
height (/ (.-innerHeight js/window) 2)]
(q/sketch
:host node
:draw draw
:setup (init-canvas width height state)
:size [width height]
:middleware [m/fun-mode])))
:render
(fn [] [:div])}))
And the holder looks like:
(defn canvas-holder
[(let [sketch-state @(rf/subscribe [:query-sketch-state])]
[:div
[do-stuff-button]
[(canvas sketch-state)]])])
ah i mean a react ref to reference the element, think it would look like this:
(defonce my-canvas (atom nil))
(defn ui []
[:div
[:canvas {:ref (fn [el] (reset! my-canvas el))}]])
then you could draw whenever another atom changed
(defonce color (atom "red"))
(add-watch color :watcher
(fn [key atom old-state new-state]
(when @my-canvas
(let [ctx (.getContext @my-canvas "2d")]
(.beginPath ctx)
(.rect ctx 10 10 20 20)
(set! ctx -fillStyle @color)
(.fill ctx)))))
(replace with quill drawing stuff)Ah interesting add-watch is a clojure core thing, I've never used it before
now that I look at https://github.com/yogthos/quil-reagent-demo/blob/master/src/circles_demo/core.cljs though.. maybe you're meant to set up a quil :update
function, then never actually trigger a re-render in the holder?
Yea, I based mine off that demo.
I wish there was a pure functional 2d canvas library heh