From 491251f5ceb1c168b91a9ccea32a9c182636212d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Tue, 11 Jul 2023 20:15:20 +0200 Subject: [PATCH] :bug: Fix overlay position with elements fixed when scrolling --- CHANGES.md | 1 + .../app/common/types/shape/interactions.cljc | 9 ++- .../src/app/main/ui/viewer/interactions.cljs | 18 ++++-- frontend/src/app/main/ui/viewer/shapes.cljs | 59 ++++++++++--------- 4 files changed, 48 insertions(+), 39 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 44d750ebdc..079eb62910 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -66,6 +66,7 @@ - Fix overlay manual position in nested boards [Taiga #5135](https://tree.taiga.io/project/penpot/issue/5135) - Fix close overlay from a nested board [Taiga #5587](https://tree.taiga.io/project/penpot/issue/5587) - Fix overlay position when it has shadow or blur [Taiga #4752](https://tree.taiga.io/project/penpot/issue/4752) +- Fix overlay position when there are elements fixed when scrolling [Taiga #4383](https://tree.taiga.io/project/penpot/issue/4383) ### :arrow_up: Deps updates diff --git a/common/src/app/common/types/shape/interactions.cljc b/common/src/app/common/types/shape/interactions.cljc index 61ef1ebeae..162222c307 100644 --- a/common/src/app/common/types/shape/interactions.cljc +++ b/common/src/app/common/types/shape/interactions.cljc @@ -495,8 +495,7 @@ "expected compatible interaction map" (has-overlay-opts interaction)) - (let [ - ;; When the interactive item is inside a nested frame we need to add to the offset the position + (let [;; When the interactive item is inside a nested frame we need to add to the offset the position ;; of the parent-frame otherwise the position won't match shape-frame (cph/get-frame objects shape) @@ -505,10 +504,10 @@ (cph/root-frame? shape-frame) (cph/root? shape-frame)) frame-offset - (gpt/add frame-offset (gpt/point shape-frame))) - ] + (gpt/add frame-offset (gpt/point shape-frame)))] + (if (nil? dest-frame) - (gpt/point 0 0) + [(gpt/point 0 0) [:top :left]] (let [overlay-size (gsb/get-object-bounds objects dest-frame) base-frame-size (:selrect base-frame) relative-to-shape-size (:selrect relative-to-shape) diff --git a/frontend/src/app/main/ui/viewer/interactions.cljs b/frontend/src/app/main/ui/viewer/interactions.cljs index a3419e419a..deab4db369 100644 --- a/frontend/src/app/main/ui/viewer/interactions.cljs +++ b/frontend/src/app/main/ui/viewer/interactions.cljs @@ -71,18 +71,24 @@ (d/index-by :id) (prepare-objects frame size delta))) - wrapper-fixed (mf/with-memo [page frame size] - (shapes/frame-container-factory (calculate-objects fixed-ids))) + objects-fixed (mf/with-memo [fixed-ids page frame size delta] + (calculate-objects fixed-ids)) - objects-not-fixed (mf/with-memo [page frame size] + objects-not-fixed (mf/with-memo [not-fixed-ids page frame size delta] (calculate-objects not-fixed-ids)) + all-objects (mf/with-memo [objects-fixed objects-not-fixed] + (merge objects-fixed objects-not-fixed)) + + wrapper-fixed (mf/with-memo [page frame size] + (shapes/frame-container-factory objects-fixed all-objects)) + wrapper-not-fixed (mf/with-memo [objects-not-fixed] - (shapes/frame-container-factory objects-not-fixed)) + (shapes/frame-container-factory objects-not-fixed all-objects)) ;; Retrieve frames again with correct modifier - frame (get objects-not-fixed (:id frame)) - base (get objects-not-fixed (:id base)) + frame (get all-objects (:id frame)) + base (get all-objects (:id base)) non-delay-interactions (->> (:interactions frame) (filterv #(not= (:event-type %) :after-delay))) diff --git a/frontend/src/app/main/ui/viewer/shapes.cljs b/frontend/src/app/main/ui/viewer/shapes.cljs index ccc6663ce0..13f9c10481 100644 --- a/frontend/src/app/main/ui/viewer/shapes.cljs +++ b/frontend/src/app/main/ui/viewer/shapes.cljs @@ -92,7 +92,7 @@ (if (= (:type shape) :frame) ;; manual interactions are always from "self" (:frame-id shape) (:id shape)) - (:position-relative-to interaction)) + (:position-relative-to interaction)) relative-to-shape (or (get objects relative-to-id) base-frame) overlays-ids (set (map :id overlays)) relative-to-base-frame (find-relative-to-base-frame relative-to-shape objects overlays-ids base-frame) @@ -285,6 +285,7 @@ childs (unchecked-get props "childs") frame (unchecked-get props "frame") objects (unchecked-get props "objects") + all-objects (or (unchecked-get props "all-objects") objects) base-frame (mf/use-ctx base-frame-ctx) frame-offset (mf/use-ctx frame-offset-ctx) interactions-show? (mf/deref viewer-interactions-show?) @@ -293,25 +294,25 @@ svg-element? (and (= :svg-raw (:type shape)) (not= :svg (get-in shape [:content :tag]))) - ;; _ (js/console.log "======" (:name shape)) - ;; _ (js/console.log "shape" (clj->js shape)) - ;; _ (js/console.log "frame-offset" (clj->js frame-offset)) + ;; The objects parameter has the shapes that we must draw. It may be a subset of + ;; all-objects in some cases (e.g. if there are fixed elements). But for interactions + ;; handling we need access to all objects inside the page. + on-pointer-down - (mf/use-fn (mf/deps shape base-frame frame-offset objects) - #(on-pointer-down % shape base-frame frame-offset objects overlays)) + (mf/use-fn (mf/deps shape base-frame frame-offset all-objects) + #(on-pointer-down % shape base-frame frame-offset all-objects overlays)) on-pointer-up - (mf/use-fn (mf/deps shape base-frame frame-offset objects) - #(on-pointer-up % shape base-frame frame-offset objects overlays)) + (mf/use-fn (mf/deps shape base-frame frame-offset all-objects) + #(on-pointer-up % shape base-frame frame-offset all-objects overlays)) on-pointer-enter - (mf/use-fn (mf/deps shape base-frame frame-offset objects) - #(on-pointer-enter % shape base-frame frame-offset objects overlays)) + (mf/use-fn (mf/deps shape base-frame frame-offset all-objects) + #(on-pointer-enter % shape base-frame frame-offset all-objects overlays)) on-pointer-leave - (mf/use-fn (mf/deps shape base-frame frame-offset objects) - #(on-pointer-leave % shape base-frame frame-offset objects overlays))] - + (mf/use-fn (mf/deps shape base-frame frame-offset all-objects) + #(on-pointer-leave % shape base-frame frame-offset all-objects overlays))] (mf/with-effect [] (let [sems (on-load shape base-frame frame-offset objects overlays)] @@ -380,8 +381,8 @@ (declare shape-container-factory) (defn frame-container-factory - [objects] - (let [shape-container (shape-container-factory objects) + [objects all-objects] + (let [shape-container (shape-container-factory objects all-objects) frame-wrapper (frame-wrapper shape-container)] (mf/fnc frame-container {::mf/wrap-props false} @@ -391,13 +392,14 @@ props (obj/merge! #js {} props #js {:shape shape :childs childs - :objects objects})] + :objects objects + :all-objects all-objects})] [:> frame-wrapper props])))) (defn group-container-factory - [objects] - (let [shape-container (shape-container-factory objects) + [objects all-objects] + (let [shape-container (shape-container-factory objects all-objects) group-wrapper (group-wrapper shape-container)] (mf/fnc group-container {::mf/wrap-props false} @@ -410,8 +412,8 @@ [:> group-wrapper props]))))) (defn bool-container-factory - [objects] - (let [shape-container (shape-container-factory objects) + [objects all-objects] + (let [shape-container (shape-container-factory objects all-objects) bool-wrapper (bool-wrapper shape-container)] (mf/fnc bool-container {::mf/wrap-props false} @@ -424,8 +426,8 @@ [:> bool-wrapper props])))) (defn svg-raw-container-factory - [objects] - (let [shape-container (shape-container-factory objects) + [objects all-objects] + (let [shape-container (shape-container-factory objects all-objects) svg-raw-wrapper (svg-raw-wrapper shape-container)] (mf/fnc svg-raw-container {::mf/wrap-props false} @@ -437,7 +439,7 @@ [:> svg-raw-wrapper props])))) (defn shape-container-factory - [objects] + [objects all-objects] (let [path-wrapper (path-wrapper) text-wrapper (text-wrapper) rect-wrapper (rect-wrapper) @@ -452,26 +454,27 @@ group-container (mf/with-memo [objects] - (group-container-factory objects)) + (group-container-factory objects all-objects)) frame-container (mf/with-memo [objects] - (frame-container-factory objects)) + (frame-container-factory objects all-objects)) bool-container (mf/with-memo [objects] - (bool-container-factory objects)) + (bool-container-factory objects all-objects)) svg-raw-container (mf/with-memo [objects] - (svg-raw-container-factory objects))] + (svg-raw-container-factory objects all-objects))] (when (and shape (not (:hidden shape))) (let [shape (-> shape #_(gsh/transform-shape) (gsh/translate-to-frame frame)) opts #js {:shape shape - :objects objects}] + :objects objects + :all-objects all-objects}] (case (:type shape) :frame [:> frame-container opts] :text [:> text-wrapper opts]