mirror of
https://github.com/penpot/penpot.git
synced 2025-06-13 02:41:39 +02:00
🚧 Initial work on multicanvas feature.
This commit is contained in:
parent
176ca590e1
commit
807555d478
32 changed files with 1408 additions and 1495 deletions
|
@ -21,19 +21,27 @@
|
|||
[uxbox.main.workers :as uwrk]
|
||||
[uxbox.util.math :as mth]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.data :refer [seek]]
|
||||
[uxbox.util.geom.path :as path]
|
||||
[uxbox.util.geom.point :as gpt]))
|
||||
[uxbox.util.geom.point :as gpt]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
(defn- rxfinalize
|
||||
[f ob]
|
||||
(.pipe ob (.finalize js/rxjs.operators f)))
|
||||
|
||||
;; --- Events
|
||||
|
||||
(declare handle-drawing)
|
||||
(declare handle-drawing-generic)
|
||||
(declare handle-drawing-path)
|
||||
(declare handle-drawing-free-path)
|
||||
(declare handle-drawing-curve)
|
||||
(declare handle-finish-drawing)
|
||||
(declare conditional-align)
|
||||
|
||||
(defn start-drawing
|
||||
[object]
|
||||
[type]
|
||||
{:pre [(keyword? type)]}
|
||||
(let [id (gensym "drawing")]
|
||||
(reify
|
||||
ptk/UpdateEvent
|
||||
|
@ -42,35 +50,65 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [lock (get-in state [:workspace :drawing-lock])]
|
||||
(let [pid (get-in state [:workspace :current])
|
||||
lock (get-in state [:workspace :drawing-lock])]
|
||||
(if (= lock id)
|
||||
(rx/merge (->> stream
|
||||
(rx/filter #(= % handle-finish-drawing))
|
||||
(rx/take 1)
|
||||
(rx/map (fn [_] #(update % :workspace dissoc :drawing-lock))))
|
||||
(rx/of (handle-drawing object)))
|
||||
(rx/merge
|
||||
(->> (rx/filter #(= % handle-finish-drawing) stream)
|
||||
(rx/take 1)
|
||||
(rx/map (fn [_] #(update % :workspace dissoc :drawing-lock))))
|
||||
(rx/of (handle-drawing type)))
|
||||
(rx/empty)))))))
|
||||
|
||||
(defn- conditional-align [point align?]
|
||||
(if align?
|
||||
(uwrk/align-point point)
|
||||
(rx/of point)))
|
||||
(def ^:private minimal-shapes
|
||||
[{:type :rect
|
||||
:name "Rect"
|
||||
:stroke-color "#000000"}
|
||||
{:type :circle
|
||||
:name "Circle"}
|
||||
{:type :path
|
||||
:name "Path"
|
||||
:stroke-style :solid
|
||||
:stroke-color "#000000"
|
||||
:stroke-width 2
|
||||
:fill-color "#000000"
|
||||
:fill-opacity 0
|
||||
:segments []}
|
||||
{:type :curve
|
||||
:name "Path"
|
||||
:stroke-style :solid
|
||||
:stroke-color "#000000"
|
||||
:stroke-width 2
|
||||
:fill-color "#000000"
|
||||
:fill-opacity 0
|
||||
:segments []}
|
||||
{:type :text
|
||||
:name "Text"
|
||||
:content "Type your text here"}])
|
||||
|
||||
(defn- make-minimal-shape
|
||||
[type]
|
||||
(let [tool (seek #(= type (:type %)) minimal-shapes)]
|
||||
(assert tool "unexpected drawing tool")
|
||||
(assoc tool :id (uuid/random))))
|
||||
|
||||
;; TODO: maybe this should be a simple function
|
||||
(defn handle-drawing
|
||||
[shape]
|
||||
[type]
|
||||
(reify
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [pid (get-in state [:workspace :current])
|
||||
shape (make-minimal-shape type)]
|
||||
(assoc-in state [:workspace pid :drawing] shape)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(rx/of
|
||||
(if (= :path (:type shape))
|
||||
(if (:free shape)
|
||||
(handle-drawing-free-path shape)
|
||||
(handle-drawing-path shape))
|
||||
(handle-drawing-generic shape))))))
|
||||
(case type
|
||||
:path (rx/of handle-drawing-path)
|
||||
:curve (rx/of handle-drawing-curve)
|
||||
(rx/of handle-drawing-generic)))))
|
||||
|
||||
(defn- handle-drawing-generic
|
||||
[shape]
|
||||
(def handle-drawing-generic
|
||||
(letfn [(initialize-drawing [state point]
|
||||
(let [pid (get-in state [:workspace :current])
|
||||
shape (get-in state [:workspace pid :drawing])
|
||||
|
@ -114,11 +152,11 @@
|
|||
stoper (->> (rx/filter #(or (uws/mouse-up? %) (= % :interrupt)) stream)
|
||||
(rx/take 1))
|
||||
|
||||
mouse (->> uws/viewport-mouse-position
|
||||
mouse (->> uws/mouse-position
|
||||
(rx/mapcat #(conditional-align % align?))
|
||||
(rx/with-latest vector uws/mouse-position-ctrl))]
|
||||
(rx/concat
|
||||
(->> uws/viewport-mouse-position
|
||||
(->> uws/mouse-position
|
||||
(rx/take 1)
|
||||
(rx/mapcat #(conditional-align % align?))
|
||||
(rx/map (fn [pt] #(initialize-drawing % pt))))
|
||||
|
@ -127,8 +165,7 @@
|
|||
(rx/take-until stoper))
|
||||
(rx/of handle-finish-drawing)))))))
|
||||
|
||||
(defn handle-drawing-path
|
||||
[shape]
|
||||
(def handle-drawing-path
|
||||
(letfn [(stoper-event? [{:keys [type shift] :as event}]
|
||||
(or (= event :interrupt)
|
||||
(and (uws/mouse-event? event)
|
||||
|
@ -166,12 +203,12 @@
|
|||
flags (get-in state [:workspace pid :flags])
|
||||
align? (refs/alignment-activated? flags)
|
||||
|
||||
last-point (volatile! @uws/viewport-mouse-position)
|
||||
last-point (volatile! @uws/mouse-position)
|
||||
|
||||
stoper (->> (rx/filter stoper-event? stream)
|
||||
(rx/take 1))
|
||||
(rx/share))
|
||||
|
||||
mouse (->> (rx/sample 10 uws/viewport-mouse-position)
|
||||
mouse (->> (rx/sample 10 uws/mouse-position)
|
||||
(rx/mapcat #(conditional-align % align?)))
|
||||
|
||||
points (->> stream
|
||||
|
@ -186,7 +223,6 @@
|
|||
(rx/with-latest vector counter)
|
||||
(rx/map flatten))
|
||||
|
||||
|
||||
imm-transform #(vector (- % 7) (+ % 7) %)
|
||||
immanted-zones (vec (concat
|
||||
(map imm-transform (range 0 181 15))
|
||||
|
@ -205,8 +241,8 @@
|
|||
|
||||
(->> points
|
||||
(rx/take-until stoper)
|
||||
(rx/map (fn [pt]
|
||||
#(insert-point-segment % pt))))
|
||||
(rx/map (fn [pt]#(insert-point-segment % pt))))
|
||||
|
||||
(rx/concat
|
||||
(->> stream'
|
||||
(rx/map (fn [[point ctrl? index :as xxx]]
|
||||
|
@ -221,8 +257,7 @@
|
|||
(rx/of remove-dangling-segmnet
|
||||
handle-finish-drawing))))))))
|
||||
|
||||
(defn- handle-drawing-free-path
|
||||
[shape]
|
||||
(def handle-drawing-curve
|
||||
(letfn [(stoper-event? [{:keys [type shift] :as event}]
|
||||
(or (= event :interrupt)
|
||||
(and (uws/mouse-event? event) (= type :up))))
|
||||
|
@ -249,7 +284,7 @@
|
|||
stoper (->> (rx/filter stoper-event? stream)
|
||||
(rx/take 1))
|
||||
|
||||
mouse (->> (rx/sample 10 uws/viewport-mouse-position)
|
||||
mouse (->> (rx/sample 10 uws/mouse-position)
|
||||
(rx/mapcat #(conditional-align % align?)))]
|
||||
(rx/concat
|
||||
(rx/of initialize-drawing)
|
||||
|
@ -275,10 +310,11 @@
|
|||
#(update-in % [:workspace pid :modifiers] dissoc (:id shape))
|
||||
|
||||
;; Unselect the drawing tool
|
||||
#(update-in % [:workspace pid] dissoc :drawing :drawing-tool)
|
||||
;; TODO; maybe a specific event for clear draw-tool
|
||||
dw/clear-drawing
|
||||
|
||||
;; Add & select the cred shape to the workspace
|
||||
(ds/add-shape shape)
|
||||
(dw/add-shape (dissoc shape ::initialized?))
|
||||
(dw/select-first-shape)))
|
||||
(rx/of #(update-in % [:workspace pid] dissoc :drawing :drawing-tool)))))))
|
||||
|
||||
|
@ -296,8 +332,8 @@
|
|||
|
||||
(mf/defc draw-area
|
||||
[{:keys [zoom shape modifiers] :as props}]
|
||||
(if (= (:type shape) :path)
|
||||
[:& path-draw-area {:shape shape}]
|
||||
(case (:type shape)
|
||||
(:path :curve) [:& path-draw-area {:shape shape}]
|
||||
[:& generic-draw-area {:shape (assoc shape :modifiers modifiers)
|
||||
:zoom zoom}]))
|
||||
|
||||
|
@ -328,7 +364,7 @@
|
|||
(when-let [{:keys [x y] :as segment} (first (:segments shape))]
|
||||
[:g
|
||||
(shapes/render-shape shape)
|
||||
(when-not (:free shape)
|
||||
(when (not= :curve (:type shape))
|
||||
[:circle.close-bezier
|
||||
{:cx x
|
||||
:cy y
|
||||
|
@ -336,3 +372,8 @@
|
|||
:on-click on-click
|
||||
:on-mouse-enter on-mouse-enter
|
||||
:on-mouse-leave on-mouse-leave}])])))
|
||||
|
||||
(defn- conditional-align [point align?]
|
||||
(if align?
|
||||
(uwrk/align-point point)
|
||||
(rx/of point)))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue