mirror of
https://github.com/penpot/penpot.git
synced 2025-01-26 08:29:42 -05:00
Reimplemented the draw shapes/icons.
This commit is contained in:
parent
28047aa64d
commit
32b7bfe383
5 changed files with 139 additions and 66 deletions
|
@ -80,10 +80,8 @@
|
||||||
(defonce interactions-b (rx/bus))
|
(defonce interactions-b (rx/bus))
|
||||||
|
|
||||||
(defn emit-interaction!
|
(defn emit-interaction!
|
||||||
([type]
|
[type]
|
||||||
(rx/push! interactions-b {:type type}))
|
(rx/push! interactions-b type))
|
||||||
([type payload]
|
|
||||||
(rx/push! interactions-b {:type type :payload payload})))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Mouse Position Stream
|
;; Mouse Position Stream
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
[uxbox.ui.dom :as dom]
|
[uxbox.ui.dom :as dom]
|
||||||
[uxbox.ui.workspace.base :as wb]
|
[uxbox.ui.workspace.base :as wb]
|
||||||
[uxbox.ui.workspace.canvas.movement]
|
[uxbox.ui.workspace.canvas.movement]
|
||||||
|
[uxbox.ui.workspace.canvas.draw :refer (draw-area)]
|
||||||
[uxbox.ui.workspace.canvas.selection :refer (shapes-selection)]
|
[uxbox.ui.workspace.canvas.selection :refer (shapes-selection)]
|
||||||
[uxbox.ui.workspace.canvas.selrect :refer (selrect)]
|
[uxbox.ui.workspace.canvas.selrect :refer (selrect)]
|
||||||
[uxbox.ui.workspace.grid :refer (grid)]
|
[uxbox.ui.workspace.grid :refer (grid)]
|
||||||
|
@ -67,7 +68,6 @@
|
||||||
(do
|
(do
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(swap! local assoc :init-coords [x y])
|
(swap! local assoc :init-coords [x y])
|
||||||
#_(reset! wb/shapes-dragging? true)
|
|
||||||
(if (.-ctrlKey event)
|
(if (.-ctrlKey event)
|
||||||
(rs/emit! (dw/select-shape id))
|
(rs/emit! (dw/select-shape id))
|
||||||
(rs/emit! (dw/deselect-all)
|
(rs/emit! (dw/deselect-all)
|
||||||
|
@ -162,7 +162,8 @@
|
||||||
(for [item (sequence xf (:shapes page))]
|
(for [item (sequence xf (:shapes page))]
|
||||||
(-> (shape item workspace-selected)
|
(-> (shape item workspace-selected)
|
||||||
(rum/with-key (str (:id item)))))
|
(rum/with-key (str (:id item)))))
|
||||||
(selrect)]]])))
|
(selrect)
|
||||||
|
(draw-area)]]])))
|
||||||
|
|
||||||
(def canvas
|
(def canvas
|
||||||
(mx/component
|
(mx/component
|
||||||
|
@ -187,27 +188,16 @@
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(when-not (empty? (:selected workspace))
|
(when-not (empty? (:selected workspace))
|
||||||
(rs/emit! (dw/deselect-all)))
|
(rs/emit! (dw/deselect-all)))
|
||||||
(wb/emit-interaction! :selrect/draw))
|
(if-let [shape (:drawing workspace)]
|
||||||
|
(wb/emit-interaction! :draw/shape)
|
||||||
|
(wb/emit-interaction! :draw/selrect)))
|
||||||
(on-mouse-up [event]
|
(on-mouse-up [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(wb/emit-interaction! :nothing))
|
(wb/emit-interaction! :nothing))]
|
||||||
(on-click [event wstate]
|
|
||||||
(let [mousepos @wb/mouse-position
|
|
||||||
scroll-top @wb/scroll-top
|
|
||||||
shape (:drawing wstate)]
|
|
||||||
(when shape
|
|
||||||
(let [props {:x (first mousepos)
|
|
||||||
:y (+ (second mousepos) scroll-top)
|
|
||||||
:width 100
|
|
||||||
:height 100}]
|
|
||||||
(rs/emit!
|
|
||||||
(dw/add-shape shape props)
|
|
||||||
(dw/select-for-drawing nil))))))]
|
|
||||||
(html
|
(html
|
||||||
[:svg.viewport {:width wb/viewport-height
|
[:svg.viewport {:width wb/viewport-height
|
||||||
:height wb/viewport-width
|
:height wb/viewport-width
|
||||||
:class (when drawing? "drawing")
|
:class (when drawing? "drawing")
|
||||||
:on-click #(on-click % workspace)
|
|
||||||
:on-mouse-down on-mouse-down
|
:on-mouse-down on-mouse-down
|
||||||
:on-mouse-up on-mouse-up}
|
:on-mouse-up on-mouse-up}
|
||||||
[:g.zoom {:transform (str "scale(" zoom ", " zoom ")")}
|
[:g.zoom {:transform (str "scale(" zoom ", " zoom ")")}
|
||||||
|
|
86
src/uxbox/ui/workspace/canvas/draw.cljs
Normal file
86
src/uxbox/ui/workspace/canvas/draw.cljs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
(ns uxbox.ui.workspace.canvas.draw
|
||||||
|
(:require-macros [uxbox.util.syntax :refer [define-once]])
|
||||||
|
(:require [sablono.core :as html :refer-macros [html]]
|
||||||
|
[rum.core :as rum]
|
||||||
|
[beicon.core :as rx]
|
||||||
|
[cats.labs.lens :as l]
|
||||||
|
[uxbox.rstore :as rs]
|
||||||
|
[uxbox.state :as st]
|
||||||
|
[uxbox.shapes :as sh]
|
||||||
|
[uxbox.data.workspace :as dw]
|
||||||
|
[uxbox.ui.workspace.base :as wb]
|
||||||
|
[uxbox.ui.mixins :as mx]
|
||||||
|
[uxbox.ui.dom :as dom]))
|
||||||
|
|
||||||
|
(defonce +drawing-shape+ (atom nil))
|
||||||
|
(defonce +drawing-position+ (atom nil))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Component
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn- draw-area-render
|
||||||
|
[own]
|
||||||
|
(let [shape (rum/react +drawing-shape+)
|
||||||
|
[x y] (rum/react +drawing-position+)]
|
||||||
|
(when shape
|
||||||
|
(-> (sh/-resize shape [x y])
|
||||||
|
(sh/-render identity)))))
|
||||||
|
|
||||||
|
(def ^:static draw-area
|
||||||
|
(mx/component
|
||||||
|
{:render draw-area-render
|
||||||
|
:name "draw-area"
|
||||||
|
:mixins [mx/static rum/reactive]}))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Subscriptions
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(define-once :drawing-subscriptions
|
||||||
|
(letfn [(init-shape [shape]
|
||||||
|
(let [[x y :as mpos] @wb/mouse-position
|
||||||
|
stop @wb/scroll-top
|
||||||
|
y (+ stop y)
|
||||||
|
shape (sh/-initialize shape {:x1 x :y1 y :x2 x :y2 y})]
|
||||||
|
(reset! +drawing-shape+ shape)
|
||||||
|
(reset! +drawing-position+ [x y])
|
||||||
|
|
||||||
|
(as-> wb/interactions-b $
|
||||||
|
(rx/filter #(not= % :shape/movement) $)
|
||||||
|
(rx/take 1 $)
|
||||||
|
(rx/take-until $ wb/mouse-s)
|
||||||
|
(rx/subscribe $ on-value nil on-complete))))
|
||||||
|
|
||||||
|
(on-value [[x y :as pos]]
|
||||||
|
(let [stop @wb/scroll-top]
|
||||||
|
(reset! +drawing-position+
|
||||||
|
[x (+ y stop)])))
|
||||||
|
|
||||||
|
(on-complete []
|
||||||
|
(let [shape @+drawing-shape+
|
||||||
|
shpos @+drawing-position+
|
||||||
|
shape (sh/-resize shape shpos)]
|
||||||
|
(rs/emit! (dw/add-shape shape)
|
||||||
|
(dw/select-for-drawing nil))
|
||||||
|
(reset! +drawing-position+ nil)
|
||||||
|
(reset! +drawing-shape+ nil)))
|
||||||
|
|
||||||
|
(init-icon [shape]
|
||||||
|
(let [[x y] @wb/mouse-position
|
||||||
|
stop @wb/scroll-top
|
||||||
|
y (+ stop y)
|
||||||
|
props {:x1 x :y1 y :x2 (+ x 100) :y2 (+ y 100)}
|
||||||
|
shape (sh/-initialize shape props)]
|
||||||
|
(rs/emit! (dw/add-shape shape)
|
||||||
|
(dw/select-for-drawing nil))))
|
||||||
|
(init []
|
||||||
|
(when-let [shape (:drawing @wb/workspace-l)]
|
||||||
|
(case (:type shape)
|
||||||
|
:builtin/icon (init-icon shape)
|
||||||
|
:builtin/line (init-shape shape))))]
|
||||||
|
|
||||||
|
(as-> wb/interactions-b $
|
||||||
|
(rx/dedupe $)
|
||||||
|
(rx/filter #(= :draw/shape %) $)
|
||||||
|
(rx/on-value $ init))))
|
|
@ -7,16 +7,24 @@
|
||||||
[uxbox.ui.workspace.base :as wb]
|
[uxbox.ui.workspace.base :as wb]
|
||||||
[uxbox.data.workspace :as dw]))
|
[uxbox.data.workspace :as dw]))
|
||||||
|
|
||||||
(define-once :mouse-subscriptions
|
(define-once :movement-subscription
|
||||||
(as-> (rx/with-latest-from vector wb/interactions-b wb/mouse-delta-s) $
|
(letfn [(on-value [delta]
|
||||||
(rx/filter #(= (:type (second %)) :shape/movement) $)
|
(let [pageid (get-in @st/state [:workspace :page])
|
||||||
(rx/map first $)
|
selected (get-in @st/state [:workspace :selected])
|
||||||
(rx/on-value $ (fn [delta]
|
shapes (->> (vals @wb/shapes-by-id)
|
||||||
(let [pageid (get-in @st/state [:workspace :page])
|
(filter #(= (:page %) pageid))
|
||||||
selected (get-in @st/state [:workspace :selected])
|
(filter (comp selected :id)))]
|
||||||
shapes (->> (vals @wb/shapes-by-id)
|
(doseq [{:keys [id group]} shapes]
|
||||||
(filter #(= (:page %) pageid))
|
(rs/emit! (dw/move-shape id delta)))))
|
||||||
(filter (comp selected :id)))]
|
|
||||||
(doseq [{:keys [id group]} shapes]
|
|
||||||
(rs/emit! (dw/move-shape id delta))))))))
|
|
||||||
|
|
||||||
|
(init []
|
||||||
|
(as-> wb/interactions-b $
|
||||||
|
(rx/filter #(not= % :shape/movement) $)
|
||||||
|
(rx/take 1 $)
|
||||||
|
(rx/take-until $ wb/mouse-delta-s)
|
||||||
|
(rx/on-value $ on-value)))]
|
||||||
|
|
||||||
|
(as-> wb/interactions-b $
|
||||||
|
(rx/dedupe $)
|
||||||
|
(rx/filter #(= :shape/movement %) $)
|
||||||
|
(rx/on-value $ init))))
|
||||||
|
|
|
@ -58,36 +58,27 @@
|
||||||
:height (- current-y start-y)}))
|
:height (- current-y start-y)}))
|
||||||
|
|
||||||
(define-once :selrect-subscriptions
|
(define-once :selrect-subscriptions
|
||||||
(let [events #{:selrect/draw :nothing}
|
(letfn [(on-value [[x y :as pos]]
|
||||||
ss (as-> wb/interactions-b $
|
(let [scroll (or @wb/scroll-top 0)
|
||||||
(rx/filter #(contains? events (:type %)) $)
|
pos [x (+ y scroll)]]
|
||||||
(rx/dedupe $)
|
(if (nil? @selrect-pos)
|
||||||
(rx/merge (rx/of {:type :nothing}) $)
|
(reset! selrect-pos {:start pos :current pos})
|
||||||
(rx/map (fn [event]
|
(swap! selrect-pos assoc :current pos))))
|
||||||
(case (:type event)
|
|
||||||
:selrect/draw true
|
(on-complete []
|
||||||
:nothing false)) $)
|
(let [selrect (selrect->rect @selrect-pos)]
|
||||||
(rx/buffer 2 1 $)
|
(rs/emit! (dw/select-shapes selrect))
|
||||||
(rx/share $))]
|
(reset! selrect-pos nil)))
|
||||||
(as-> ss $
|
|
||||||
(rx/filter #(= (vec %) [false true]) $)
|
(init []
|
||||||
(rx/with-latest-from vector wb/mouse-s $)
|
(as-> wb/interactions-b $
|
||||||
(rx/on-value $ (fn [[_ [x y :as pos]]]
|
(rx/filter #(not= % :draw/selrect) $)
|
||||||
(let [scroll (or @wb/scroll-top 0)
|
(rx/take 1 $)
|
||||||
pos [x (+ y scroll)]]
|
(rx/take-until $ wb/mouse-s)
|
||||||
(swap! selrect-pos assoc
|
(rx/subscribe $ on-value nil on-complete)))]
|
||||||
:start pos
|
|
||||||
:current pos)))))
|
(as-> wb/interactions-b $
|
||||||
(as-> ss $
|
(rx/dedupe $)
|
||||||
(rx/filter #(= (vec %) [true false]) $)
|
(rx/filter #(= :draw/selrect %) $)
|
||||||
(rx/on-value $ (fn []
|
(rx/on-value $ init))))
|
||||||
(let [selrect (selrect->rect @selrect-pos)]
|
|
||||||
(rs/emit! (dw/select-shapes selrect))
|
|
||||||
(reset! selrect-pos nil)))))
|
|
||||||
(as-> (rx/with-latest-from vector wb/interactions-b wb/mouse-s) $
|
|
||||||
(rx/filter #(= (:type (second %)) :selrect/draw) $)
|
|
||||||
(rx/map first $)
|
|
||||||
(rx/on-value $ (fn [[x y :as pos]]
|
|
||||||
(let [scroll (or @wb/scroll-top 0)
|
|
||||||
pos [x (+ y scroll)]]
|
|
||||||
(swap! selrect-pos assoc :current pos)))))))
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue