0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-13 10:38:13 -05:00

Merge pull request #3093 from penpot/alotor-bugfixing-14

Alotor bugfixing 14
This commit is contained in:
Alejandro 2023-03-31 13:56:25 +02:00 committed by GitHub
commit cc469b116d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 198 additions and 177 deletions

View file

@ -133,29 +133,38 @@
(-> (get-shape-filter-bounds shape) (-> (get-shape-filter-bounds shape)
(add-padding (calculate-padding shape true)))) (add-padding (calculate-padding shape true))))
bounds (if (or (:masked-group? shape) bounds
(and (cph/frame-shape? shape) (cond
(not (:show-content shape)))) (empty? (:shapes shape))
[(calculate-base-bounds shape)] [(calculate-base-bounds shape)]
(cph/reduce-objects
objects
(fn [shape]
(and (d/not-empty? (:shapes shape))
(or (not (cph/frame-shape? shape))
(:show-content shape))
(or (not (cph/group-shape? shape)) (:masked-group? shape)
(not (:masked-group? shape))))) [(calculate-base-bounds shape)]
(:id shape) (and (cph/frame-shape? shape) (not (:show-content shape)))
[(calculate-base-bounds shape)]
(fn [result shape] :else
(conj result (get-object-bounds objects shape))) (cph/reduce-objects
objects
(fn [shape]
(and (d/not-empty? (:shapes shape))
(or (not (cph/frame-shape? shape))
(:show-content shape))
[(calculate-base-bounds shape)])) (or (not (cph/group-shape? shape))
(not (:masked-group? shape)))))
children-bounds (cond->> (gsr/join-selrects bounds) (:id shape)
(not (cph/frame-shape? shape)) (or (:children-bounds shape)))
(fn [result child]
(conj result (calculate-base-bounds child)))
[(calculate-base-bounds shape)]))
children-bounds
(cond->> (gsr/join-selrects bounds)
(not (cph/frame-shape? shape)) (or (:children-bounds shape)))
filters (shape->filters shape) filters (shape->filters shape)
blur-value (or (-> shape :blur :value) 0)] blur-value (or (-> shape :blur :value) 0)]

View file

