mirror of
https://github.com/penpot/penpot.git
synced 2025-01-24 07:29:08 -05:00
💅 drag/drop of element libraries in to canvas
This commit is contained in:
parent
c4c9fcf9e9
commit
8b2612559d
5 changed files with 74 additions and 30 deletions
|
@ -100,6 +100,15 @@
|
||||||
color: $color-white;
|
color: $color-white;
|
||||||
padding: $size-2 0;
|
padding: $size-2 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.is-dragging {
|
||||||
|
border-radius: 0;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
& .library-tab-element-name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.library-tab-element-name {
|
.library-tab-element-name {
|
||||||
|
|
|
@ -31,7 +31,8 @@
|
||||||
:text (move-rect shape dpoint)
|
:text (move-rect shape dpoint)
|
||||||
:curve (move-path shape dpoint)
|
:curve (move-path shape dpoint)
|
||||||
:path (move-path shape dpoint)
|
:path (move-path shape dpoint)
|
||||||
:circle (move-circle shape dpoint)))
|
:circle (move-circle shape dpoint)
|
||||||
|
nil))
|
||||||
|
|
||||||
(defn- move-rect
|
(defn- move-rect
|
||||||
"A specialized function for relative movement
|
"A specialized function for relative movement
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
[uxbox.main.ui.shapes.icon :as icon]
|
[uxbox.main.ui.shapes.icon :as icon]
|
||||||
[uxbox.main.ui.workspace.sortable :refer [use-sortable]]
|
[uxbox.main.ui.workspace.sortable :refer [use-sortable]]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
|
[uxbox.util.timers :as timers]
|
||||||
[uxbox.util.uuid :as uuid]
|
[uxbox.util.uuid :as uuid]
|
||||||
[uxbox.util.i18n :as i18n :refer [tr]]
|
[uxbox.util.i18n :as i18n :refer [tr]]
|
||||||
[uxbox.util.data :refer [classnames]]
|
[uxbox.util.data :refer [classnames]]
|
||||||
|
@ -50,11 +51,27 @@
|
||||||
(-> (comp (l/key :library-filter) (l/key section))
|
(-> (comp (l/key :library-filter) (l/key section))
|
||||||
(l/derive st/state)))
|
(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
|
;; --- Components
|
||||||
|
|
||||||
(mf/defc library-tab [{:keys [libraries section]}]
|
(mf/defc library-tab [{:keys [libraries section]}]
|
||||||
(when (and libraries (-> libraries count (> 0)))
|
(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)]
|
current-selection (or (mf/deref (selected-library-ref section)) first-id)]
|
||||||
|
|
||||||
;; Check if the current selection is in the list of libraries
|
;; Check if the current selection is in the list of libraries
|
||||||
|
@ -82,33 +99,23 @@
|
||||||
[:div.library-tab-content
|
[:div.library-tab-content
|
||||||
(let [items (mf/deref (selected-items-ref section current-selection))]
|
(let [items (mf/deref (selected-items-ref section current-selection))]
|
||||||
(for [item items]
|
(for [item items]
|
||||||
(if (= section :icons)
|
|
||||||
;; ICONS
|
|
||||||
[:div.library-tab-element
|
[:div.library-tab-element
|
||||||
{:key (str "icon-" (:id item))
|
{:draggable true
|
||||||
:on-click #(st/emit! (dw/select-for-drawing :icon item))}
|
: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 " "))
|
[:svg {:view-box (->> item :metadata :view-box (str/join " "))
|
||||||
:width (-> item :metadata :width)
|
:width (-> item :metadata :width)
|
||||||
:height (-> item :metadat :height)
|
:height (-> item :metadat :height)
|
||||||
:dangerouslySetInnerHTML {:__html (:content item)}}]
|
:dangerouslySetInnerHTML {:__html (:content item)}}]
|
||||||
[:span.library-tab-element-name (:name item)]]
|
[:img {:draggable false
|
||||||
|
:src (:thumb-uri item)}])
|
||||||
;; IMAGES
|
[:span.library-tab-element-name (:name item)]]))]])))
|
||||||
[: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)]])
|
|
||||||
))]])))
|
|
||||||
|
|
||||||
(mf/defc libraries-toolbox
|
(mf/defc libraries-toolbox
|
||||||
[{:keys [key]}]
|
[{:keys [key]}]
|
||||||
|
|
|
@ -234,8 +234,7 @@
|
||||||
|
|
||||||
on-mouse-move
|
on-mouse-move
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(let [pt (gpt/point (.-clientX event)
|
(let [pt (gpt/point (.-clientX event) (.-clientY event))
|
||||||
(.-clientY event))
|
|
||||||
pt (translate-point-to-viewport pt)]
|
pt (translate-point-to-viewport pt)]
|
||||||
(st/emit! (ms/->PointerEvent :viewport pt
|
(st/emit! (ms/->PointerEvent :viewport pt
|
||||||
(kbd/ctrl? event)
|
(kbd/ctrl? event)
|
||||||
|
@ -251,7 +250,22 @@
|
||||||
(events/unlistenByKey key1)
|
(events/unlistenByKey key1)
|
||||||
(events/unlistenByKey key2)
|
(events/unlistenByKey key2)
|
||||||
(events/unlistenByKey key3)
|
(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)
|
(mf/use-effect on-mount)
|
||||||
[:*
|
[:*
|
||||||
|
@ -264,7 +278,9 @@
|
||||||
:on-click on-click
|
:on-click on-click
|
||||||
:on-double-click on-double-click
|
:on-double-click on-double-click
|
||||||
:on-mouse-down on-mouse-down
|
: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 ")")}
|
[:g.zoom {:transform (str "scale(" zoom ", " zoom ")")}
|
||||||
;; [:> js/React.Profiler
|
;; [:> js/React.Profiler
|
||||||
;; {:id "foobar"
|
;; {:id "foobar"
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[uxbox.util.geom.point :as gpt]
|
[uxbox.util.geom.point :as gpt]
|
||||||
[uxbox.util.blob :as blob]))
|
[uxbox.util.blob :as blob]
|
||||||
|
[uxbox.util.transit :as ts]))
|
||||||
|
|
||||||
;; --- Deprecated methods
|
;; --- Deprecated methods
|
||||||
|
|
||||||
|
@ -146,3 +147,13 @@
|
||||||
[node]
|
[node]
|
||||||
(.focus 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)))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue