Эскиз пера на холсте Реагент
У меня есть HTML-холст и я хотел бы показать эскиз Quil на нем. Большинство примеров Quil используют defsketch
рисовать на холсте, определенном на статической HTML-странице. Я хотел бы сделать это на холсте в этом компоненте Reagent:
(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]]])
Лучшая документация, которую я нашел для такого рода вещей, здесь, но я не могу понять, как перейти на следующий уровень и применить ее к описанному выше холсту. Фактический код, скажем, для рисования линии на вышеупомянутом холсте был бы отличным.
На самом деле статичный и всегда работает defsketch
было бы хорошо - трудно было бы получить доступ к этому динамическому виду холста.
Если это не может быть сделано, то это было бы полезно узнать, и я буду использовать Processing.js напрямую, предполагая, что это следующая лучшая идея.
2 ответа
Вы должны заглянуть в исходный код Quil и выяснить, как он работает. defsketch
это просто макрос, который создает функцию, которая вызывает quil.sketch/sketch
, который в конечном итоге возвращает js/Processing.Sketch
объект. Это то, что вы можете использовать с quil.sketch/with-sketch
макрос, который просто использует binding
, Это означает, что большинство функций рисования Quil используют quil.sketch/*applet*
вар.
Я предлагаю следующее: Используйте defsketch
как вы обычно делаете в приложении Quil, но используйте :no-start true
вариант. Кроме того, используйте некоторые исправленные :host
ID элемента, который вы будете использовать в своем компоненте реагента, т.е. :canvas#wathever
Пример репо здесь: https://github.com/skrat/quil-reagent-test Запустите с: lein figwheel dev
затем откройте 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")))
Чтобы Quil хорошо играл с Reagent, я думаю, вы хотите sketch
функция, которая (а) создает холст и (б) уничтожает эскиз, когда реагент отключает его. (Если вы не уничтожите эскиз, он будет использовать циклы процессора.)
Я попробовал это сделать - смотрите https://github.com/simon-katz/nomisdraw/blob/for-quil-api-request/src/cljs/nomisdraw/utils/nomis_quil_on_reagent.cljs.
Мой код использует функцию, которая не является частью API Quil, поэтому я поднял проблему в надежде, что она будет решена. (См. https://github.com/quil/quil/issues/186)
Если это сработает, я превращу это в мини-библиотеку.