@ -552,19 +552,22 @@
(loop [current-val init-val (loop [current-val init-val
current-id (first root-children) current-id (first root-children)
pending-ids (rest root-children)] pending-ids (rest root-children)
processed #{}]
(if (contains? processed current-id)
(recur current-val (first pending-ids) (rest pending-ids) processed)
(let [current-shape (get objects current-id)
processed (conj processed current-id)
next-val (reducer-fn current-val current-shape)
next-pending-ids
(if (or (nil? check-children?) (check-children? current-shape))
(concat (or (:shapes current-shape) []) pending-ids)
pending-ids)]
(let [current-shape (get objects current-id) (if (empty? next-pending-ids)
next-val (reducer-fn current-val current-shape) next-val
next-pending-ids (recur next-val (first next-pending-ids) (rest next-pending-ids) processed)))))))))
(if (or (nil? check-children?) (check-children? current-shape))
(concat (or (:shapes current-shape) []) pending-ids)
pending-ids)]
(if (empty? next-pending-ids)
next-val
(recur next-val (first next-pending-ids) (rest next-pending-ids)))))))))
(defn selected-with-children (defn selected-with-children
[objects selected] [objects selected]

View file

@ -9,6 +9,7 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes.bounds :as gsb] [app.common.geom.shapes.bounds :as gsb]
[app.common.pages.helpers :as cph]
[app.common.spec :as us] [app.common.spec :as us]
[clojure.spec.alpha :as s])) [clojure.spec.alpha :as s]))
@ -363,6 +364,7 @@
(defn calc-overlay-position (defn calc-overlay-position
[interaction ;; interaction data [interaction ;; interaction data
shape ;; Shape with the interaction
objects ;; the objects tree objects ;; the objects tree
relative-to-shape ;; the interaction position is realtive to this sape relative-to-shape ;; the interaction position is realtive to this sape
base-frame ;; the base frame of the current interaction base-frame ;; the base frame of the current interaction
@ -371,56 +373,68 @@
(us/verify ::interaction interaction) (us/verify ::interaction interaction)
(assert (has-overlay-opts interaction)) (assert (has-overlay-opts interaction))
(if (nil? dest-frame) (let [
(gpt/point 0 0) ;; When the interactive item is inside a nested frame we need to add to the offset the position
(let [overlay-size (gsb/get-object-bounds objects dest-frame) ;; of the parent-frame otherwise the position won't match
base-frame-size (:selrect base-frame) shape-frame (cph/get-frame objects shape)
relative-to-shape-size (:selrect relative-to-shape)
relative-to-adjusted-to-base-frame {:x (- (:x relative-to-shape-size) (:x base-frame-size))
:y (- (:y relative-to-shape-size) (:y base-frame-size))}
relative-to-is-auto? (and (nil? (:position-relative-to interaction)) (not= :manual (:overlay-pos-type interaction)))
base-position (if relative-to-is-auto?
{:x 0 :y 0}
{:x (+ (:x frame-offset)
(:x relative-to-adjusted-to-base-frame))
:y (+ (:y frame-offset)
(:y relative-to-adjusted-to-base-frame))})
overlay-position (:overlay-position interaction)
overlay-position (if (= (:type relative-to-shape) :frame)
overlay-position
{:x (- (:x overlay-position) (:x relative-to-adjusted-to-base-frame))
:y (- (:y overlay-position) (:y relative-to-adjusted-to-base-frame))})]
(case (:overlay-pos-type interaction)
:center
(gpt/point (+ (:x base-position) (/ (- (:width relative-to-shape-size) (:width overlay-size)) 2))
(+ (:y base-position) (/ (- (:height relative-to-shape-size) (:height overlay-size)) 2)))
:top-left frame-offset (if (or (not= :manual (:overlay-pos-type interaction))
(gpt/point (:x base-position) (:y base-position)) (nil? shape-frame)
(cph/root-frame? shape-frame)
(cph/root? shape-frame))
frame-offset
(gpt/add frame-offset (gpt/point shape-frame)))
]
(if (nil? dest-frame)
(gpt/point 0 0)
(let [overlay-size (gsb/get-object-bounds objects dest-frame)
base-frame-size (:selrect base-frame)
relative-to-shape-size (:selrect relative-to-shape)
relative-to-adjusted-to-base-frame {:x (- (:x relative-to-shape-size) (:x base-frame-size))
:y (- (:y relative-to-shape-size) (:y base-frame-size))}
relative-to-is-auto? (and (nil? (:position-relative-to interaction)) (not= :manual (:overlay-pos-type interaction)))
base-position (if relative-to-is-auto?
{:x 0 :y 0}
{:x (+ (:x frame-offset)
(:x relative-to-adjusted-to-base-frame))
:y (+ (:y frame-offset)
(:y relative-to-adjusted-to-base-frame))})
overlay-position (:overlay-position interaction)
overlay-position (if (= (:type relative-to-shape) :frame)
overlay-position
{:x (- (:x overlay-position) (:x relative-to-adjusted-to-base-frame))
:y (- (:y overlay-position) (:y relative-to-adjusted-to-base-frame))})]
(case (:overlay-pos-type interaction)
:center
(gpt/point (+ (:x base-position) (/ (- (:width relative-to-shape-size) (:width overlay-size)) 2))
(+ (:y base-position) (/ (- (:height relative-to-shape-size) (:height overlay-size)) 2)))
:top-right :top-left
(gpt/point (+ (:x base-position) (- (:width relative-to-shape-size) (:width overlay-size))) (gpt/point (:x base-position) (:y base-position))
(:y base-position))
:top-center :top-right
(gpt/point (+ (:x base-position) (/ (- (:width relative-to-shape-size) (:width overlay-size)) 2)) (gpt/point (+ (:x base-position) (- (:width relative-to-shape-size) (:width overlay-size)))
(:y base-position)) (:y base-position))
:bottom-left :top-center
(gpt/point (:x base-position) (gpt/point (+ (:x base-position) (/ (- (:width relative-to-shape-size) (:width overlay-size)) 2))
(+ (:y base-position) (- (:height relative-to-shape-size) (:height overlay-size)))) (:y base-position))
:bottom-right :bottom-left
(gpt/point (+ (:x base-position) (- (:width relative-to-shape-size) (:width overlay-size))) (gpt/point (:x base-position)
(+ (:y base-position) (- (:height relative-to-shape-size) (:height overlay-size)))) (+ (:y base-position) (- (:height relative-to-shape-size) (:height overlay-size))))
:bottom-center :bottom-right
(gpt/point (+ (:x base-position) (/ (- (:width relative-to-shape-size) (:width overlay-size)) 2)) (gpt/point (+ (:x base-position) (- (:width relative-to-shape-size) (:width overlay-size)))
(+ (:y base-position) (- (:height relative-to-shape-size) (:height overlay-size)))) (+ (:y base-position) (- (:height relative-to-shape-size) (:height overlay-size))))
:manual :bottom-center
(gpt/point (+ (:x base-position) (:x overlay-position)) (gpt/point (+ (:x base-position) (/ (- (:width relative-to-shape-size) (:width overlay-size)) 2))
(+ (:y base-position) (:y overlay-position))))))) (+ (:y base-position) (- (:height relative-to-shape-size) (:height overlay-size))))
:manual
(gpt/point (+ (:x base-position) (:x overlay-position))
(+ (:y base-position) (:y overlay-position))))))))
(defn has-animation? (defn has-animation?
[interaction] [interaction]

View file

@ -324,49 +324,49 @@
interaction-rect (ctsi/set-position-relative-to interaction (:id rect))] interaction-rect (ctsi/set-position-relative-to interaction (:id rect))]
(t/testing "Overlay top-left relative to auto" (t/testing "Overlay top-left relative to auto"
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-left base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-left base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 0)) (t/is (= (:x overlay-pos) 0))
(t/is (= (:y overlay-pos) 0)))) (t/is (= (:y overlay-pos) 0))))
(t/testing "Overlay top-center relative to auto" (t/testing "Overlay top-center relative to auto"
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 35)) (t/is (= (:x overlay-pos) 35))
(t/is (= (:y overlay-pos) 0)))) (t/is (= (:y overlay-pos) 0))))
(t/testing "Overlay top-right relative to auto" (t/testing "Overlay top-right relative to auto"
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-right base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-right base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 70)) (t/is (= (:x overlay-pos) 70))
(t/is (= (:y overlay-pos) 0)))) (t/is (= (:y overlay-pos) 0))))
(t/testing "Overlay bottom-left relative to auto" (t/testing "Overlay bottom-left relative to auto"
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-left base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-left base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 0)) (t/is (= (:x overlay-pos) 0))
(t/is (= (:y overlay-pos) 80)))) (t/is (= (:y overlay-pos) 80))))
(t/testing "Overlay bottom-center relative to auto" (t/testing "Overlay bottom-center relative to auto"
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 35)) (t/is (= (:x overlay-pos) 35))
(t/is (= (:y overlay-pos) 80)))) (t/is (= (:y overlay-pos) 80))))
(t/testing "Overlay bottom-right relative to auto" (t/testing "Overlay bottom-right relative to auto"
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-right base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-right base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 70)) (t/is (= (:x overlay-pos) 70))
(t/is (= (:y overlay-pos) 80)))) (t/is (= (:y overlay-pos) 80))))
(t/testing "Overlay center relative to auto" (t/testing "Overlay center relative to auto"
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-auto :center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 35)) (t/is (= (:x overlay-pos) 35))
(t/is (= (:y overlay-pos) 40)))) (t/is (= (:y overlay-pos) 40))))
(t/testing "Overlay manual relative to auto" (t/testing "Overlay manual relative to auto"
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-auto :center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 35)) (t/is (= (:x overlay-pos) 35))
(t/is (= (:y overlay-pos) 40)))) (t/is (= (:y overlay-pos) 40))))
@ -374,49 +374,49 @@
(let [i2 (-> interaction-auto (let [i2 (-> interaction-auto
(ctsi/set-overlay-pos-type :manual base-frame objects) (ctsi/set-overlay-pos-type :manual base-frame objects)
(ctsi/set-overlay-position (gpt/point 12 62))) (ctsi/set-overlay-position (gpt/point 12 62)))
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 17)) (t/is (= (:x overlay-pos) 17))
(t/is (= (:y overlay-pos) 67)))) (t/is (= (:y overlay-pos) 67))))
(t/testing "Overlay top-left relative to base-frame" (t/testing "Overlay top-left relative to base-frame"
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-left base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-left base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 5)) (t/is (= (:x overlay-pos) 5))
(t/is (= (:y overlay-pos) 5)))) (t/is (= (:y overlay-pos) 5))))
(t/testing "Overlay top-center relative to base-frame" (t/testing "Overlay top-center relative to base-frame"
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 40)) (t/is (= (:x overlay-pos) 40))
(t/is (= (:y overlay-pos) 5)))) (t/is (= (:y overlay-pos) 5))))
(t/testing "Overlay top-right relative to base-frame" (t/testing "Overlay top-right relative to base-frame"
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-right base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-right base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 75)) (t/is (= (:x overlay-pos) 75))
(t/is (= (:y overlay-pos) 5)))) (t/is (= (:y overlay-pos) 5))))
(t/testing "Overlay bottom-left relative to base-frame" (t/testing "Overlay bottom-left relative to base-frame"
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-left base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-left base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 5)) (t/is (= (:x overlay-pos) 5))
(t/is (= (:y overlay-pos) 85)))) (t/is (= (:y overlay-pos) 85))))
(t/testing "Overlay bottom-center relative to base-frame" (t/testing "Overlay bottom-center relative to base-frame"
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 40)) (t/is (= (:x overlay-pos) 40))
(t/is (= (:y overlay-pos) 85)))) (t/is (= (:y overlay-pos) 85))))
(t/testing "Overlay bottom-right relative to base-frame" (t/testing "Overlay bottom-right relative to base-frame"
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-right base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-right base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 75)) (t/is (= (:x overlay-pos) 75))
(t/is (= (:y overlay-pos) 85)))) (t/is (= (:y overlay-pos) 85))))
(t/testing "Overlay center relative to base-frame" (t/testing "Overlay center relative to base-frame"
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 40)) (t/is (= (:x overlay-pos) 40))
(t/is (= (:y overlay-pos) 45)))) (t/is (= (:y overlay-pos) 45))))
@ -424,49 +424,49 @@
(let [i2 (-> interaction-base-frame (let [i2 (-> interaction-base-frame
(ctsi/set-overlay-pos-type :manual base-frame objects) (ctsi/set-overlay-pos-type :manual base-frame objects)
(ctsi/set-overlay-position (gpt/point 12 62))) (ctsi/set-overlay-position (gpt/point 12 62)))
overlay-pos (ctsi/calc-overlay-position i2 objects base-frame base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 17)) (t/is (= (:x overlay-pos) 17))
(t/is (= (:y overlay-pos) 67)))) (t/is (= (:y overlay-pos) 67))))
(t/testing "Overlay top-left relative to popup" (t/testing "Overlay top-left relative to popup"
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-left base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-left base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects popup base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 15)) (t/is (= (:x overlay-pos) 15))
(t/is (= (:y overlay-pos) 15)))) (t/is (= (:y overlay-pos) 15))))
(t/testing "Overlay top-center relative to popup" (t/testing "Overlay top-center relative to popup"
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects popup base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 25)) (t/is (= (:x overlay-pos) 25))
(t/is (= (:y overlay-pos) 15)))) (t/is (= (:y overlay-pos) 15))))
(t/testing "Overlay top-right relative to popup" (t/testing "Overlay top-right relative to popup"
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-right base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-right base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects popup base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 35)) (t/is (= (:x overlay-pos) 35))
(t/is (= (:y overlay-pos) 15)))) (t/is (= (:y overlay-pos) 15))))
(t/testing "Overlay bottom-left relative to popup" (t/testing "Overlay bottom-left relative to popup"
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-left base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-left base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects popup base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 15)) (t/is (= (:x overlay-pos) 15))
(t/is (= (:y overlay-pos) 45)))) (t/is (= (:y overlay-pos) 45))))
(t/testing "Overlay bottom-center relative to popup" (t/testing "Overlay bottom-center relative to popup"
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects popup base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 25)) (t/is (= (:x overlay-pos) 25))
(t/is (= (:y overlay-pos) 45)))) (t/is (= (:y overlay-pos) 45))))
(t/testing "Overlay bottom-right relative to popup" (t/testing "Overlay bottom-right relative to popup"
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-right base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-right base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects popup base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 35)) (t/is (= (:x overlay-pos) 35))
(t/is (= (:y overlay-pos) 45)))) (t/is (= (:y overlay-pos) 45))))
(t/testing "Overlay center relative to popup" (t/testing "Overlay center relative to popup"
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-popup :center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects popup base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 25)) (t/is (= (:x overlay-pos) 25))
(t/is (= (:y overlay-pos) 30)))) (t/is (= (:y overlay-pos) 30))))
@ -474,49 +474,49 @@
(let [i2 (-> interaction-popup (let [i2 (-> interaction-popup
(ctsi/set-overlay-pos-type :manual base-frame objects) (ctsi/set-overlay-pos-type :manual base-frame objects)
(ctsi/set-overlay-position (gpt/point 12 62))) (ctsi/set-overlay-position (gpt/point 12 62)))
overlay-pos (ctsi/calc-overlay-position i2 objects popup base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 27)) (t/is (= (:x overlay-pos) 27))
(t/is (= (:y overlay-pos) 77)))) (t/is (= (:y overlay-pos) 77))))
(t/testing "Overlay top-left relative to popup" (t/testing "Overlay top-left relative to popup"
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-left base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-left base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects popup base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 15)) (t/is (= (:x overlay-pos) 15))
(t/is (= (:y overlay-pos) 15)))) (t/is (= (:y overlay-pos) 15))))
(t/testing "Overlay top-center relative to rect" (t/testing "Overlay top-center relative to rect"
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :top-center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-rect :top-center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects rect base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 25)) (t/is (= (:x overlay-pos) 25))
(t/is (= (:y overlay-pos) 15)))) (t/is (= (:y overlay-pos) 15))))
(t/testing "Overlay top-right relative to rect" (t/testing "Overlay top-right relative to rect"
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :top-right base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-rect :top-right base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects rect base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 35)) (t/is (= (:x overlay-pos) 35))
(t/is (= (:y overlay-pos) 15)))) (t/is (= (:y overlay-pos) 15))))
(t/testing "Overlay bottom-left relative to rect" (t/testing "Overlay bottom-left relative to rect"
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-left base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-left base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects rect base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 15)) (t/is (= (:x overlay-pos) 15))
(t/is (= (:y overlay-pos) 45)))) (t/is (= (:y overlay-pos) 45))))
(t/testing "Overlay bottom-center relative to rect" (t/testing "Overlay bottom-center relative to rect"
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects rect base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 25)) (t/is (= (:x overlay-pos) 25))
(t/is (= (:y overlay-pos) 45)))) (t/is (= (:y overlay-pos) 45))))
(t/testing "Overlay bottom-right relative to rect" (t/testing "Overlay bottom-right relative to rect"
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-right base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-right base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects rect base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 35)) (t/is (= (:x overlay-pos) 35))
(t/is (= (:y overlay-pos) 45)))) (t/is (= (:y overlay-pos) 45))))
(t/testing "Overlay center relative to rect" (t/testing "Overlay center relative to rect"
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :center base-frame objects) (let [i2 (ctsi/set-overlay-pos-type interaction-rect :center base-frame objects)
overlay-pos (ctsi/calc-overlay-position i2 objects rect base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 25)) (t/is (= (:x overlay-pos) 25))
(t/is (= (:y overlay-pos) 30)))) (t/is (= (:y overlay-pos) 30))))
@ -524,7 +524,7 @@
(let [i2 (-> interaction-rect (let [i2 (-> interaction-rect
(ctsi/set-overlay-pos-type :manual base-frame objects) (ctsi/set-overlay-pos-type :manual base-frame objects)
(ctsi/set-overlay-position (gpt/point 12 62))) (ctsi/set-overlay-position (gpt/point 12 62)))
overlay-pos (ctsi/calc-overlay-position i2 objects rect base-frame overlay-frame frame-offset)] overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
(t/is (= (:x overlay-pos) 17)) (t/is (= (:x overlay-pos) 17))
(t/is (= (:y overlay-pos) 67)))))) (t/is (= (:y overlay-pos) 67))))))

