mirror of
https://github.com/penpot/penpot.git
synced 2025-08-01 05:28:28 +02:00
🐛 Fix calculate zoom to avoid bubbles to get outside viewbox (#6138)
* 🐛 Fix calculate zoom to avoid bubbles to get outside vbox * 📎 PR changes
This commit is contained in:
parent
e81adb241b
commit
dc84ab3e41
3 changed files with 55 additions and 11 deletions
|
@ -10,6 +10,7 @@
|
|||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.align :as gal]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.rect :as gpr]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
|
@ -83,6 +84,25 @@
|
|||
(fn [local]
|
||||
(setup state local)))))))
|
||||
|
||||
(defn calculate-centered-viewbox
|
||||
"Updates the viewbox coordinates for a given center position"
|
||||
[local position]
|
||||
(let [vbox (:vbox local)
|
||||
nw (/ (:width vbox) 2)
|
||||
nh (/ (:height vbox) 2)
|
||||
nx (- (:x position) nw)
|
||||
ny (- (:y position) nh)]
|
||||
(update local :vbox assoc :x nx :y ny)))
|
||||
|
||||
(defn update-viewport-position-center
|
||||
[position]
|
||||
(assert (gpt/point? position) "expected a point instance for `position` param")
|
||||
|
||||
(ptk/reify ::update-viewport-position-center
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :workspace-local calculate-centered-viewbox position))))
|
||||
|
||||
(defn update-viewport-position
|
||||
[{:keys [x y] :or {x identity y identity}}]
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn- impl-update-zoom
|
||||
(defn impl-update-zoom
|
||||
[{:keys [vbox] :as local} center zoom]
|
||||
(let [new-zoom (if (fn? zoom) (zoom (:zoom local)) zoom)
|
||||
old-zoom (:zoom local)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
[app.main.data.comments :as dcm]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace.comments :as dwcm]
|
||||
[app.main.data.workspace.viewport :as dwv]
|
||||
[app.main.data.workspace.zoom :as dwz]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
|
@ -1097,15 +1098,35 @@
|
|||
groups))
|
||||
(group-bubbles zoom remaining visited (cons [current] groups)))))))
|
||||
|
||||
(defn- calculate-zoom-scale-to-ungroup-bubbles
|
||||
"Calculate the minimum zoom scale needed for a group of bubbles to avoid overlap among them"
|
||||
[zoom threads]
|
||||
(defn- inside-vbox?
|
||||
"Checks if a bubble or a bubble group is inside a viewbox"
|
||||
[thread-group wl]
|
||||
(let [vbox (:vbox wl)
|
||||
positions (mapv :position thread-group)
|
||||
position (gpt/center-points positions)
|
||||
pos-x (:x position)
|
||||
pos-y (:y position)
|
||||
x1 (:x vbox)
|
||||
y1 (:y vbox)
|
||||
x2 (+ x1 (:width vbox))
|
||||
y2 (+ y1 (:height vbox))]
|
||||
(and (> x2 pos-x x1) (> y2 pos-y y1))))
|
||||
|
||||
(defn- calculate-zoom-scale
|
||||
"Calculates the zoom level needed to ungroup the largest number of bubbles while
|
||||
keeping them all visible in the viewbox."
|
||||
[position zoom threads wl]
|
||||
(let [num-threads (count threads)
|
||||
num-grouped-threads (count (group-bubbles zoom threads))
|
||||
zoom-scale-step 1.75]
|
||||
(if (= num-threads num-grouped-threads)
|
||||
grouped-threads (group-bubbles zoom threads)
|
||||
num-grouped-threads (count grouped-threads)
|
||||
zoom-scale-step 1.75
|
||||
scaled-zoom (* zoom zoom-scale-step)
|
||||
zoomed-wl (dwz/impl-update-zoom wl position scaled-zoom)
|
||||
outside-vbox? (complement inside-vbox?)]
|
||||
(if (or (= num-threads num-grouped-threads)
|
||||
(some #(outside-vbox? % zoomed-wl) grouped-threads))
|
||||
zoom
|
||||
(calculate-zoom-scale-to-ungroup-bubbles (* zoom zoom-scale-step) threads))))
|
||||
(calculate-zoom-scale position scaled-zoom threads zoomed-wl))))
|
||||
|
||||
(mf/defc comment-floating-group*
|
||||
{::mf/wrap [mf/memo]}
|
||||
|
@ -1126,11 +1147,14 @@
|
|||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
(mf/deps thread-group position)
|
||||
(mf/deps thread-group position zoom)
|
||||
(fn []
|
||||
(let [updated-zoom (calculate-zoom-scale-to-ungroup-bubbles zoom thread-group)
|
||||
(let [wl (deref refs/workspace-local)
|
||||
centered-wl (dwv/calculate-centered-viewbox wl position)
|
||||
updated-zoom (calculate-zoom-scale position zoom thread-group centered-wl)
|
||||
scale-zoom (/ updated-zoom zoom)]
|
||||
(st/emit! (dwz/set-zoom position scale-zoom)))))]
|
||||
(st/emit! (dwv/update-viewport-position-center position)
|
||||
(dwz/set-zoom position scale-zoom)))))]
|
||||
|
||||
[:div {:style {:top (dm/str pos-y "px")
|
||||
:left (dm/str pos-x "px")}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue