mirror of
https://github.com/penpot/penpot.git
synced 2025-02-11 01:28:30 -05:00
Remodeled the mouse position <-> canvas coords matching.
This commit is contained in:
parent
f8a6342b98
commit
beda689dfc
3 changed files with 168 additions and 149 deletions
|
@ -2,7 +2,7 @@
|
||||||
(:require [beicon.core :as rx]
|
(:require [beicon.core :as rx]
|
||||||
[cats.labs.lens :as l]
|
[cats.labs.lens :as l]
|
||||||
[uxbox.rstore :as rs]
|
[uxbox.rstore :as rs]
|
||||||
[uxbox.state :as s]
|
[uxbox.state :as st]
|
||||||
[uxbox.data.projects :as dp]
|
[uxbox.data.projects :as dp]
|
||||||
[uxbox.data.workspace :as dw]
|
[uxbox.data.workspace :as dw]
|
||||||
[uxbox.util.lens :as ul]
|
[uxbox.util.lens :as ul]
|
||||||
|
@ -16,32 +16,20 @@
|
||||||
|
|
||||||
(def ^:static project-state
|
(def ^:static project-state
|
||||||
(as-> (ul/dep-in [:projects-by-id] [:workspace :project]) $
|
(as-> (ul/dep-in [:projects-by-id] [:workspace :project]) $
|
||||||
(l/focus-atom $ s/state)))
|
(l/focus-atom $ st/state)))
|
||||||
|
|
||||||
(def ^:static page-state
|
(def ^:static page-state
|
||||||
(as-> (ul/dep-in [:pages-by-id] [:workspace :page]) $
|
(as-> (ul/dep-in [:pages-by-id] [:workspace :page]) $
|
||||||
(l/focus-atom $ s/state)))
|
(l/focus-atom $ st/state)))
|
||||||
|
|
||||||
(def ^:static pages-state
|
(def ^:static pages-state
|
||||||
(as-> (ul/getter #(let [pid (get-in % [:workspace :project])]
|
(as-> (ul/getter #(let [pid (get-in % [:workspace :project])]
|
||||||
(dp/project-pages % pid))) $
|
(dp/project-pages % pid))) $
|
||||||
(l/focus-atom $ s/state)))
|
(l/focus-atom $ st/state)))
|
||||||
|
|
||||||
(def ^:static shapes-state
|
|
||||||
(as-> (ul/getter (fn [state]
|
|
||||||
(let [pid (get-in state [:workspace :page])
|
|
||||||
shapes (->> (vals (:shapes-by-id state))
|
|
||||||
(filter #(= (:page %) pid)))]
|
|
||||||
(into [] shapes)))) $
|
|
||||||
(l/focus-atom $ s/state)))
|
|
||||||
|
|
||||||
(def ^:static workspace-state
|
(def ^:static workspace-state
|
||||||
(as-> (l/in [:workspace]) $
|
(as-> (l/in [:workspace]) $
|
||||||
(l/focus-atom $ s/state)))
|
(l/focus-atom $ st/state)))
|
||||||
|
|
||||||
(def ^:static selected-state
|
|
||||||
(as-> (l/in [:workspace :selected]) $
|
|
||||||
(l/focus-atom $ s/state)))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Scroll Stream
|
;; Scroll Stream
|
||||||
|
@ -68,12 +56,14 @@
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defonce shapes-dragging? (atom false))
|
(defonce shapes-dragging? (atom false))
|
||||||
|
|
||||||
(defonce selrect-dragging? (atom false))
|
(defonce selrect-dragging? (atom false))
|
||||||
(defonce selrect-pos (atom nil))
|
(defonce selrect-pos (atom nil))
|
||||||
|
|
||||||
(defonce mouse-b (rx/bus))
|
(defonce mouse-b (rx/bus))
|
||||||
(defonce mouse-s (rx/dedupe mouse-b))
|
(defonce mouse-s
|
||||||
|
(->> mouse-b
|
||||||
|
(rx/filter #(= (:id %) (:id @page-state)))
|
||||||
|
(rx/map :coords)))
|
||||||
|
|
||||||
;; Deltas
|
;; Deltas
|
||||||
|
|
||||||
|
@ -94,8 +84,11 @@
|
||||||
(as-> mouse-delta-s $
|
(as-> mouse-delta-s $
|
||||||
(rx/filter #(deref shapes-dragging?) $)
|
(rx/filter #(deref shapes-dragging?) $)
|
||||||
(rx/on-value $ (fn [delta]
|
(rx/on-value $ (fn [delta]
|
||||||
(doseq [sid @selected-state]
|
(let [pageid (get-in @st/state [:workspace :page])
|
||||||
(rs/emit! (dw/move-shape sid delta)))))))
|
selected (get-in @st/state [:workspace :selected])
|
||||||
|
page (get-in @st/state [:pages-by-id pageid])]
|
||||||
|
(doseq [sid (filter selected (:shapes page))]
|
||||||
|
(rs/emit! (dw/move-shape sid delta))))))))
|
||||||
|
|
||||||
(defn selrect->rect
|
(defn selrect->rect
|
||||||
[data]
|
[data]
|
||||||
|
@ -140,38 +133,12 @@
|
||||||
|
|
||||||
;; Materialized views
|
;; Materialized views
|
||||||
|
|
||||||
(defonce mouse-position (rx/to-atom (rx/sample 50 mouse-s)))
|
(defonce mouse-position
|
||||||
|
(->> mouse-s
|
||||||
|
(rx/sample 50)
|
||||||
|
(rx/to-atom)))
|
||||||
|
|
||||||
(defn- mouse-mixin-did-mount
|
(defonce bounding-rect (atom {}))
|
||||||
[own]
|
|
||||||
(letfn [(on-mousemove [event]
|
|
||||||
(let [canvas (util/get-ref-dom own "canvas")
|
|
||||||
brect (.getBoundingClientRect canvas)
|
|
||||||
offset-x (.-left brect)
|
|
||||||
offset-y (.-top brect)
|
|
||||||
x (.-clientX event)
|
|
||||||
y (.-clientY event)]
|
|
||||||
(rx/push! mouse-b [(- x offset-x)
|
|
||||||
(- y offset-y)])))]
|
|
||||||
(let [key (events/listen js/document EventType.MOUSEMOVE on-mousemove)]
|
|
||||||
(js/console.log "mouse-mixin-did-mount" key)
|
|
||||||
(assoc own ::eventkey key))))
|
|
||||||
|
|
||||||
(defn- mouse-mixin-will-unmount
|
|
||||||
[own]
|
|
||||||
(let [key (::eventkey own)]
|
|
||||||
(events/unlistenByKey key)
|
|
||||||
(dissoc own ::eventkey)))
|
|
||||||
|
|
||||||
(defn- mouse-mixin-transfer-state
|
|
||||||
[old-own own]
|
|
||||||
(let [key (::eventkey old-own)]
|
|
||||||
(assoc own ::eventkey key)))
|
|
||||||
|
|
||||||
(def ^:static mouse-mixin
|
|
||||||
{:did-mount mouse-mixin-did-mount
|
|
||||||
:will-unmount mouse-mixin-will-unmount
|
|
||||||
:transfer-state mouse-mixin-transfer-state})
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Constants
|
;; Constants
|
||||||
|
|
|
@ -2,10 +2,13 @@
|
||||||
(:require [sablono.core :as html :refer-macros [html]]
|
(:require [sablono.core :as html :refer-macros [html]]
|
||||||
[rum.core :as rum]
|
[rum.core :as rum]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
|
[cats.labs.lens :as l]
|
||||||
|
[goog.events :as events]
|
||||||
[uxbox.router :as r]
|
[uxbox.router :as r]
|
||||||
[uxbox.rstore :as rs]
|
[uxbox.rstore :as rs]
|
||||||
[uxbox.state :as s]
|
[uxbox.state :as st]
|
||||||
[uxbox.shapes :as shapes]
|
[uxbox.shapes :as shapes]
|
||||||
|
[uxbox.util.lens :as ul]
|
||||||
[uxbox.library.icons :as _icons]
|
[uxbox.library.icons :as _icons]
|
||||||
[uxbox.data.projects :as dp]
|
[uxbox.data.projects :as dp]
|
||||||
[uxbox.data.workspace :as dw]
|
[uxbox.data.workspace :as dw]
|
||||||
|
@ -14,7 +17,17 @@
|
||||||
[uxbox.ui.util :as util]
|
[uxbox.ui.util :as util]
|
||||||
[uxbox.ui.workspace.base :as wb]
|
[uxbox.ui.workspace.base :as wb]
|
||||||
[uxbox.ui.workspace.grid :refer (grid)]
|
[uxbox.ui.workspace.grid :refer (grid)]
|
||||||
[uxbox.ui.workspace.toolboxes :as toolboxes]))
|
[uxbox.ui.workspace.options :refer (element-opts)]
|
||||||
|
[uxbox.ui.workspace.toolboxes :as toolboxes])
|
||||||
|
(:import goog.events.EventType))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Lenses
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(def ^:static shapes-by-id
|
||||||
|
(as-> (l/key :shapes-by-id) $
|
||||||
|
(l/focus-atom $ st/state)))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Background
|
;; Background
|
||||||
|
@ -33,7 +46,28 @@
|
||||||
:mixins [mx/static]}))
|
:mixins [mx/static]}))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Shape
|
;; Select Rect
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn selrect-render
|
||||||
|
[own]
|
||||||
|
(when-let [data (rum/react wb/selrect-pos)]
|
||||||
|
(let [{:keys [x y width height]} (wb/selrect->rect data)]
|
||||||
|
(html
|
||||||
|
[:rect.selection-rect
|
||||||
|
{:x x
|
||||||
|
:y y
|
||||||
|
:width width
|
||||||
|
:height height}]))))
|
||||||
|
|
||||||
|
(def ^:static selrect
|
||||||
|
(util/component
|
||||||
|
{:render selrect-render
|
||||||
|
:name "selrect"
|
||||||
|
:mixins [mx/static rum/reactive]}))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Selected shapes group
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private
|
||||||
|
@ -48,10 +82,56 @@
|
||||||
:fill "lavender"
|
:fill "lavender"
|
||||||
:stroke "gray"})
|
:stroke "gray"})
|
||||||
|
|
||||||
|
(defn- selected-shapes-render
|
||||||
|
[own shapes selected]
|
||||||
|
(let [local (:rum/local own)
|
||||||
|
x (apply min (map :x shapes))
|
||||||
|
y (apply min (map :y shapes))
|
||||||
|
x' (apply max (map (fn [{:keys [x width]}] (+ x width)) shapes))
|
||||||
|
y' (apply max (map (fn [{:keys [y height]}] (+ y height)) shapes))
|
||||||
|
width (- x' x)
|
||||||
|
height (- y' y)]
|
||||||
|
(letfn [(on-mouse-down [event]
|
||||||
|
(dom/stop-propagation event)
|
||||||
|
(swap! local assoc :init-coords [x y])
|
||||||
|
(reset! wb/shapes-dragging? true))
|
||||||
|
(on-mouse-up [event]
|
||||||
|
(dom/stop-propagation event)
|
||||||
|
(reset! wb/shapes-dragging? false))]
|
||||||
|
(html
|
||||||
|
[:g {:class "shape selected"
|
||||||
|
:on-mouse-down on-mouse-down
|
||||||
|
:on-mouse-up on-mouse-up}
|
||||||
|
(for [item shapes]
|
||||||
|
(shapes/render item))
|
||||||
|
[:g.controls
|
||||||
|
[:rect {:x x :y y :width width :height height
|
||||||
|
:style {:stroke "black" :fill "transparent"
|
||||||
|
:stroke-opacity "0.5"}}]
|
||||||
|
[:circle.top-left (merge default-selection-props
|
||||||
|
{:cx x :cy y})]
|
||||||
|
[:circle.top-right (merge default-selection-props
|
||||||
|
{:cx (+ x width) :cy y})]
|
||||||
|
[:circle.bottom-left (merge default-selection-props
|
||||||
|
{:cx x :cy (+ y height)})]
|
||||||
|
[:circle.bottom-right (merge default-selection-props
|
||||||
|
{:cx (+ x width) :cy (+ y height)})]]]))))
|
||||||
|
|
||||||
|
(def selected-shapes
|
||||||
|
(util/component
|
||||||
|
{:render selected-shapes-render
|
||||||
|
:name "selected-shapes"
|
||||||
|
:mixins [mx/static rum/reactive (mx/local {})]}))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Shape
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn shape-render
|
(defn shape-render
|
||||||
[own {:keys [id x y width height] :as shape}]
|
[own shape selected]
|
||||||
(let [selected (rum/react wb/selected-state)
|
(let [{:keys [id x y width height] :as shape} shape
|
||||||
selected? (contains? selected id)]
|
selected? (contains? selected id)]
|
||||||
|
(println "shape-render" id)
|
||||||
(letfn [(on-mouse-down [event]
|
(letfn [(on-mouse-down [event]
|
||||||
(let [local (:rum/local own)]
|
(let [local (:rum/local own)]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
|
@ -94,88 +174,55 @@
|
||||||
(util/component
|
(util/component
|
||||||
{:render shape-render
|
{:render shape-render
|
||||||
:name "shape"
|
:name "shape"
|
||||||
:mixins [mx/static rum/reactive (mx/local {})]}))
|
:mixins [mx/static (mx/local {})]}))
|
||||||
|
|
||||||
(defn- selected-shapes-render
|
|
||||||
[own shapes]
|
|
||||||
(let [selected (rum/react wb/selected-state)
|
|
||||||
local (:rum/local own)
|
|
||||||
x (apply min (map :x shapes))
|
|
||||||
y (apply min (map :y shapes))
|
|
||||||
x' (apply max (map (fn [{:keys [x width]}] (+ x width)) shapes))
|
|
||||||
y' (apply max (map (fn [{:keys [y height]}] (+ y height)) shapes))
|
|
||||||
width (- x' x)
|
|
||||||
height (- y' y)]
|
|
||||||
(letfn [(on-mouse-down [event]
|
|
||||||
(dom/stop-propagation event)
|
|
||||||
(swap! local assoc :init-coords [x y])
|
|
||||||
(reset! wb/shapes-dragging? true))
|
|
||||||
(on-mouse-up [event]
|
|
||||||
(dom/stop-propagation event)
|
|
||||||
(reset! wb/shapes-dragging? false))]
|
|
||||||
(html
|
|
||||||
[:g {:class "shape selected"
|
|
||||||
:on-mouse-down on-mouse-down
|
|
||||||
:on-mouse-up on-mouse-up}
|
|
||||||
(for [item shapes]
|
|
||||||
(shapes/render item))
|
|
||||||
[:g.controls
|
|
||||||
[:rect {:x x :y y :width width :height height
|
|
||||||
:style {:stroke "black" :fill "transparent"
|
|
||||||
:stroke-opacity "0.5"}}]
|
|
||||||
[:circle.top-left (merge default-selection-props
|
|
||||||
{:cx x :cy y})]
|
|
||||||
[:circle.top-right (merge default-selection-props
|
|
||||||
{:cx (+ x width) :cy y})]
|
|
||||||
[:circle.bottom-left (merge default-selection-props
|
|
||||||
{:cx x :cy (+ y height)})]
|
|
||||||
[:circle.bottom-right (merge default-selection-props
|
|
||||||
{:cx (+ x width) :cy (+ y height)})]]]))))
|
|
||||||
|
|
||||||
(def selected-shapes
|
|
||||||
(util/component
|
|
||||||
{:render selected-shapes-render
|
|
||||||
:name "selected-shapes"
|
|
||||||
:mixins [mx/static rum/reactive (mx/local {})]}))
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; Select Rect
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
(defn selrect-render
|
|
||||||
[own]
|
|
||||||
(when-let [data (rum/react wb/selrect-pos)]
|
|
||||||
(let [{:keys [x y width height]} (wb/selrect->rect data)]
|
|
||||||
(html
|
|
||||||
[:rect.selection-rect
|
|
||||||
{:x x
|
|
||||||
:y y
|
|
||||||
:width width
|
|
||||||
:height height}]))))
|
|
||||||
|
|
||||||
(def ^:static selrect
|
|
||||||
(util/component
|
|
||||||
{:render selrect-render
|
|
||||||
:name "selrect"
|
|
||||||
:mixins [mx/static rum/reactive]}))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Canvas
|
;; Canvas
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn canvas-render
|
(defn- canvas-did-mount
|
||||||
[own]
|
[own]
|
||||||
(let [page (rum/react wb/page-state)
|
(letfn [(on-mousemove [event page [offset-x offset-y]]
|
||||||
shapes (rum/react wb/shapes-state)
|
(let [x (.-clientX event)
|
||||||
selected-ids (rum/react wb/selected-state)
|
y (.-clientY event)
|
||||||
selected (filter (comp selected-ids :id) shapes)
|
event {:id (:id page)
|
||||||
nonselected (filter (comp not selected-ids :id) shapes)
|
:coords [(- x offset-x)
|
||||||
page-width (:width page)
|
(- y offset-y)]}]
|
||||||
page-height (:height page)]
|
(rx/push! wb/mouse-b event)))]
|
||||||
|
(let [[page] (:rum/props own)
|
||||||
|
canvas (util/get-ref-dom own (str "canvas" (:id page)))
|
||||||
|
brect (.getBoundingClientRect canvas)
|
||||||
|
brect [(.-left brect) (.-top brect)]
|
||||||
|
key (events/listen js/document EventType.MOUSEMOVE
|
||||||
|
#(on-mousemove % page brect))]
|
||||||
|
(swap! wb/bounding-rect assoc (:id page) brect)
|
||||||
|
(assoc own ::eventkey key))))
|
||||||
|
|
||||||
|
(defn- canvas-will-unmount
|
||||||
|
[own]
|
||||||
|
(let [key (::eventkey own)
|
||||||
|
[page] (:rum/props own)]
|
||||||
|
(swap! wb/bounding-rect dissoc (:id page))
|
||||||
|
(events/unlistenByKey key)
|
||||||
|
(dissoc own ::eventkey)))
|
||||||
|
|
||||||
|
(defn- canvas-transfer-state
|
||||||
|
[old-own own]
|
||||||
|
(let [key (::eventkey old-own)]
|
||||||
|
(assoc own ::eventkey key)))
|
||||||
|
|
||||||
|
(defn- canvas-render
|
||||||
|
[own {:keys [width height id] :as page}]
|
||||||
|
(println "canvas-render" id)
|
||||||
|
(let [workspace (rum/react wb/workspace-state)
|
||||||
|
shapes-by-id (rum/react shapes-by-id)
|
||||||
|
workspace-selected (:selected workspace)
|
||||||
|
shapes (map #(get shapes-by-id %) (:shapes page))
|
||||||
|
shapes-selected (filter (comp workspace-selected :id) shapes)
|
||||||
|
shapes-notselected (filter (comp not workspace-selected :id) shapes)]
|
||||||
(letfn [(on-mouse-down [event]
|
(letfn [(on-mouse-down [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(when-not (empty? selected-ids)
|
(when-not (empty? shapes-selected)
|
||||||
(rs/emit! (dw/deselect-all)))
|
(rs/emit! (dw/deselect-all)))
|
||||||
(reset! wb/selrect-dragging? true))
|
(reset! wb/selrect-dragging? true))
|
||||||
(on-mouse-up [event]
|
(on-mouse-up [event]
|
||||||
|
@ -183,30 +230,34 @@
|
||||||
(reset! wb/shapes-dragging? false)
|
(reset! wb/shapes-dragging? false)
|
||||||
(reset! wb/selrect-dragging? false))]
|
(reset! wb/selrect-dragging? false))]
|
||||||
(html
|
(html
|
||||||
[:svg.page-canvas {:x wb/document-start-x
|
[:svg#page-canvas.page-canvas {:x wb/document-start-x
|
||||||
:y wb/document-start-y
|
:y wb/document-start-y
|
||||||
:ref "canvas"
|
:ref (str "canvas" id)
|
||||||
:width page-width
|
:width width
|
||||||
:height page-height
|
:height height
|
||||||
:on-mouse-down on-mouse-down
|
:on-mouse-down on-mouse-down
|
||||||
:on-mouse-up on-mouse-up}
|
:on-mouse-up on-mouse-up}
|
||||||
(background)
|
(background)
|
||||||
(grid 1)
|
(grid 1)
|
||||||
[:svg.page-layout {}
|
[:svg.page-layout {}
|
||||||
(for [item nonselected]
|
(for [item shapes-notselected
|
||||||
(rum/with-key (shape item) (str (:id item))))
|
:let [component (shape item workspace-selected)]]
|
||||||
|
(rum/with-key component (str (:id item))))
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
(= (count selected) 1)
|
(= (count shapes-selected) 1)
|
||||||
(shape (first selected))
|
(let [item (first shapes-selected)]
|
||||||
|
(shape item workspace-selected))
|
||||||
(> (count selected) 1)
|
|
||||||
(selected-shapes selected))
|
|
||||||
|
|
||||||
|
(> (count shapes-selected) 1)
|
||||||
|
(selected-shapes shapes-selected))
|
||||||
(selrect)]]))))
|
(selrect)]]))))
|
||||||
|
|
||||||
(def canvas
|
(def canvas
|
||||||
(util/component
|
(util/component
|
||||||
{:render canvas-render
|
{:render canvas-render
|
||||||
|
:did-mount canvas-did-mount
|
||||||
|
:will-unmount canvas-will-unmount
|
||||||
|
:transfer-state canvas-transfer-state
|
||||||
:name "canvas"
|
:name "canvas"
|
||||||
:mixins [rum/reactive wb/mouse-mixin]}))
|
:mixins [mx/static rum/reactive]}))
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
(defn viewport-render
|
(defn viewport-render
|
||||||
[own]
|
[own]
|
||||||
(let [workspace (rum/react wb/workspace-state)
|
(let [workspace (rum/react wb/workspace-state)
|
||||||
|
page (rum/react wb/page-state)
|
||||||
drawing? (:drawing workspace)
|
drawing? (:drawing workspace)
|
||||||
zoom 1]
|
zoom 1]
|
||||||
(html
|
(html
|
||||||
|
@ -41,8 +42,8 @@
|
||||||
:on-click #(on-click % workspace)
|
:on-click #(on-click % workspace)
|
||||||
:class (when drawing? "drawing")}
|
:class (when drawing? "drawing")}
|
||||||
[:g.zoom {:transform (str "scale(" zoom ", " zoom ")")}
|
[:g.zoom {:transform (str "scale(" zoom ", " zoom ")")}
|
||||||
(canvas)
|
(if page
|
||||||
#_(grid zoom)]])))
|
(canvas page))]])))
|
||||||
|
|
||||||
(def viewport
|
(def viewport
|
||||||
(util/component
|
(util/component
|
||||||
|
|
Loading…
Add table
Reference in a new issue