Skip to content

Instantly share code, notes, and snippets.

@Sose
Created May 24, 2021 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sose/a8341b8a33e32c51d8cd3f3ad194bcb7 to your computer and use it in GitHub Desktop.
Save Sose/a8341b8a33e32c51d8cd3f3ad194bcb7 to your computer and use it in GitHub Desktop.
(ns piirtely.views.drawing
(:require
[reagent.core :as reagent]
[re-frame.core :as re-frame]
[piirtely.styles :as styles]
[piirtely.events :as events]
[piirtely.routes :as routes]
[piirtely.subs :as subs]))
(defonce mouse (reagent/atom
{:coords [0 0]
:startcoords [0 0]
:mousedown false}))
(defn clear-canvas! [canvas]
(let [ctx (.getContext canvas "2d")]
(doto ctx
(aset "fillStyle" "white")
(.fillRect 0 0 (.-width canvas) (.-height canvas)))))
(defn draw-line! [ctx shape]
(let [[[x1 y1] [x2 y2]] (:coords shape)]
(doto ctx
(.beginPath)
(.moveTo x1 y1)
(.lineTo x2 y2)
(.stroke))))
(defn draw-shapes! [canvas shapes]
(let [ctx (.getContext canvas "2d")]
(doseq [shape shapes]
(case (:type shape)
:line (draw-line! ctx shape)
(js/alert "invalid shape in draw-shapes!")))))
(defn render-canvas! [canvas shapes]
(clear-canvas! canvas)
(draw-shapes! canvas shapes))
(defn add-line [mouse]
(re-frame/dispatch [::events/add-shape {:type :line
:coords [(:startcoords @mouse)
(:coords @mouse)]}]))
(defn fn-for-tool [tool]
(case tool
:line add-line
(js/alert "no draw fn for" tool)))
(defn mouse-down-handler [mouse e]
(swap! mouse assoc
:startcoords [(.-offsetX e) (.-offsetY e)]
:mousedown true))
(defn mouse-up-handler [mouse _e]
(let [tool (re-frame/subscribe [::subs/selected-tool])]
((fn-for-tool @tool) mouse)
(swap! mouse assoc :mousedown false)))
(defn mouse-move-handler [mouse e]
(swap! mouse assoc :coords [(.-offsetX e) (.-offsetY e)]))
(defn canvas []
(let [ref (atom nil)
shapes (re-frame/subscribe [::subs/active-shapes])]
(reagent/create-class
{:component-did-mount
(fn []
(.addEventListener @ref "mousedown" (partial mouse-down-handler mouse))
(.addEventListener @ref "mouseup" (partial mouse-up-handler mouse))
(.addEventListener @ref "mousemove" (partial mouse-move-handler mouse))
(render-canvas! @ref @shapes))
:component-did-update
(fn []
(render-canvas! @ref @shapes))
:reagent-render
(fn []
[:canvas {:ref #(reset! ref %)
:width 600
:height 400}])})))
(defn tool-button [{:keys [tool text]}]
(let [selected-tool (re-frame/subscribe [::subs/selected-tool])
active? (= @selected-tool tool)]
[:button {:class (styles/toolbutton active?) :onClick #(re-frame/dispatch [::events/set-tool tool])} text]))
(defn draw-buttons []
[:div
[tool-button {:tool :line :text "Line"}]
[tool-button {:tool :rectangle :text "Rectangle"}]])
(defn draw-panel []
[:div
[:p "Hello! Draw stuff"]
[draw-buttons]
[canvas]])
(defmethod routes/panels :draw [] [draw-panel])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment