mirror of
https://github.com/penpot/penpot.git
synced 2025-03-11 23:31:21 -05:00
🎉 Reimplement canvas as svg (instead of g+rect).
This commit is contained in:
parent
63a339dd31
commit
86ba4fd083
12 changed files with 442 additions and 152 deletions
|
@ -960,28 +960,107 @@
|
||||||
(let [shape (get-in state [:workspace-data :shapes-by-id id])]
|
(let [shape (get-in state [:workspace-data :shapes-by-id id])]
|
||||||
(assoc shape :id (uuid/next))))
|
(assoc shape :id (uuid/next))))
|
||||||
|
|
||||||
|
;; (defn duplicate-shapes
|
||||||
|
;; [ids]
|
||||||
|
;; (us/verify (s/every ::us/uuid) ids)
|
||||||
|
;; (ptk/reify ::duplicate-selected
|
||||||
|
;; ptk/UpdateEvent
|
||||||
|
;; (update [_ state]
|
||||||
|
;; (let [duplicate #(-> (get-in state [:workspace-data :shapes-by-id %])
|
||||||
|
;; (assoc :id (uuid/next)))]
|
||||||
|
;; (reduce
|
||||||
|
|
||||||
|
;; shapes (map duplicate selected)
|
||||||
|
;; sid (:session-id state)
|
||||||
|
;; changes (mapv (fn [shape]
|
||||||
|
;; {:type :add-shape
|
||||||
|
;; :id (:id shape)
|
||||||
|
;; :shape shape
|
||||||
|
;; :session-id sid})
|
||||||
|
;; shapes)
|
||||||
|
;; uchanges (mapv (fn [shape]
|
||||||
|
;; {:type :del-shape
|
||||||
|
;; :id (:id shape)
|
||||||
|
;; :session-id sid})
|
||||||
|
;; shapes)]
|
||||||
|
;; (rx/merge
|
||||||
|
|
||||||
|
(defn duplicate-shapes
|
||||||
|
[shapes]
|
||||||
|
(ptk/reify ::duplicate-shapes
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(reduce (fn [state {:keys [id] :as shape}]
|
||||||
|
(-> state
|
||||||
|
(assoc-in [:workspace-data :shapes-by-id id] shape)
|
||||||
|
(update-in [:workspace-data :shapes] (fnil conj []) id)))
|
||||||
|
state
|
||||||
|
shapes))
|
||||||
|
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state stream]
|
||||||
|
(let [rchanges (mapv (fn [shape]
|
||||||
|
{:type :add-shape
|
||||||
|
:id (:id shape)
|
||||||
|
:shape shape
|
||||||
|
:session-id (:session-id state)})
|
||||||
|
shapes)
|
||||||
|
uchanges (mapv (fn [shape]
|
||||||
|
{:type :del-shape
|
||||||
|
:id (:id shape)
|
||||||
|
:session-id (:session-id state)})
|
||||||
|
shapes)]
|
||||||
|
(rx/of (commit-changes rchanges uchanges))))))
|
||||||
|
|
||||||
|
(defn duplicate-canvas
|
||||||
|
[{:keys [id] :as canvas} prev-id]
|
||||||
|
(ptk/reify ::duplicate-canvas
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(-> state
|
||||||
|
(assoc-in [:workspace-data :shapes-by-id id] canvas)
|
||||||
|
(update-in [:workspace-data :canvas] (fnil conj []) id)))
|
||||||
|
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state stream]
|
||||||
|
(let [shapes (->> (vals (get-in state [:workspace-data :shapes-by-id]))
|
||||||
|
(filter #(= (:canvas %) prev-id))
|
||||||
|
(map #(assoc % :id (uuid/next)))
|
||||||
|
(map #(assoc % :canvas id)))
|
||||||
|
|
||||||
|
rchange {:type :add-canvas
|
||||||
|
:id id
|
||||||
|
:shape canvas
|
||||||
|
:session-id (:session-id state)}
|
||||||
|
uchange {:type :del-canvas
|
||||||
|
:id id
|
||||||
|
:session-id (:session-id state)}]
|
||||||
|
(rx/of (duplicate-shapes shapes)
|
||||||
|
(commit-changes [rchange] [uchange]))))))
|
||||||
|
|
||||||
|
|
||||||
(def duplicate-selected
|
(def duplicate-selected
|
||||||
(ptk/reify ::duplicate-selected
|
(ptk/reify ::duplicate-selected
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [selected (get-in state [:workspace-local :selected])
|
(let [selected (get-in state [:workspace-local :selected])
|
||||||
duplicate (partial impl-duplicate-shape state)
|
dup #(-> (get-in state [:workspace-data :shapes-by-id %])
|
||||||
shapes (map duplicate selected)
|
(assoc :id (uuid/next)))
|
||||||
sid (:session-id state)
|
shapes (map dup selected)
|
||||||
changes (mapv (fn [shape]
|
shape? #(not= (:type %) :canvas)]
|
||||||
{:type :add-shape
|
(cond
|
||||||
:id (:id shape)
|
(and (= (count shapes) 1)
|
||||||
:shape shape
|
(= (:type (first shapes)) :canvas))
|
||||||
:session-id sid})
|
(rx/of (duplicate-canvas (first shapes) (first selected)))
|
||||||
shapes)
|
|
||||||
uchanges (mapv (fn [shape]
|
(and (pos? (count shapes))
|
||||||
{:type :del-shape
|
(every? shape? shapes))
|
||||||
:id (:id shape)
|
(rx/of (duplicate-shapes shapes))
|
||||||
:session-id sid})
|
|
||||||
shapes)]
|
:else
|
||||||
(rx/merge
|
(rx/empty))))))
|
||||||
(rx/from (map (fn [s] #(impl-assoc-shape % s)) shapes))
|
|
||||||
(rx/of (commit-changes changes uchanges)))))))
|
|
||||||
|
|
||||||
;; --- Toggle shape's selection status (selected or deselected)
|
;; --- Toggle shape's selection status (selected or deselected)
|
||||||
|
|
||||||
|
@ -1080,8 +1159,6 @@
|
||||||
;; --- Shape Movement (using keyboard shorcuts)
|
;; --- Shape Movement (using keyboard shorcuts)
|
||||||
|
|
||||||
(declare initial-selection-align)
|
(declare initial-selection-align)
|
||||||
(declare apply-temporal-displacement-in-bulk)
|
|
||||||
(declare materialize-temporal-modifier-in-bulk)
|
|
||||||
|
|
||||||
(defn- get-displacement-with-grid
|
(defn- get-displacement-with-grid
|
||||||
"Retrieve the correct displacement delta point for the
|
"Retrieve the correct displacement delta point for the
|
||||||
|
@ -1109,6 +1186,9 @@
|
||||||
|
|
||||||
(s/def ::direction #{:up :down :right :left})
|
(s/def ::direction #{:up :down :right :left})
|
||||||
|
|
||||||
|
(declare apply-displacement-in-bulk)
|
||||||
|
(declare materialize-displacement-in-bulk)
|
||||||
|
|
||||||
(defn move-selected
|
(defn move-selected
|
||||||
[direction align?]
|
[direction align?]
|
||||||
(us/verify ::direction direction)
|
(us/verify ::direction direction)
|
||||||
|
@ -1124,8 +1204,8 @@
|
||||||
displacement (if align?
|
displacement (if align?
|
||||||
(get-displacement-with-grid shape direction options)
|
(get-displacement-with-grid shape direction options)
|
||||||
(get-displacement shape direction))]
|
(get-displacement shape direction))]
|
||||||
(rx/of (apply-temporal-displacement-in-bulk selected displacement)
|
(rx/of (apply-displacement-in-bulk selected displacement)
|
||||||
(materialize-temporal-modifier-in-bulk selected))))))
|
(materialize-displacement-in-bulk selected))))))
|
||||||
|
|
||||||
;; --- Delete Selected
|
;; --- Delete Selected
|
||||||
|
|
||||||
|
@ -1289,34 +1369,10 @@
|
||||||
(:y1 sshape))]
|
(:y1 sshape))]
|
||||||
(->> (uwrk/align-point point)
|
(->> (uwrk/align-point point)
|
||||||
(rx/map (fn [{:keys [x y] :as pt}]
|
(rx/map (fn [{:keys [x y] :as pt}]
|
||||||
(apply-temporal-displacement-in-bulk ids (gpt/subtract pt point)))))))))
|
(apply-displacement-in-bulk ids (gpt/subtract pt point)))))))))
|
||||||
|
|
||||||
;; --- Temportal displacement for Shape / Selection
|
;; --- Temportal displacement for Shape / Selection
|
||||||
|
|
||||||
(defn assoc-temporal-modifier-in-bulk
|
|
||||||
[ids xfmt]
|
|
||||||
(us/verify ::set-of-uuid ids)
|
|
||||||
(us/verify gmt/matrix? xfmt)
|
|
||||||
(ptk/reify ::assoc-temporal-modifier-in-bulk
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(reduce #(assoc-in %1 [:workspace-data :shapes-by-id %2 :modifier-mtx] xfmt) state ids))))
|
|
||||||
|
|
||||||
(defn apply-temporal-displacement-in-bulk
|
|
||||||
"Apply the same displacement delta to all shapes identified by the
|
|
||||||
set if ids."
|
|
||||||
[ids delta]
|
|
||||||
(us/verify ::set-of-uuid ids)
|
|
||||||
(us/verify gpt/point? delta)
|
|
||||||
(letfn [(process-shape [state id]
|
|
||||||
(let [prev (get-in state [:workspace-data :shapes-by-id id :modifier-mtx] (gmt/matrix))
|
|
||||||
xfmt (gmt/translate prev delta)]
|
|
||||||
(assoc-in state [:workspace-data :shapes-by-id id :modifier-mtx] xfmt)))]
|
|
||||||
(ptk/reify ::apply-temporal-displacement-in-bulk
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(reduce process-shape state ids)))))
|
|
||||||
|
|
||||||
(defn- recalculate-shape-canvas-relation
|
(defn- recalculate-shape-canvas-relation
|
||||||
[state shape]
|
[state shape]
|
||||||
(let [shape' (geom/shape->rect-shape shape)
|
(let [shape' (geom/shape->rect-shape shape)
|
||||||
|
@ -1330,21 +1386,109 @@
|
||||||
(first))]
|
(first))]
|
||||||
(assoc shape :canvas id)))
|
(assoc shape :canvas id)))
|
||||||
|
|
||||||
(defn materialize-temporal-modifier-in-bulk
|
(defn assoc-resize-modifier-in-bulk
|
||||||
|
[ids xfmt]
|
||||||
|
(us/verify ::set-of-uuid ids)
|
||||||
|
(us/verify gmt/matrix? xfmt)
|
||||||
|
(ptk/reify ::assoc-resize-modifier-in-bulk
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(reduce #(assoc-in %1 [:workspace-data :shapes-by-id %2 :resize-modifier] xfmt) state ids))))
|
||||||
|
|
||||||
|
(defn materialize-resize-modifier-in-bulk
|
||||||
[ids]
|
[ids]
|
||||||
(letfn [(process-shape [state id]
|
(letfn [(process-shape [state id]
|
||||||
(let [shape (get-in state [:workspace-data :shapes-by-id id])
|
(let [shape (get-in state [:workspace-data :shapes-by-id id])
|
||||||
xfmt (or (:modifier-mtx shape) (gmt/matrix))
|
modifier (:resize-modifier shape (gmt/matrix))
|
||||||
shape-old (dissoc shape :modifier-mtx)
|
|
||||||
shape-new (geom/transform shape-old xfmt)
|
shape (-> (dissoc shape :resize-modifier)
|
||||||
shape-new (recalculate-shape-canvas-relation state shape-new)]
|
(geom/transform modifier))
|
||||||
(assoc-in state [:workspace-data :shapes-by-id id] shape-new)))]
|
shape (recalculate-shape-canvas-relation state shape)]
|
||||||
(ptk/reify ::materialize-temporal-modifier-in-bulk
|
(assoc-in state [:workspace-data :shapes-by-id id] shape)))]
|
||||||
|
(ptk/reify ::materialize-resize-modifier-in-bulk
|
||||||
IBatchedChange
|
IBatchedChange
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(reduce process-shape state ids)))))
|
(reduce process-shape state ids)))))
|
||||||
|
|
||||||
|
(defn apply-displacement-in-bulk
|
||||||
|
"Apply the same displacement delta to all shapes identified by the
|
||||||
|
set if ids."
|
||||||
|
[ids delta]
|
||||||
|
(us/verify ::set-of-uuid ids)
|
||||||
|
(us/verify gpt/point? delta)
|
||||||
|
(letfn [(process-shape [state id]
|
||||||
|
(let [shape (get-in state [:workspace-data :shapes-by-id id])
|
||||||
|
prev (:displacement-modifier shape (gmt/matrix))
|
||||||
|
curr (gmt/translate prev delta)]
|
||||||
|
(->> (assoc shape :displacement-modifier curr)
|
||||||
|
(assoc-in state [:workspace-data :shapes-by-id id]))))]
|
||||||
|
(ptk/reify ::apply-displacement-in-bulk
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(reduce process-shape state ids)))))
|
||||||
|
|
||||||
|
(defn materialize-displacement-in-bulk
|
||||||
|
[ids]
|
||||||
|
(letfn [(process-shape [state id]
|
||||||
|
(let [shape (get-in state [:workspace-data :shapes-by-id id])
|
||||||
|
modifier (:displacement-modifier shape (gmt/matrix))
|
||||||
|
|
||||||
|
shape (-> (dissoc shape :displacement-modifier)
|
||||||
|
(geom/transform modifier))
|
||||||
|
shape (recalculate-shape-canvas-relation state shape)]
|
||||||
|
(assoc-in state [:workspace-data :shapes-by-id id] shape)))]
|
||||||
|
(ptk/reify ::materialize-displacement-in-bulk
|
||||||
|
IBatchedChange
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(reduce process-shape state ids)))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn apply-canvas-displacement
|
||||||
|
"Apply the same displacement delta to all shapes identified by the
|
||||||
|
set if ids."
|
||||||
|
[id delta]
|
||||||
|
(us/verify ::us/uuid id)
|
||||||
|
(us/verify gpt/point? delta)
|
||||||
|
(ptk/reify ::apply-canvas-displacement
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(let [shape (get-in state [:workspace-data :shapes-by-id id])
|
||||||
|
prev-xfmt (:displacement-modifier shape (gmt/matrix))
|
||||||
|
xfmt (gmt/translate prev-xfmt delta)]
|
||||||
|
(->> (assoc shape :displacement-modifier xfmt)
|
||||||
|
(assoc-in state [:workspace-data :shapes-by-id id]))))))
|
||||||
|
|
||||||
|
(defn materialize-canvas-displacement
|
||||||
|
[id]
|
||||||
|
(us/verify ::us/uuid id)
|
||||||
|
(ptk/reify ::materialize-canvas-displacement
|
||||||
|
IBatchedChange
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(let [data (:workspace-data state)
|
||||||
|
shapes-map (:shapes-by-id data)
|
||||||
|
|
||||||
|
canvas (get shapes-map id)
|
||||||
|
|
||||||
|
xfmt (or (:displacement-modifier canvas) (gmt/matrix))
|
||||||
|
|
||||||
|
canvas (-> canvas
|
||||||
|
(dissoc :displacement-modifier)
|
||||||
|
(geom/transform xfmt))
|
||||||
|
|
||||||
|
shapes (->> (:shapes data [])
|
||||||
|
(map #(get shapes-map %))
|
||||||
|
(filter #(= (:canvas %) id))
|
||||||
|
(map #(geom/transform % xfmt)))
|
||||||
|
|
||||||
|
shapes (d/index-by :id shapes)
|
||||||
|
shapes (assoc shapes (:id canvas) canvas)]
|
||||||
|
|
||||||
|
(update-in state [:workspace-data :shapes-by-id] merge shapes)))))
|
||||||
|
|
||||||
|
|
||||||
(defn commit-changes
|
(defn commit-changes
|
||||||
([changes undo-changes] (commit-changes changes undo-changes true))
|
([changes undo-changes] (commit-changes changes undo-changes true))
|
||||||
([changes undo-changes save-undo?]
|
([changes undo-changes save-undo?]
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2016-2019 Andrey Antukh <niwi@niwi.nz>
|
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||||
|
;; defined by the Mozilla Public License, v. 2.0.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) 2016-2020 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns uxbox.main.ui.shapes
|
(ns uxbox.main.ui.shapes
|
||||||
(:require
|
(:require
|
||||||
|
@ -10,25 +13,7 @@
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.shapes.circle :as circle]
|
[uxbox.main.ui.shapes.canvas :as canvas]))
|
||||||
[uxbox.main.ui.shapes.icon :as icon]
|
|
||||||
[uxbox.main.ui.shapes.image :as image]
|
|
||||||
[uxbox.main.ui.shapes.path :as path]
|
|
||||||
[uxbox.main.ui.shapes.rect :as rect]
|
|
||||||
[uxbox.main.ui.shapes.canvas :as canvas]
|
|
||||||
[uxbox.main.ui.shapes.text :as text]))
|
|
||||||
|
|
||||||
(mf/defc shape-wrapper
|
|
||||||
{:wrap [mf/wrap-memo]}
|
|
||||||
[{:keys [shape] :as props}]
|
|
||||||
(when (and shape (not (:hidden shape)))
|
|
||||||
(case (:type shape)
|
|
||||||
:canvas [:& canvas/canvas-wrapper {:shape shape}]
|
|
||||||
:curve [:& path/path-wrapper {:shape shape}]
|
|
||||||
:text [:& text/text-wrapper {:shape shape}]
|
|
||||||
:icon [:& icon/icon-wrapper {:shape shape}]
|
|
||||||
:rect [:& rect/rect-wrapper {:shape shape}]
|
|
||||||
:path [:& path/path-wrapper {:shape shape}]
|
|
||||||
:image [:& image/image-wrapper {:shape shape}]
|
|
||||||
:circle [:& circle/circle-wrapper {:shape shape}])))
|
|
||||||
|
|
||||||
|
(def shape-wrapper canvas/shape-wrapper)
|
||||||
|
(def canvas-wrapper canvas/canvas-wrapper)
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
|
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||||
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
;; defined by the Mozilla Public License, v. 2.0.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
;; Copyright (c) 2015-2020 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
|
||||||
(ns uxbox.main.ui.shapes.canvas
|
(ns uxbox.main.ui.shapes.canvas
|
||||||
(:require
|
(:require
|
||||||
|
@ -13,29 +16,97 @@
|
||||||
[uxbox.main.data.workspace :as dw]
|
[uxbox.main.data.workspace :as dw]
|
||||||
[uxbox.main.geom :as geom]
|
[uxbox.main.geom :as geom]
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.main.ui.shapes.common :as common]
|
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.shapes.rect :refer [rect-shape]]
|
[uxbox.main.ui.shapes.attrs :as attrs]
|
||||||
|
[uxbox.main.ui.shapes.circle :as circle]
|
||||||
|
[uxbox.main.ui.shapes.common :as common]
|
||||||
|
[uxbox.main.ui.shapes.icon :as icon]
|
||||||
|
[uxbox.main.ui.shapes.image :as image]
|
||||||
|
[uxbox.main.ui.shapes.path :as path]
|
||||||
|
[uxbox.main.ui.shapes.rect :as rect]
|
||||||
|
[uxbox.main.ui.shapes.text :as text]
|
||||||
[uxbox.util.data :refer [parse-int]]
|
[uxbox.util.data :refer [parse-int]]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
|
[uxbox.util.geom.matrix :as gmt]
|
||||||
[uxbox.util.geom.point :as gpt]))
|
[uxbox.util.geom.point :as gpt]))
|
||||||
|
|
||||||
|
(declare canvas-wrapper)
|
||||||
|
|
||||||
|
(mf/defc shape-wrapper
|
||||||
|
{:wrap [mf/wrap-memo]}
|
||||||
|
[{:keys [shape] :as props}]
|
||||||
|
(when (and shape (not (:hidden shape)))
|
||||||
|
(case (:type shape)
|
||||||
|
:canvas [:& canvas-wrapper {:shape shape :childs []}]
|
||||||
|
:curve [:& path/path-wrapper {:shape shape}]
|
||||||
|
:text [:& text/text-wrapper {:shape shape}]
|
||||||
|
:icon [:& icon/icon-wrapper {:shape shape}]
|
||||||
|
:rect [:& rect/rect-wrapper {:shape shape}]
|
||||||
|
:path [:& path/path-wrapper {:shape shape}]
|
||||||
|
:image [:& image/image-wrapper {:shape shape}]
|
||||||
|
:circle [:& circle/circle-wrapper {:shape shape}])))
|
||||||
|
|
||||||
(def canvas-default-props
|
(def canvas-default-props
|
||||||
{:fill-color "#ffffff"})
|
{:fill-color "#ffffff"})
|
||||||
|
|
||||||
|
(declare canvas-shape)
|
||||||
|
|
||||||
(mf/defc canvas-wrapper
|
(mf/defc canvas-wrapper
|
||||||
[{:keys [shape] :as props}]
|
[{:keys [shape childs] :as props}]
|
||||||
(let [selected (mf/deref refs/selected-shapes)
|
(when (and shape (not (:hidden shape)))
|
||||||
selected? (contains? selected (:id shape))
|
(let [selected (mf/deref refs/selected-shapes)
|
||||||
on-mouse-down #(common/on-mouse-down % shape selected)
|
selected? (contains? selected (:id shape))
|
||||||
shape (merge canvas-default-props shape)]
|
on-mouse-down #(common/on-mouse-down % shape selected)
|
||||||
(letfn [(on-double-click [event]
|
shape (merge canvas-default-props shape)
|
||||||
(dom/prevent-default event)
|
|
||||||
(st/emit! dw/deselect-all
|
on-double-click
|
||||||
(dw/select-shape (:id shape))))]
|
(fn [event]
|
||||||
[:g.shape {:class (when selected? "selected")
|
(dom/prevent-default event)
|
||||||
:on-double-click on-double-click
|
(st/emit! dw/deselect-all
|
||||||
:on-mouse-down on-mouse-down}
|
(dw/select-shape (:id shape))))]
|
||||||
[:& rect-shape {:shape shape}]])))
|
[:g {:class (when selected? "selected")
|
||||||
|
:on-double-click on-double-click
|
||||||
|
:on-mouse-down on-mouse-down}
|
||||||
|
[:& canvas-shape {:shape shape :childs childs}]])))
|
||||||
|
|
||||||
|
(defn- translate-to-canvas
|
||||||
|
[shape canvas-ds-modifier pt]
|
||||||
|
(let [rz-modifier (:resize-modifier shape)
|
||||||
|
shape (cond-> shape
|
||||||
|
(gmt/matrix? canvas-ds-modifier)
|
||||||
|
(geom/transform canvas-ds-modifier)
|
||||||
|
|
||||||
|
(gmt/matrix? rz-modifier)
|
||||||
|
(-> (geom/transform rz-modifier)
|
||||||
|
(dissoc :resize-modifier)))]
|
||||||
|
(geom/move shape pt)))
|
||||||
|
|
||||||
|
(mf/defc canvas-shape
|
||||||
|
[{:keys [shape childs] :as props}]
|
||||||
|
(let [rotation (:rotation shape)
|
||||||
|
ds-modifier (:displacement-modifier shape)
|
||||||
|
rz-modifier (:modifier-mtx shape)
|
||||||
|
|
||||||
|
shape (cond-> shape
|
||||||
|
(gmt/matrix? rz-modifier) (geom/transform rz-modifier)
|
||||||
|
(gmt/matrix? ds-modifier) (geom/transform ds-modifier))
|
||||||
|
|
||||||
|
{:keys [id x y width height]} shape
|
||||||
|
|
||||||
|
props (-> (attrs/extract-style-attrs shape)
|
||||||
|
(assoc :x 0
|
||||||
|
:y 0
|
||||||
|
:id (str "shape-" id)
|
||||||
|
:width width
|
||||||
|
:height height
|
||||||
|
))
|
||||||
|
|
||||||
|
translate #(translate-to-canvas % ds-modifier (gpt/point (- x) (- y)))]
|
||||||
|
|
||||||
|
[:svg {:x x :y y :width width :height height}
|
||||||
|
[:& "rect" props]
|
||||||
|
(for [item (map translate childs)]
|
||||||
|
[:& shape-wrapper {:shape item :key (:id item)}])]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,28 +32,28 @@
|
||||||
|
|
||||||
(mf/defc circle-shape
|
(mf/defc circle-shape
|
||||||
[{:keys [shape] :as props}]
|
[{:keys [shape] :as props}]
|
||||||
(let [{:keys [id rotation cx cy modifier-mtx]} shape
|
|
||||||
|
|
||||||
shape (cond
|
(let [ds-modifier (:displacement-modifier shape)
|
||||||
(gmt/matrix? modifier-mtx) (geom/transform shape modifier-mtx)
|
rz-modifier (:resize-modifier shape)
|
||||||
:else shape)
|
|
||||||
|
|
||||||
center (gpt/point (:cx shape)
|
shape (cond-> shape
|
||||||
(:cy shape))
|
(gmt/matrix? rz-modifier) (geom/transform rz-modifier)
|
||||||
|
(gmt/matrix? ds-modifier) (geom/transform ds-modifier))
|
||||||
|
|
||||||
rotation (or rotation 0)
|
{:keys [id cx cy rx ry rotation]} shape
|
||||||
|
|
||||||
moving? (boolean modifier-mtx)
|
|
||||||
|
|
||||||
|
center (gpt/point cx cy)
|
||||||
|
rotation (or rotation 0)
|
||||||
transform (when (pos? rotation)
|
transform (when (pos? rotation)
|
||||||
(str (-> (gmt/matrix)
|
(str (-> (gmt/matrix)
|
||||||
(gmt/rotate rotation center))))
|
(gmt/rotate rotation center))))
|
||||||
|
|
||||||
props {:id (str "shape-" id)
|
props (-> (attrs/extract-style-attrs shape)
|
||||||
:class (classnames :move-cursor moving?)
|
(assoc :cx cx
|
||||||
:transform transform}
|
:cy cy
|
||||||
|
:rx rx
|
||||||
attrs (merge props
|
:ry ry
|
||||||
(attrs/extract-style-attrs shape)
|
:transform transform
|
||||||
(select-keys shape [:cx :cy :rx :ry]))]
|
:id (str "shape-" id)
|
||||||
[:> :ellipse (normalize-props attrs)]))
|
))]
|
||||||
|
[:& "elipse" props]))
|
||||||
|
|
|
@ -13,12 +13,15 @@
|
||||||
(:require
|
(:require
|
||||||
[potok.core :as ptk]
|
[potok.core :as ptk]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
|
[uxbox.common.data :as d]
|
||||||
|
[uxbox.common.spec :as us]
|
||||||
[uxbox.main.data.workspace :as dw]
|
[uxbox.main.data.workspace :as dw]
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.keyboard :as kbd]
|
[uxbox.main.ui.keyboard :as kbd]
|
||||||
[uxbox.main.streams :as uws]
|
[uxbox.main.streams :as uws]
|
||||||
[uxbox.main.workers :as uwrk]
|
[uxbox.main.workers :as uwrk]
|
||||||
|
[uxbox.main.geom :as geom]
|
||||||
[uxbox.util.geom.matrix :as gmt]
|
[uxbox.util.geom.matrix :as gmt]
|
||||||
[uxbox.util.geom.point :as gpt]
|
[uxbox.util.geom.point :as gpt]
|
||||||
[uxbox.util.dom :as dom]))
|
[uxbox.util.dom :as dom]))
|
||||||
|
@ -34,14 +37,93 @@
|
||||||
stoper (rx/filter uws/mouse-up? stream)
|
stoper (rx/filter uws/mouse-up? stream)
|
||||||
position @uws/mouse-position]
|
position @uws/mouse-position]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
;; (when (refs/alignment-activated? flags)
|
|
||||||
;; (rx/of (dw/initial-selection-align selected)))
|
|
||||||
(->> (uws/mouse-position-deltas position)
|
(->> (uws/mouse-position-deltas position)
|
||||||
(rx/map #(dw/apply-temporal-displacement-in-bulk selected %))
|
(rx/map #(dw/apply-displacement-in-bulk selected %))
|
||||||
(rx/take-until stoper))
|
(rx/take-until stoper))
|
||||||
(rx/of (dw/materialize-temporal-modifier-in-bulk selected)
|
(rx/of (dw/materialize-displacement-in-bulk selected)
|
||||||
::dw/page-data-update))))))
|
::dw/page-data-update))))))
|
||||||
|
|
||||||
|
;; (defn apply-canvas-displacement
|
||||||
|
;; "Apply the same displacement delta to all shapes identified by the
|
||||||
|
;; set if ids."
|
||||||
|
;; [id delta]
|
||||||
|
;; (us/verify ::us/uuid id)
|
||||||
|
;; (us/verify gpt/point? delta)
|
||||||
|
;; (ptk/reify ::apply-temporal-displacement-in-bulk
|
||||||
|
;; ptk/UpdateEvent
|
||||||
|
;; (update [_ state]
|
||||||
|
;; (let [shape (get-in state [:workspace-data :shapes-by-id id])
|
||||||
|
;; prev-xfmt (:displacement-modifier shape (gmt/matrix))
|
||||||
|
;; xfmt (gmt/translate prev-xfmt delta)]
|
||||||
|
;; (->> (assoc shape :displacement-modifier xfmt)
|
||||||
|
;; (assoc-in state [:workspace-data :shapes-by-id id]))))))
|
||||||
|
|
||||||
|
;; (defn materialize-canvas-displacement
|
||||||
|
;; [id]
|
||||||
|
;; (us/verify ::us/uuid id)
|
||||||
|
;; (ptk/reify ::materialize-temporal-modifier
|
||||||
|
;; dw/IBatchedChange
|
||||||
|
;; ptk/UpdateEvent
|
||||||
|
;; (update [_ state]
|
||||||
|
;; (let [data (:workspace-data state)
|
||||||
|
;; shapes-map (:shapes-by-id data)
|
||||||
|
|
||||||
|
;; canvas (get shapes-map id)
|
||||||
|
|
||||||
|
;; xfmt (or (:displacement-modifier canvas) (gmt/matrix))
|
||||||
|
|
||||||
|
;; canvas (-> canvas
|
||||||
|
;; (dissoc :displacement-modifier)
|
||||||
|
;; (geom/transform xfmt))
|
||||||
|
|
||||||
|
;; shapes (->> (:shapes data [])
|
||||||
|
;; (map #(get shapes-map %))
|
||||||
|
;; (filter #(= (:canvas %) id))
|
||||||
|
;; (map #(geom/transform % xfmt)))
|
||||||
|
|
||||||
|
;; shapes (d/index-by :id shapes)
|
||||||
|
;; shapes (assoc shapes (:id canvas) canvas)]
|
||||||
|
|
||||||
|
;; (update-in state [:workspace-data :shapes-by-id] merge shapes)))))
|
||||||
|
|
||||||
|
;; (defn- move-canvas
|
||||||
|
;; [id delta]
|
||||||
|
;; (ptk/reify ::move-canvas
|
||||||
|
;; ptk/UpdateEvent
|
||||||
|
;; (update [_ state]
|
||||||
|
;; (let [data (:workspace-data state)
|
||||||
|
;; shapes-map (:shapes-by-id data)
|
||||||
|
|
||||||
|
;; canvas (-> (get shapes-map id)
|
||||||
|
;; (geom/move delta))
|
||||||
|
|
||||||
|
;; shapes (->> (:shapes data [])
|
||||||
|
;; (map #(get shapes-map %))
|
||||||
|
;; (filter #(= (:canvas %) id))
|
||||||
|
;; (map #(geom/move % delta)))
|
||||||
|
|
||||||
|
;; shapes (d/index-by :id shapes)
|
||||||
|
;; shapes (assoc shapes (:id canvas) canvas)]
|
||||||
|
|
||||||
|
;; (update-in state [:workspace-data :shapes-by-id] merge shapes)))))
|
||||||
|
|
||||||
|
|
||||||
|
(def start-move-canvas
|
||||||
|
(ptk/reify ::start-move-selected
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state stream]
|
||||||
|
(let [flags (get-in state [:workspace-local :flags])
|
||||||
|
selected (get-in state [:workspace-local :selected])
|
||||||
|
stoper (rx/filter uws/mouse-up? stream)
|
||||||
|
canvas-id (first selected)
|
||||||
|
position @uws/mouse-position]
|
||||||
|
|
||||||
|
(rx/concat
|
||||||
|
(->> (uws/mouse-position-deltas position)
|
||||||
|
(rx/map #(dw/apply-canvas-displacement canvas-id %))
|
||||||
|
(rx/take-until stoper))
|
||||||
|
(rx/of (dw/materialize-canvas-displacement canvas-id)))))))
|
||||||
|
|
||||||
(defn on-mouse-down
|
(defn on-mouse-down
|
||||||
[event {:keys [id type] :as shape} selected]
|
[event {:keys [id type] :as shape} selected]
|
||||||
(let [selected? (contains? selected id)
|
(let [selected? (contains? selected id)
|
||||||
|
@ -54,7 +136,7 @@
|
||||||
(= type :canvas)
|
(= type :canvas)
|
||||||
(when selected?
|
(when selected?
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(st/emit! start-move-selected))
|
(st/emit! start-move-canvas))
|
||||||
|
|
||||||
(and (not selected?) (empty? selected))
|
(and (not selected?) (empty? selected))
|
||||||
(do
|
(do
|
||||||
|
|
|
@ -34,13 +34,14 @@
|
||||||
|
|
||||||
(mf/defc icon-shape
|
(mf/defc icon-shape
|
||||||
[{:keys [shape] :as props}]
|
[{:keys [shape] :as props}]
|
||||||
(let [{:keys [id content metadata rotation modifier-mtx]} shape
|
(let [ds-modifier (:displacement-modifier shape)
|
||||||
|
rz-modifier (:resize-modifier shape)
|
||||||
|
|
||||||
shape (cond
|
shape (cond-> shape
|
||||||
(gmt/matrix? modifier-mtx) (geom/transform shape modifier-mtx)
|
(gmt/matrix? rz-modifier) (geom/transform rz-modifier)
|
||||||
:else shape)
|
(gmt/matrix? ds-modifier) (geom/transform ds-modifier))
|
||||||
|
|
||||||
{:keys [x y width height] :as shape} shape
|
{:keys [id x y width height metadata rotation content] :as shape} shape
|
||||||
|
|
||||||
transform (when (and rotation (pos? rotation))
|
transform (when (and rotation (pos? rotation))
|
||||||
(str/format "rotate(%s %s %s)"
|
(str/format "rotate(%s %s %s)"
|
||||||
|
@ -48,7 +49,6 @@
|
||||||
(+ x (/ width 2))
|
(+ x (/ width 2))
|
||||||
(+ y (/ height 2))))
|
(+ y (/ height 2))))
|
||||||
|
|
||||||
|
|
||||||
view-box (apply str (interpose " " (:view-box metadata)))
|
view-box (apply str (interpose " " (:view-box metadata)))
|
||||||
|
|
||||||
props (-> (attrs/extract-style-attrs shape)
|
props (-> (attrs/extract-style-attrs shape)
|
||||||
|
|
|
@ -33,13 +33,14 @@
|
||||||
|
|
||||||
(mf/defc image-shape
|
(mf/defc image-shape
|
||||||
[{:keys [shape] :as props}]
|
[{:keys [shape] :as props}]
|
||||||
(let [{:keys [id rotation modifier-mtx metadata]} shape
|
(let [ds-modifier (:displacement-modifier shape)
|
||||||
|
rz-modifier (:resize-modifier shape)
|
||||||
|
|
||||||
shape (cond
|
shape (cond-> shape
|
||||||
(gmt/matrix? modifier-mtx) (geom/transform shape modifier-mtx)
|
(gmt/matrix? rz-modifier) (geom/transform rz-modifier)
|
||||||
:else shape)
|
(gmt/matrix? ds-modifier) (geom/transform ds-modifier))
|
||||||
|
|
||||||
{:keys [x y width height]} shape
|
{:keys [id x y width height rotation metadata]} shape
|
||||||
|
|
||||||
transform (when (and rotation (pos? rotation))
|
transform (when (and rotation (pos? rotation))
|
||||||
(str/format "rotate(%s %s %s)"
|
(str/format "rotate(%s %s %s)"
|
||||||
|
|
|
@ -61,14 +61,14 @@
|
||||||
|
|
||||||
(mf/defc path-shape
|
(mf/defc path-shape
|
||||||
[{:keys [shape background?] :as props}]
|
[{:keys [shape background?] :as props}]
|
||||||
(let [modifier-mtx (:modifier-mtx shape)
|
(let [ds-modifier (:displacement-modifier shape)
|
||||||
rotation (:rotation shape)
|
rz-modifier (:resize-modifier shape)
|
||||||
|
|
||||||
shape (cond
|
shape (cond-> shape
|
||||||
(gmt/matrix? modifier-mtx) (geom/transform shape modifier-mtx)
|
(gmt/matrix? rz-modifier) (geom/transform rz-modifier)
|
||||||
:else shape)
|
(gmt/matrix? ds-modifier) (geom/transform ds-modifier))
|
||||||
|
|
||||||
{:keys [id x y width height]} (geom/shape->rect-shape shape)
|
{:keys [id x y width height rotation]} (geom/shape->rect-shape shape)
|
||||||
|
|
||||||
transform (when (and rotation (pos? rotation))
|
transform (when (and rotation (pos? rotation))
|
||||||
(str/format "rotate(%s %s %s)"
|
(str/format "rotate(%s %s %s)"
|
||||||
|
|
|
@ -34,13 +34,14 @@
|
||||||
|
|
||||||
(mf/defc rect-shape
|
(mf/defc rect-shape
|
||||||
[{:keys [shape] :as props}]
|
[{:keys [shape] :as props}]
|
||||||
(let [{:keys [id rotation modifier-mtx]} shape
|
(let [ds-modifier (:displacement-modifier shape)
|
||||||
|
rz-modifier (:resize-modifier shape)
|
||||||
|
|
||||||
shape (cond
|
shape (cond-> shape
|
||||||
(gmt/matrix? modifier-mtx) (geom/transform shape modifier-mtx)
|
(gmt/matrix? rz-modifier) (geom/transform rz-modifier)
|
||||||
:else shape)
|
(gmt/matrix? ds-modifier) (geom/transform ds-modifier))
|
||||||
|
|
||||||
{:keys [x y width height]} shape
|
{:keys [id x y width height rotation]} shape
|
||||||
|
|
||||||
transform (when (and rotation (pos? rotation))
|
transform (when (and rotation (pos? rotation))
|
||||||
(str/format "rotate(%s %s %s)"
|
(str/format "rotate(%s %s %s)"
|
||||||
|
|
|
@ -120,7 +120,7 @@
|
||||||
result (geom/resize-shape :bottom-right shape' point lock?)
|
result (geom/resize-shape :bottom-right shape' point lock?)
|
||||||
scale (geom/calculate-scale-ratio shape' result)
|
scale (geom/calculate-scale-ratio shape' result)
|
||||||
mtx (geom/generate-resize-matrix :bottom-right shape' scale)]
|
mtx (geom/generate-resize-matrix :bottom-right shape' scale)]
|
||||||
(assoc shape :modifier-mtx mtx)))
|
(assoc shape :resize-modifier mtx)))
|
||||||
|
|
||||||
(update-drawing [state point lock?]
|
(update-drawing [state point lock?]
|
||||||
(update-in state [:workspace-local :drawing] resize-shape point lock?))]
|
(update-in state [:workspace-local :drawing] resize-shape point lock?))]
|
||||||
|
@ -273,11 +273,11 @@
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of dw/clear-drawing)
|
(rx/of dw/clear-drawing)
|
||||||
(when (::initialized? shape)
|
(when (::initialized? shape)
|
||||||
(let [modifier-mtx (:modifier-mtx shape)
|
(let [modifier (:resize-modifier shape)
|
||||||
shape (if (gmt/matrix? modifier-mtx)
|
shape (if (gmt/matrix? modifier)
|
||||||
(geom/transform shape modifier-mtx)
|
(geom/transform shape modifier)
|
||||||
shape)
|
shape)
|
||||||
shape (dissoc shape ::initialized? :modifier-mtx)]
|
shape (dissoc shape ::initialized? :resize-modifier)]
|
||||||
;; Add & select the created shape to the workspace
|
;; Add & select the created shape to the workspace
|
||||||
(rx/of dw/deselect-all
|
(rx/of dw/deselect-all
|
||||||
(if (= :canvas (:type shape))
|
(if (= :canvas (:type shape))
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
(let [result (geom/resize-shape vid shape point lock?)
|
(let [result (geom/resize-shape vid shape point lock?)
|
||||||
scale (geom/calculate-scale-ratio shape result)
|
scale (geom/calculate-scale-ratio shape result)
|
||||||
mtx (geom/generate-resize-matrix vid shape scale)]
|
mtx (geom/generate-resize-matrix vid shape scale)]
|
||||||
(rx/of (dw/assoc-temporal-modifier-in-bulk ids mtx))))
|
(rx/of (dw/assoc-resize-modifier-in-bulk ids mtx))))
|
||||||
|
|
||||||
;; Unifies the instantaneous proportion lock modifier
|
;; Unifies the instantaneous proportion lock modifier
|
||||||
;; activated by Ctrl key and the shapes own proportion
|
;; activated by Ctrl key and the shapes own proportion
|
||||||
|
@ -64,8 +64,7 @@
|
||||||
(rx/map normalize-proportion-lock)
|
(rx/map normalize-proportion-lock)
|
||||||
(rx/mapcat (partial resize shape))
|
(rx/mapcat (partial resize shape))
|
||||||
(rx/take-until stoper))
|
(rx/take-until stoper))
|
||||||
(rx/of (dw/materialize-temporal-modifier-in-bulk ids)
|
(rx/of (dw/materialize-resize-modifier-in-bulk ids))))))))
|
||||||
::dw/page-data-update)))))))
|
|
||||||
|
|
||||||
(defn start-rotate
|
(defn start-rotate
|
||||||
[shape]
|
[shape]
|
||||||
|
@ -261,9 +260,13 @@
|
||||||
(st/emit! (start-resize %1 #{(:id shape)} shape)))
|
(st/emit! (start-resize %1 #{(:id shape)} shape)))
|
||||||
on-rotate #(do (dom/stop-propagation %)
|
on-rotate #(do (dom/stop-propagation %)
|
||||||
(st/emit! (start-rotate shape)))
|
(st/emit! (start-rotate shape)))
|
||||||
modifier (:modifier-mtx shape)
|
|
||||||
shape (-> (geom/shape->rect-shape shape)
|
ds-modifier (:displacement-modifier shape)
|
||||||
(geom/transform (or modifier (gmt/matrix))))]
|
rz-modifier (:resize-modifier shape)
|
||||||
|
shape (cond-> (geom/shape->rect-shape shape)
|
||||||
|
(gmt/matrix? rz-modifier) (geom/transform rz-modifier)
|
||||||
|
(gmt/matrix? ds-modifier) (geom/transform ds-modifier))]
|
||||||
|
|
||||||
[:& controls {:shape shape
|
[:& controls {:shape shape
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:on-rotate on-rotate
|
:on-rotate on-rotate
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
[uxbox.main.ui.workspace.ruler :refer [ruler]]
|
[uxbox.main.ui.workspace.ruler :refer [ruler]]
|
||||||
[uxbox.main.ui.workspace.drawarea :refer [start-drawing]]
|
[uxbox.main.ui.workspace.drawarea :refer [start-drawing]]
|
||||||
|
|
||||||
[uxbox.main.ui.shapes :refer [shape-wrapper]]
|
[uxbox.main.ui.shapes :refer [shape-wrapper canvas-wrapper]]
|
||||||
[uxbox.main.ui.workspace.drawarea :refer [draw-area]]
|
[uxbox.main.ui.workspace.drawarea :refer [draw-area]]
|
||||||
[uxbox.main.ui.workspace.selection :refer [selection-handlers]]
|
[uxbox.main.ui.workspace.selection :refer [selection-handlers]]
|
||||||
|
|
||||||
|
@ -149,11 +149,14 @@
|
||||||
(let [data (mf/deref refs/workspace-data)
|
(let [data (mf/deref refs/workspace-data)
|
||||||
shapes-by-id (:shapes-by-id data)
|
shapes-by-id (:shapes-by-id data)
|
||||||
shapes (map #(get shapes-by-id %) (:shapes data []))
|
shapes (map #(get shapes-by-id %) (:shapes data []))
|
||||||
canvas (map #(get shapes-by-id %) (:canvas data []))]
|
canvas (map #(get shapes-by-id %) (:canvas data []))
|
||||||
|
unassinged (filter #(nil? (:canvas %)) shapes)]
|
||||||
[:g.shapes
|
[:g.shapes
|
||||||
(for [item canvas]
|
(for [item canvas]
|
||||||
[:& shape-wrapper {:shape item :key (:id item)}])
|
(let [shapes (filter #(= (:canvas %) (:id item)) shapes)]
|
||||||
(for [item shapes]
|
[:& canvas-wrapper {:shape item :key (:id item)
|
||||||
|
:childs shapes}]))
|
||||||
|
(for [item unassinged]
|
||||||
[:& shape-wrapper {:shape item :key (:id item)}])]))
|
[:& shape-wrapper {:shape item :key (:id item)}])]))
|
||||||
|
|
||||||
(mf/defc viewport
|
(mf/defc viewport
|
||||||
|
|
Loading…
Add table
Reference in a new issue