mirror of
https://github.com/penpot/penpot.git
synced 2025-01-22 14:39:45 -05:00
✨ Improved mouse collision detection for groups and text shapes
This commit is contained in:
parent
0d48c758df
commit
c5c0b36f28
5 changed files with 44 additions and 4 deletions
|
@ -23,6 +23,7 @@
|
|||
- Create first E2E tests [Taiga #2608](https://tree.taiga.io/project/penpot/task/2608), [Taiga #2608](https://tree.taiga.io/project/penpot/task/2608)
|
||||
- Redesign of workspace toolbars [Taiga #2319](https://tree.taiga.io/project/penpot/us/2319)
|
||||
- Graphic Tablet usability improvements [Taiga #1913](https://tree.taiga.io/project/penpot/us/1913)
|
||||
- Improved mouse collision detection for groups and text shapes [Taiga #2452](https://tree.taiga.io/project/penpot/us/2452), [Taiga #2453](https://tree.taiga.io/project/penpot/us/2453)
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
|
||||
;; REFS
|
||||
viewport-ref (mf/use-ref nil)
|
||||
raw-position-ref (mf/use-ref nil) ;; Stores the raw position of the cursor
|
||||
|
||||
;; VARS
|
||||
disable-paste (mf/use-var false)
|
||||
|
@ -127,7 +128,7 @@
|
|||
on-pointer-down (actions/on-pointer-down)
|
||||
on-pointer-enter (actions/on-pointer-enter in-viewport?)
|
||||
on-pointer-leave (actions/on-pointer-leave in-viewport?)
|
||||
on-pointer-move (actions/on-pointer-move viewport-ref zoom move-stream)
|
||||
on-pointer-move (actions/on-pointer-move viewport-ref raw-position-ref zoom move-stream)
|
||||
on-pointer-up (actions/on-pointer-up)
|
||||
on-move-selected (actions/on-move-selected hover hover-ids selected space?)
|
||||
on-menu-selected (actions/on-menu-selected hover hover-ids selected)
|
||||
|
@ -164,7 +165,7 @@
|
|||
(hooks/setup-viewport-size viewport-ref)
|
||||
(hooks/setup-cursor cursor alt? ctrl? space? panning drawing-tool drawing-path? node-editing?)
|
||||
(hooks/setup-keyboard alt? ctrl? space?)
|
||||
(hooks/setup-hover-shapes page-id move-stream base-objects transform selected ctrl? hover hover-ids @hover-disabled? zoom)
|
||||
(hooks/setup-hover-shapes page-id move-stream raw-position-ref base-objects transform selected ctrl? hover hover-ids @hover-disabled? zoom)
|
||||
(hooks/setup-viewport-modifiers modifiers base-objects)
|
||||
(hooks/setup-shortcuts node-editing? drawing-path?)
|
||||
(hooks/setup-active-frames base-objects vbox hover active-frames)
|
||||
|
|
|
@ -346,13 +346,14 @@
|
|||
(kbd/shift? event)
|
||||
(kbd/alt? event))))))))
|
||||
|
||||
(defn on-pointer-move [viewport-ref zoom move-stream]
|
||||
(defn on-pointer-move [viewport-ref raw-position-ref zoom move-stream]
|
||||
(mf/use-callback
|
||||
(mf/deps zoom move-stream)
|
||||
(fn [event]
|
||||
(let [raw-pt (dom/get-client-position event)
|
||||
viewport (mf/ref-val viewport-ref)
|
||||
pt (utils/translate-point-to-viewport viewport zoom raw-pt)]
|
||||
(mf/set-ref-val! raw-position-ref raw-pt)
|
||||
(rx/push! move-stream pt)))))
|
||||
|
||||
(defn on-mouse-wheel [viewport-ref zoom]
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.rect :as gshr]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.main.data.shortcuts :as dsc]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
@ -84,7 +85,30 @@
|
|||
(hooks/use-stream ms/keyboard-ctrl #(reset! ctrl? %))
|
||||
(hooks/use-stream ms/keyboard-space #(reset! space? %)))
|
||||
|
||||
(defn setup-hover-shapes [page-id move-stream objects transform selected ctrl? hover hover-ids hover-disabled? zoom]
|
||||
(defn group-empty-space?
|
||||
"Given a group `group-id` check if `hover-ids` contains any of its children. If it doesn't means
|
||||
we're hovering over empty space for the group "
|
||||
[group-id objects hover-ids]
|
||||
|
||||
(and (contains? #{:group :bool} (get-in objects [group-id :type]))
|
||||
|
||||
;; If there are no children in the hover-ids we're in the empty side
|
||||
(->> hover-ids
|
||||
(remove #(contains? #{:group :bool} (get-in objects [% :type])))
|
||||
(some #(cph/is-parent? objects % group-id))
|
||||
(not))))
|
||||
|
||||
(defn check-text-collision?
|
||||
"Checks if he current position `pos` overlaps any of the text-nodes for the given `text-id`"
|
||||
[objects pos text-id]
|
||||
(and (= :text (get-in objects [text-id :type]))
|
||||
(let [collisions
|
||||
(->> (dom/query-all (str "#shape-" text-id " .text-node"))
|
||||
(map dom/get-bounding-rect)
|
||||
(map dom/bounding-rect->rect))]
|
||||
(not (some #(gshr/contains-point? % pos) collisions)))))
|
||||
|
||||
(defn setup-hover-shapes [page-id move-stream raw-position-ref objects transform selected ctrl? hover hover-ids hover-disabled? zoom]
|
||||
(let [;; We use ref so we don't recreate the stream on a change
|
||||
zoom-ref (mf/use-ref zoom)
|
||||
ctrl-ref (mf/use-ref @ctrl?)
|
||||
|
@ -156,6 +180,12 @@
|
|||
|
||||
remove-xfm (mapcat #(cph/get-parent-ids objects %))
|
||||
remove-id? (cond-> (into #{} remove-xfm selected)
|
||||
:always
|
||||
(into (filter #(check-text-collision? objects (mf/ref-val raw-position-ref) %)) ids)
|
||||
|
||||
(not @ctrl?)
|
||||
(into (filter #(group-empty-space? % objects ids)) ids)
|
||||
|
||||
@ctrl?
|
||||
(into (filter is-group?) ids))
|
||||
|
||||
|
|
|
@ -257,6 +257,13 @@
|
|||
:width (.-width ^js rect)
|
||||
:height (.-height ^js rect)}))
|
||||
|
||||
(defn bounding-rect->rect
|
||||
[{:keys [left top width height]}]
|
||||
{:x left
|
||||
:y top
|
||||
:width width
|
||||
:height height})
|
||||
|
||||
(defn get-window-size
|
||||
[]
|
||||
{:width (.-innerWidth ^js js/window)
|
||||
|
|
Loading…
Add table
Reference in a new issue