Эскиз пера на холсте Реагент

У меня есть 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)

Если это сработает, я превращу это в мини-библиотеку.

Другие вопросы по тегам