diff --git a/common/src/app/common/geom/align.cljc b/common/src/app/common/geom/align.cljc index e7b8bcc518..2d27e74c79 100644 --- a/common/src/app/common/geom/align.cljc +++ b/common/src/app/common/geom/align.cljc @@ -124,33 +124,51 @@ (defn adjust-to-viewport ([viewport srect] (adjust-to-viewport viewport srect nil)) - ([viewport srect {:keys [padding] :or {padding 0}}] + ([viewport srect {:keys [padding min-zoom] :or {padding 0 min-zoom nil}}] (let [gprop (/ (:width viewport) (:height viewport)) - srect (-> srect - (update :x #(- % padding)) - (update :y #(- % padding)) - (update :width #(+ % padding padding)) - (update :height #(+ % padding padding))) - width (:width srect) - height (:height srect) - lprop (/ width height)] - (cond - (> gprop lprop) - (let [width' (* (/ width lprop) gprop) - padding (/ (- width' width) 2)] - (-> srect - (update :x #(- % padding)) - (assoc :width width') - (grc/update-rect :position))) + srect-padded (-> srect + (update :x #(- % padding)) + (update :y #(- % padding)) + (update :width #(+ % padding padding)) + (update :height #(+ % padding padding))) + width (:width srect-padded) + height (:height srect-padded) + lprop (/ width height) + adjusted-rect + (cond + (> gprop lprop) + (let [width' (* (/ width lprop) gprop) + padding (/ (- width' width) 2)] + (-> srect-padded + (update :x #(- % padding)) + (assoc :width width') + (grc/update-rect :position))) - (< gprop lprop) - (let [height' (/ (* height lprop) gprop) - padding (/ (- height' height) 2)] - (-> srect - (update :y #(- % padding)) - (assoc :height height') - (grc/update-rect :position))) + (< gprop lprop) + (let [height' (/ (* height lprop) gprop) + padding (/ (- height' height) 2)] + (-> srect-padded + (update :y #(- % padding)) + (assoc :height height') + (grc/update-rect :position))) - :else - (grc/update-rect srect :position))))) + :else + (grc/update-rect srect-padded :position))] + ;; If min-zoom is specified and the resulting zoom would be below it, + ;; return a rect with the original top-left corner centered in the viewport + ;; instead of using the aspect-ratio-adjusted rect (which can push coords + ;; extremely far with extreme aspect ratios). + (if (and (some? min-zoom) + (< (/ (:width viewport) (:width adjusted-rect)) min-zoom)) + (let [anchor-x (:x srect) + anchor-y (:y srect) + vbox-width (/ (:width viewport) min-zoom) + vbox-height (/ (:height viewport) min-zoom)] + (-> adjusted-rect + (assoc :x (- anchor-x (/ vbox-width 2)) + :y (- anchor-y (/ vbox-height 2)) + :width vbox-width + :height vbox-height) + (grc/update-rect :position))) + adjusted-rect)))) diff --git a/frontend/src/app/main/data/workspace/viewport.cljs b/frontend/src/app/main/data/workspace/viewport.cljs index 79da7ba477..2687bb9113 100644 --- a/frontend/src/app/main/data/workspace/viewport.cljs +++ b/frontend/src/app/main/data/workspace/viewport.cljs @@ -51,7 +51,7 @@ (or (> (:width srect) width) (> (:height srect) height)) - (let [srect (gal/adjust-to-viewport size srect {:padding 40}) + (let [srect (gal/adjust-to-viewport size srect {:padding 40 :min-zoom 0.01}) zoom (/ (:width size) (:width srect))] (-> local diff --git a/frontend/src/app/main/data/workspace/zoom.cljs b/frontend/src/app/main/data/workspace/zoom.cljs index fbdd24a344..33f1846407 100644 --- a/frontend/src/app/main/data/workspace/zoom.cljs +++ b/frontend/src/app/main/data/workspace/zoom.cljs @@ -97,7 +97,7 @@ state (update state :workspace-local (fn [{:keys [vport] :as local}] - (let [srect (gal/adjust-to-viewport vport srect {:padding 160}) + (let [srect (gal/adjust-to-viewport vport srect {:padding 160 :min-zoom 0.01}) zoom (/ (:width vport) (:width srect))] (-> local (assoc :zoom zoom) @@ -118,7 +118,7 @@ (gsh/shapes->rect))] (update state :workspace-local (fn [{:keys [vport] :as local}] - (let [srect (gal/adjust-to-viewport vport srect {:padding 40}) + (let [srect (gal/adjust-to-viewport vport srect {:padding 40 :min-zoom 0.01}) zoom (/ (:width vport) (:width srect))] (-> local (assoc :zoom zoom) @@ -142,7 +142,7 @@ (fn [{:keys [vport] :as local}] (let [srect (gal/adjust-to-viewport vport srect - {:padding 40}) + {:padding 40 :min-zoom 0.01}) zoom (/ (:width vport) (:width srect))] (-> local