0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-23 23:18:48 -05:00

💅 drag/drop of element libraries in to canvas

This commit is contained in:
alonso.torres 2020-03-27 14:42:34 +01:00
parent c4c9fcf9e9
commit 8b2612559d
5 changed files with 74 additions and 30 deletions

View file

@ -100,6 +100,15 @@
color: $color-white;
padding: $size-2 0;
}
&.is-dragging {
border-radius: 0;
border: none;
& .library-tab-element-name {
display: none;
}
}
}
.library-tab-element-name {

View file

@ -31,7 +31,8 @@
:text (move-rect shape dpoint)
:curve (move-path shape dpoint)
:path (move-path shape dpoint)
:circle (move-circle shape dpoint)))
:circle (move-circle shape dpoint)
nil))
(defn- move-rect
"A specialized function for relative movement

View file

@ -21,6 +21,7 @@
[uxbox.main.ui.shapes.icon :as icon]
[uxbox.main.ui.workspace.sortable :refer [use-sortable]]
[uxbox.util.dom :as dom]
[uxbox.util.timers :as timers]
[uxbox.util.uuid :as uuid]
[uxbox.util.i18n :as i18n :refer [tr]]
[uxbox.util.data :refer [classnames]]
@ -50,11 +51,27 @@
(-> (comp (l/key :library-filter) (l/key section))
(l/derive st/state)))
(defmulti shape-from-item (fn [type _] type))
(defmethod shape-from-item :icons [_ item]
(-> item
(assoc :type :icon)
(assoc :width (-> item :metadata :width))
(assoc :height (-> item :metadata :height))))
(defmethod shape-from-item :images [_ item]
(let [metadata (select-keys item [:width :height :thumb-width
:thumb-height :thumb-uri :uri])]
(-> item
(assoc :type :image)
(assoc :metadata metadata))))
;; --- Components
(mf/defc library-tab [{:keys [libraries section]}]
(when (and libraries (-> libraries count (> 0)))
(let [first-id (-> libraries first :id)
(let [state (mf/use-state {:drag-style false})
first-id (-> libraries first :id)
current-selection (or (mf/deref (selected-library-ref section)) first-id)]
;; Check if the current selection is in the list of libraries
@ -82,33 +99,23 @@
[:div.library-tab-content
(let [items (mf/deref (selected-items-ref section current-selection))]
(for [item items]
(if (= section :icons)
;; ICONS
[:div.library-tab-element
{:key (str "icon-" (:id item))
:on-click #(st/emit! (dw/select-for-drawing :icon item))}
[:div.library-tab-element
{:draggable true
:class (classnames :is-dragging (:drag-style @state))
:key (str (:id item))
:on-drag-start (fn [event]
(swap! state assoc :drag-style true)
(dom/set-data-transfer event (shape-from-item section item))
;; This state is so we can give custom css to the dragging
(timers/schedule #(swap! state assoc :drag-style false)))}
(if (= section :icons)
[:svg {:view-box (->> item :metadata :view-box (str/join " "))
:width (-> item :metadata :width)
:height (-> item :metadat :height)
:dangerouslySetInnerHTML {:__html (:content item)}}]
[:span.library-tab-element-name (:name item)]]
;; IMAGES
[:div.library-tab-element
{:key (str "image-" (:id item))
:on-click #(let [shape {:name name
:metadata {:width (:width item)
:height (:height item)
:uri (:uri item)
:thumb-width (:thumb-width item)
:thumb-height (:thumb-height item)
:thumb-uri (:thumb-uri item)}}]
(st/emit! (dw/select-for-drawing :image shape)))}
[:img {:src (:thumb-uri item)}]
[:span.library-tab-element-name (:name item)]])
))]])))
[:img {:draggable false
:src (:thumb-uri item)}])
[:span.library-tab-element-name (:name item)]]))]])))
(mf/defc libraries-toolbox
[{:keys [key]}]

View file

@ -234,8 +234,7 @@
on-mouse-move
(fn [event]
(let [pt (gpt/point (.-clientX event)
(.-clientY event))
(let [pt (gpt/point (.-clientX event) (.-clientY event))
pt (translate-point-to-viewport pt)]
(st/emit! (ms/->PointerEvent :viewport pt
(kbd/ctrl? event)
@ -251,7 +250,22 @@
(events/unlistenByKey key1)
(events/unlistenByKey key2)
(events/unlistenByKey key3)
)))]
)))
on-drag-over
;; Should prevent only events that we'll handle on-drop
(fn [e] (dom/prevent-default e))
on-drop
(fn [event]
(let [shape (dom/get-data-transfer event)
point (gpt/point (.-clientX event) (.-clientY event))
viewport-coord (translate-point-to-viewport point)
final-x (- (:x viewport-coord) (/ (:width shape) 2))
final-y (- (:y viewport-coord) (/ (:height shape) 2))]
(st/emit! (dw/add-shape (-> shape
(assoc :x final-x)
(assoc :y final-y))))))]
(mf/use-effect on-mount)
[:*
@ -264,7 +278,9 @@
:on-click on-click
:on-double-click on-double-click
:on-mouse-down on-mouse-down
:on-mouse-up on-mouse-up}
:on-mouse-up on-mouse-up
:on-drag-over on-drag-over
:on-drop on-drop}
[:g.zoom {:transform (str "scale(" zoom ", " zoom ")")}
;; [:> js/React.Profiler
;; {:id "foobar"

View file

@ -15,7 +15,8 @@
[beicon.core :as rx]
[cuerdas.core :as str]
[uxbox.util.geom.point :as gpt]
[uxbox.util.blob :as blob]))
[uxbox.util.blob :as blob]
[uxbox.util.transit :as ts]))
;; --- Deprecated methods
@ -146,3 +147,13 @@
[node]
(.focus node))
(defn set-data-transfer
[event data]
(let [data-string (ts/encode data)]
(-> event .-dataTransfer (.setData "text" data-string))))
(defn get-data-transfer
[event]
(let [data-string (-> event .-dataTransfer (.getData "text"))]
(ts/decode data-string)))