0
Fork 0
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:
Andrey Antukh 2016-01-28 20:26:08 +02:00
parent 28047aa64d
commit 32b7bfe383
5 changed files with 139 additions and 66 deletions

View file

@ -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

View file

@ -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 ")")}

View 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))))

View file

@ -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))))

View file

@ -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)))))))