View file

@ -7,7 +7,6 @@
(ns app.main.ui.viewer.shapes (ns app.main.ui.viewer.shapes
"The main container for a frame in viewer mode" "The main container for a frame in viewer mode"
(:require (:require
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.types.shape.interactions :as ctsi] [app.common.types.shape.interactions :as ctsi]
@ -48,87 +47,82 @@
(defn- activate-interaction (defn- activate-interaction
[interaction shape base-frame frame-offset objects overlays] [interaction shape base-frame frame-offset objects overlays]
(let [;; When the interactive item is inside a nested frame we need to add to the offset the position (case (:action-type interaction)
;; of the parent-frame otherwise the position won't match :navigate
shape-frame (cph/get-frame objects shape) (when-let [frame-id (:destination interaction)]
(let [viewer-section (dom/get-element "viewer-section")
scroll (if (:preserve-scroll interaction)
(dom/get-scroll-pos viewer-section)
0)]
(st/emit! (dv/set-nav-scroll scroll)
(dv/go-to-frame frame-id (:animation interaction)))))
frame-offset (if (or (cph/root-frame? shape-frame) (cph/root? shape-frame)) :open-overlay
frame-offset (let [dest-frame-id (:destination interaction)
(gpt/add frame-offset (gpt/point shape-frame)))] viewer-objects (deref (refs/get-viewer-objects))
(case (:action-type interaction) dest-frame (get viewer-objects dest-frame-id)
:navigate relative-to-id (if (= :manual (:overlay-pos-type interaction))
(when-let [frame-id (:destination interaction)] (:id shape) ;; manual interactions are allways from "self"
(let [viewer-section (dom/get-element "viewer-section") (:position-relative-to interaction))
scroll (if (:preserve-scroll interaction) relative-to-shape (or (get objects relative-to-id) base-frame)
(dom/get-scroll-pos viewer-section) close-click-outside (:close-click-outside interaction)
0)] background-overlay (:background-overlay interaction)
(st/emit! (dv/set-nav-scroll scroll) overlays-ids (set (map :id overlays))
(dv/go-to-frame frame-id (:animation interaction))))) relative-to-base-frame (find-relative-to-base-frame relative-to-shape objects overlays-ids base-frame)
position (ctsi/calc-overlay-position interaction
shape
viewer-objects
relative-to-shape
relative-to-base-frame
dest-frame
frame-offset)]
(when dest-frame-id
(st/emit! (dv/open-overlay dest-frame-id
position
close-click-outside
background-overlay
(:animation interaction)))))
:open-overlay :toggle-overlay
(let [dest-frame-id (:destination interaction) (let [frame-id (:destination interaction)
viewer-objects (deref (refs/get-viewer-objects)) dest-frame (get objects frame-id)
dest-frame (get viewer-objects dest-frame-id) relative-to-id (if (= :manual (:overlay-pos-type interaction))
relative-to-id (if (= :manual (:overlay-pos-type interaction)) (:id shape) ;; manual interactions are allways from "self"
(:id shape) ;; manual interactions are allways from "self" (:position-relative-to interaction))
(:position-relative-to interaction)) relative-to-shape (or (get objects relative-to-id) base-frame)
relative-to-shape (or (get objects relative-to-id) base-frame) overlays-ids (set (map :id overlays))
close-click-outside (:close-click-outside interaction) relative-to-base-frame (find-relative-to-base-frame relative-to-shape objects overlays-ids base-frame)
background-overlay (:background-overlay interaction) position (ctsi/calc-overlay-position interaction
overlays-ids (set (map :id overlays)) shape
relative-to-base-frame (find-relative-to-base-frame relative-to-shape objects overlays-ids base-frame) objects
position (ctsi/calc-overlay-position interaction relative-to-shape
viewer-objects relative-to-base-frame
relative-to-shape dest-frame
relative-to-base-frame frame-offset)
dest-frame
frame-offset)] close-click-outside (:close-click-outside interaction)
(when dest-frame-id background-overlay (:background-overlay interaction)]
(st/emit! (dv/open-overlay dest-frame-id (when frame-id
(st/emit! (dv/toggle-overlay frame-id
position position
close-click-outside close-click-outside
background-overlay background-overlay
(:animation interaction))))) (:animation interaction)))))
:toggle-overlay :close-overlay
(let [frame-id (:destination interaction) (let [frame-id (or (:destination interaction)
dest-frame (get objects frame-id) (if (= (:type shape) :frame)
relative-to-id (if (= :manual (:overlay-pos-type interaction)) (:id shape)
(:id shape) ;; manual interactions are allways from "self" (:frame-id shape)))]
(:position-relative-to interaction)) (st/emit! (dv/close-overlay frame-id (:animation 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)
position (ctsi/calc-overlay-position interaction
objects
relative-to-shape
relative-to-base-frame
dest-frame
frame-offset)
close-click-outside (:close-click-outside interaction) :prev-screen
background-overlay (:background-overlay interaction)] (st/emit! (rt/nav-back-local))
(when frame-id
(st/emit! (dv/toggle-overlay frame-id
position
close-click-outside
background-overlay
(:animation interaction)))))
:close-overlay :open-url
(let [frame-id (or (:destination interaction) (st/emit! (dom/open-new-window (:url interaction)))
(if (= (:type shape) :frame)
(:id shape)
(:frame-id shape)))]
(st/emit! (dv/close-overlay frame-id (:animation interaction))))
:prev-screen nil))
(st/emit! (rt/nav-back-local))
:open-url
(st/emit! (dom/open-new-window (:url interaction)))
nil)))
;; Perform the opposite action of an interaction, if possible ;; Perform the opposite action of an interaction, if possible
(defn- deactivate-interaction (defn- deactivate-interaction
@ -165,6 +159,7 @@
overlays-ids (set (map :id overlays)) overlays-ids (set (map :id overlays))
relative-to-base-frame (find-relative-to-base-frame relative-to-shape objects overlays-ids base-frame) relative-to-base-frame (find-relative-to-base-frame relative-to-shape objects overlays-ids base-frame)
position (ctsi/calc-overlay-position interaction position (ctsi/calc-overlay-position interaction
shape
objects objects
relative-to-shape relative-to-shape
relative-to-base-frame relative-to-base-frame