mirror of
https://github.com/penpot/penpot.git
synced 2025-08-07 14:38:33 +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.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.geom.align :as gal]
|
[app.common.geom.align :as gal]
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.rect :as gpr]
|
[app.common.geom.rect :as gpr]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
|
@ -83,6 +84,25 @@
|
||||||
(fn [local]
|
(fn [local]
|
||||||
(setup state 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
|
(defn update-viewport-position
|
||||||
[{:keys [x y] :or {x identity y identity}}]
|
[{:keys [x y] :or {x identity y identity}}]
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
(defn- impl-update-zoom
|
(defn impl-update-zoom
|
||||||
[{:keys [vbox] :as local} center zoom]
|
[{:keys [vbox] :as local} center zoom]
|
||||||
(let [new-zoom (if (fn? zoom) (zoom (:zoom local)) zoom)
|
(let [new-zoom (if (fn? zoom) (zoom (:zoom local)) zoom)
|
||||||
old-zoom (:zoom local)
|
old-zoom (:zoom local)
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
[app.main.data.comments :as dcm]
|
[app.main.data.comments :as dcm]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.workspace.comments :as dwcm]
|
[app.main.data.workspace.comments :as dwcm]
|
||||||
|
[app.main.data.workspace.viewport :as dwv]
|
||||||
[app.main.data.workspace.zoom :as dwz]
|
[app.main.data.workspace.zoom :as dwz]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -1097,15 +1098,35 @@
|
||||||
groups))
|
groups))
|
||||||
(group-bubbles zoom remaining visited (cons [current] groups)))))))
|
(group-bubbles zoom remaining visited (cons [current] groups)))))))
|
||||||
|
|
||||||
(defn- calculate-zoom-scale-to-ungroup-bubbles
|
(defn- inside-vbox?
|
||||||
"Calculate the minimum zoom scale needed for a group of bubbles to avoid overlap among them"
|
"Checks if a bubble or a bubble group is inside a viewbox"
|
||||||
[zoom threads]
|
[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)
|
(let [num-threads (count threads)
|
||||||
num-grouped-threads (count (group-bubbles zoom threads))
|
grouped-threads (group-bubbles zoom threads)
|
||||||
zoom-scale-step 1.75]
|
num-grouped-threads (count grouped-threads)
|
||||||
(if (= num-threads num-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
|
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/defc comment-floating-group*
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
|
@ -1126,11 +1147,14 @@
|
||||||
|
|
||||||
on-click
|
on-click
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps thread-group position)
|
(mf/deps thread-group position zoom)
|
||||||
(fn []
|
(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)]
|
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")
|
[:div {:style {:top (dm/str pos-y "px")
|
||||||
:left (dm/str pos-x "px")}
|
:left (dm/str pos-x "px")}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue