mirror of
https://github.com/penpot/penpot.git
synced 2025-04-05 19:41:27 -05:00
🐛 Fix overlay position when it has shadow or blur
This commit is contained in:
parent
e563611c05
commit
65598aa724
10 changed files with 242 additions and 102 deletions
|
@ -65,6 +65,7 @@
|
|||
- Fix shortcuts translations not homogenized [Taiga #5141](https://tree.taiga.io/project/penpot/issue/5141)
|
||||
- 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)
|
||||
|
||||
### :arrow_up: Deps updates
|
||||
|
||||
|
|
|
@ -147,6 +147,7 @@
|
|||
:else
|
||||
(cph/reduce-objects
|
||||
objects
|
||||
|
||||
(fn [shape]
|
||||
(and (d/not-empty? (:shapes shape))
|
||||
(or (not (cph/frame-shape? shape))
|
||||
|
|
|
@ -526,37 +526,46 @@
|
|||
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)))
|
||||
[(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)))
|
||||
[:center :center]]
|
||||
|
||||
:top-left
|
||||
(gpt/point (:x base-position) (:y base-position))
|
||||
[(gpt/point (:x base-position) (:y base-position))
|
||||
[:top :left]]
|
||||
|
||||
:top-right
|
||||
(gpt/point (+ (:x base-position) (- (:width relative-to-shape-size) (:width overlay-size)))
|
||||
(:y base-position))
|
||||
[(gpt/point (+ (:x base-position) (- (:width relative-to-shape-size) (:width overlay-size)))
|
||||
(:y base-position))
|
||||
[:top :right]]
|
||||
|
||||
:top-center
|
||||
(gpt/point (+ (:x base-position) (/ (- (:width relative-to-shape-size) (:width overlay-size)) 2))
|
||||
(:y base-position))
|
||||
[(gpt/point (+ (:x base-position) (/ (- (:width relative-to-shape-size) (:width overlay-size)) 2))
|
||||
(:y base-position))
|
||||
[:top :center]]
|
||||
|
||||
:bottom-left
|
||||
(gpt/point (:x base-position)
|
||||
(+ (:y base-position) (- (:height relative-to-shape-size) (:height overlay-size))))
|
||||
[(gpt/point (:x base-position)
|
||||
(+ (:y base-position) (- (:height relative-to-shape-size) (:height overlay-size))))
|
||||
[:bottom :left]]
|
||||
|
||||
:bottom-right
|
||||
(gpt/point (+ (:x base-position) (- (:width relative-to-shape-size) (:width overlay-size)))
|
||||
(+ (:y base-position) (- (:height relative-to-shape-size) (:height overlay-size))))
|
||||
[(gpt/point (+ (:x base-position) (- (:width relative-to-shape-size) (:width overlay-size)))
|
||||
(+ (:y base-position) (- (:height relative-to-shape-size) (:height overlay-size))))
|
||||
[:bottom :right]]
|
||||
|
||||
:bottom-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))))
|
||||
[(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))))
|
||||
[:bottom :center]]
|
||||
|
||||
:manual
|
||||
(gpt/point (+ (:x base-position) (:x overlay-position))
|
||||
(+ (:y base-position) (:y overlay-position))))))))
|
||||
[(gpt/point (+ (:x base-position) (:x overlay-position))
|
||||
(+ (:y base-position) (:y overlay-position)))
|
||||
[:top :left]])))))
|
||||
|
||||
(defn has-animation?
|
||||
[interaction]
|
||||
|
|
|
@ -324,209 +324,275 @@
|
|||
interaction-rect (ctsi/set-position-relative-to interaction (:id rect))]
|
||||
(t/testing "Overlay top-left relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-left base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 0))
|
||||
(t/is (= (:y overlay-pos) 0))))
|
||||
(t/is (= (:y overlay-pos) 0))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-center relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 0))))
|
||||
(t/is (= (:y overlay-pos) 0))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay top-right relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-right base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 70))
|
||||
(t/is (= (:y overlay-pos) 0))))
|
||||
(t/is (= (:y overlay-pos) 0))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay bottom-left relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-left base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 0))
|
||||
(t/is (= (:y overlay-pos) 80))))
|
||||
(t/is (= (:y overlay-pos) 80))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay bottom-center relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 80))))
|
||||
(t/is (= (:y overlay-pos) 80))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay bottom-right relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-right base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 70))
|
||||
(t/is (= (:y overlay-pos) 80))))
|
||||
(t/is (= (:y overlay-pos) 80))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay center relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 40))))
|
||||
(t/is (= (:y overlay-pos) 40))
|
||||
(t/is (= snap-v :center))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay manual relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 40))))
|
||||
(t/is (= (:y overlay-pos) 40))
|
||||
(t/is (= snap-v :center))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay manual relative to auto"
|
||||
(let [i2 (-> interaction-auto
|
||||
(ctsi/set-overlay-pos-type :manual base-frame objects)
|
||||
(ctsi/set-overlay-position (gpt/point 12 62)))
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 17))
|
||||
(t/is (= (:y overlay-pos) 67))))
|
||||
(t/is (= (:y overlay-pos) 67))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-left relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-left base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 5))
|
||||
(t/is (= (:y overlay-pos) 5))))
|
||||
(t/is (= (:y overlay-pos) 5))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-center relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 40))
|
||||
(t/is (= (:y overlay-pos) 5))))
|
||||
(t/is (= (:y overlay-pos) 5))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay top-right relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-right base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 75))
|
||||
(t/is (= (:y overlay-pos) 5))))
|
||||
(t/is (= (:y overlay-pos) 5))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay bottom-left relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-left base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 5))
|
||||
(t/is (= (:y overlay-pos) 85))))
|
||||
(t/is (= (:y overlay-pos) 85))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay bottom-center relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 40))
|
||||
(t/is (= (:y overlay-pos) 85))))
|
||||
(t/is (= (:y overlay-pos) 85))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay bottom-right relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-right base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 75))
|
||||
(t/is (= (:y overlay-pos) 85))))
|
||||
(t/is (= (:y overlay-pos) 85))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay center relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 40))
|
||||
(t/is (= (:y overlay-pos) 45))))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :center))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay manual relative to base-frame"
|
||||
(let [i2 (-> interaction-base-frame
|
||||
(ctsi/set-overlay-pos-type :manual base-frame objects)
|
||||
(ctsi/set-overlay-position (gpt/point 12 62)))
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 17))
|
||||
(t/is (= (:y overlay-pos) 67))))
|
||||
(t/is (= (:y overlay-pos) 67))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-left relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-left base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 15))
|
||||
(t/is (= (:y overlay-pos) 15))))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-center relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 15))))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay top-right relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-right base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 15))))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay bottom-left relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-left base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 15))
|
||||
(t/is (= (:y overlay-pos) 45))))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay bottom-center relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 45))))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay bottom-right relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-right base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 45))))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay center relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 30))))
|
||||
(t/is (= (:y overlay-pos) 30))
|
||||
(t/is (= snap-v :center))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay manual relative to popup"
|
||||
(let [i2 (-> interaction-popup
|
||||
(ctsi/set-overlay-pos-type :manual base-frame objects)
|
||||
(ctsi/set-overlay-position (gpt/point 12 62)))
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 27))
|
||||
(t/is (= (:y overlay-pos) 77))))
|
||||
(t/is (= (:y overlay-pos) 77))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-left relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-left base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 15))
|
||||
(t/is (= (:y overlay-pos) 15))))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-center relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :top-center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 15))))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay top-right relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :top-right base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 15))))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay bottom-left relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-left base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 15))
|
||||
(t/is (= (:y overlay-pos) 45))))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay bottom-center relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 45))))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay bottom-right relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-right base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 45))))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay center relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :center base-frame objects)
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 30))))
|
||||
(t/is (= (:y overlay-pos) 30))
|
||||
(t/is (= snap-v :center))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay manual relative to rect"
|
||||
(let [i2 (-> interaction-rect
|
||||
(ctsi/set-overlay-pos-type :manual base-frame objects)
|
||||
(ctsi/set-overlay-position (gpt/point 12 62)))
|
||||
overlay-pos (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 17))
|
||||
(t/is (= (:y overlay-pos) 67))))))
|
||||
(t/is (= (:y overlay-pos) 67))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))))
|
||||
|
||||
|
||||
(t/deftest animation-checks
|
||||
|
|
|
@ -542,13 +542,14 @@
|
|||
;; --- Overlays
|
||||
|
||||
(defn- open-overlay*
|
||||
[state frame position close-click-outside background-overlay animation]
|
||||
[state frame position snap-to close-click-outside background-overlay animation]
|
||||
(cond-> state
|
||||
:always
|
||||
(update :viewer-overlays conj
|
||||
{:frame frame
|
||||
:id (:id frame)
|
||||
:position position
|
||||
:snap-to snap-to
|
||||
:close-click-outside close-click-outside
|
||||
:background-overlay background-overlay
|
||||
:animation animation})
|
||||
|
@ -571,7 +572,7 @@
|
|||
:animation animation})))
|
||||
|
||||
(defn open-overlay
|
||||
[frame-id position close-click-outside background-overlay animation]
|
||||
[frame-id position snap-to close-click-outside background-overlay animation]
|
||||
(dm/assert! (uuid? frame-id))
|
||||
(dm/assert! (gpt/point? position))
|
||||
(dm/assert! (or (nil? close-click-outside)
|
||||
|
@ -593,6 +594,7 @@
|
|||
(open-overlay* state
|
||||
frame
|
||||
position
|
||||
snap-to
|
||||
close-click-outside
|
||||
background-overlay
|
||||
animation)
|
||||
|
@ -600,7 +602,7 @@
|
|||
|
||||
|
||||
(defn toggle-overlay
|
||||
[frame-id position close-click-outside background-overlay animation]
|
||||
[frame-id position snap-to close-click-outside background-overlay animation]
|
||||
(dm/assert! (uuid? frame-id))
|
||||
(dm/assert! (gpt/point? position))
|
||||
(dm/assert! (or (nil? close-click-outside)
|
||||
|
@ -623,6 +625,7 @@
|
|||
(open-overlay* state
|
||||
frame
|
||||
position
|
||||
snap-to
|
||||
close-click-outside
|
||||
background-overlay
|
||||
animation)
|
||||
|
|
|
@ -142,5 +142,6 @@
|
|||
[:> frame-container props
|
||||
[:g.frame-children {:opacity (:opacity shape)}
|
||||
(for [item childs]
|
||||
[:& shape-wrapper {:key (dm/str (:id item)) :shape item}])]])))
|
||||
(when (:id item)
|
||||
[:& shape-wrapper {:key (dm/str (:id item)) :shape item}]))]])))
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
(l/derived :viewer-overlays st/state))
|
||||
|
||||
(defn- calculate-size
|
||||
"Calculate the total size we must reserve for the frame, including possible paddings
|
||||
added because shadows or blur."
|
||||
[objects frame zoom]
|
||||
(let [{:keys [x y width height]} (gsb/get-object-bounds objects frame)]
|
||||
{:base-width width
|
||||
|
@ -60,6 +62,23 @@
|
|||
:height (* height zoom)
|
||||
:vbox (dm/fmt "% % % %" 0 0 width height)}))
|
||||
|
||||
(defn calculate-delta
|
||||
"Calculate the displacement we need to apply so that the original selrect appears in the
|
||||
same position as if it had no extra paddings, depending on the side the frame will
|
||||
be snapped to."
|
||||
[size selrect [snap-v snap-h] zoom]
|
||||
(let [delta-x (case snap-h
|
||||
:left (- (:x1 selrect) (:x size))
|
||||
:right (- (:x2 selrect) (+ (:x size) (/ (:width size) zoom)))
|
||||
:center (- (/ (- (:width selrect) (/ (:width size) zoom)) 2)
|
||||
(- (:x size) (:x1 selrect))))
|
||||
delta-y (case snap-v
|
||||
:top (- (:y1 selrect) (:y size))
|
||||
:bottom (- (:y2 selrect) (+ (:y size) (/ (:height size) zoom)))
|
||||
:center (- (/ (- (:height selrect) (/ (:height size) zoom)) 2)
|
||||
(- (:y size) (:y1 selrect))))]
|
||||
(gpt/point (* delta-x zoom) (* delta-y zoom))))
|
||||
|
||||
(defn- calculate-wrapper
|
||||
[size1 size2 zoom]
|
||||
(cond
|
||||
|
@ -113,6 +132,10 @@
|
|||
(mf/with-memo [page overlay zoom]
|
||||
(calculate-size (:objects page) (:frame overlay) zoom))
|
||||
|
||||
delta
|
||||
(mf/with-memo [size overlay-frame overlay zoom]
|
||||
(calculate-delta size (:selrect overlay-frame) (:snap-to overlay) zoom))
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
(mf/deps overlay close-click-outside?)
|
||||
|
@ -145,6 +168,7 @@
|
|||
:base-frame frame
|
||||
:frame-offset overlay-position
|
||||
:size size
|
||||
:delta delta
|
||||
:page page
|
||||
:interactions-mode interactions-mode}]]]))
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
(ns app.main.ui.viewer.inspect.render
|
||||
"The main container for a frame in inspect mode"
|
||||
(:require
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.main.data.viewer :as dv]
|
||||
|
@ -186,7 +187,7 @@
|
|||
(mf/defc render-frame-svg
|
||||
[{:keys [page frame local size]}]
|
||||
(let [objects (mf/with-memo [page frame size]
|
||||
(prepare-objects frame size (:objects page)))
|
||||
(prepare-objects frame size (gpt/point 0 0) (:objects page)))
|
||||
|
||||
;; Retrieve frame again with correct modifier
|
||||
frame (get objects (:id frame))
|
||||
|
|
|
@ -28,9 +28,10 @@
|
|||
[rumext.v2 :as mf]))
|
||||
|
||||
(defn prepare-objects
|
||||
[frame size objects]
|
||||
[frame size delta objects]
|
||||
(let [frame-id (:id frame)
|
||||
vector (-> (gpt/point (:x size) (:y size))
|
||||
(gpt/add delta)
|
||||
(gpt/negate))
|
||||
update-fn #(d/update-when %1 %2 gsh/transform-shape (ctm/move-modifiers vector))]
|
||||
(->> (cph/get-children-ids objects frame-id)
|
||||
|
@ -46,6 +47,7 @@
|
|||
base (unchecked-get props "base")
|
||||
offset (unchecked-get props "offset")
|
||||
size (unchecked-get props "size")
|
||||
delta (or (unchecked-get props "delta") (gpt/point 0 0))
|
||||
|
||||
vbox (:vbox size)
|
||||
|
||||
|
@ -67,7 +69,7 @@
|
|||
(map (d/getf (:objects page)))
|
||||
(concat [frame])
|
||||
(d/index-by :id)
|
||||
(prepare-objects frame size)))
|
||||
(prepare-objects frame size delta)))
|
||||
|
||||
wrapper-fixed (mf/with-memo [page frame size]
|
||||
(shapes/frame-container-factory (calculate-objects fixed-ids)))
|
||||
|
@ -121,6 +123,7 @@
|
|||
mode (h/use-equal-memo (unchecked-get props "interactions-mode"))
|
||||
offset (h/use-equal-memo (unchecked-get props "frame-offset"))
|
||||
size (h/use-equal-memo (unchecked-get props "size"))
|
||||
delta (unchecked-get props "delta")
|
||||
|
||||
page (unchecked-get props "page")
|
||||
frame (unchecked-get props "frame")
|
||||
|
@ -163,7 +166,8 @@
|
|||
:frame frame
|
||||
:base base
|
||||
:offset offset
|
||||
:size size}]))
|
||||
:size size
|
||||
:delta delta}]))
|
||||
|
||||
(mf/defc flows-menu
|
||||
{::mf/wrap [mf/memo]}
|
||||
|
|
|
@ -61,14 +61,16 @@
|
|||
(let [dest-frame-id (:destination interaction)
|
||||
dest-frame (get objects dest-frame-id)
|
||||
relative-to-id (if (= :manual (:overlay-pos-type interaction))
|
||||
(:id shape) ;; manual interactions are allways from "self"
|
||||
(if (= (:type shape) :frame) ;; manual interactions are always from "self"
|
||||
(:frame-id shape)
|
||||
(:id shape))
|
||||
(:position-relative-to interaction))
|
||||
relative-to-shape (or (get objects relative-to-id) base-frame)
|
||||
close-click-outside (:close-click-outside interaction)
|
||||
background-overlay (:background-overlay interaction)
|
||||
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
|
||||
[position snap-to] (ctsi/calc-overlay-position interaction
|
||||
shape
|
||||
objects
|
||||
relative-to-shape
|
||||
|
@ -78,6 +80,7 @@
|
|||
(when dest-frame-id
|
||||
(st/emit! (dv/open-overlay dest-frame-id
|
||||
position
|
||||
snap-to
|
||||
close-click-outside
|
||||
background-overlay
|
||||
(:animation interaction)))))
|
||||
|
@ -86,12 +89,14 @@
|
|||
(let [dest-frame-id (:destination interaction)
|
||||
dest-frame (get objects dest-frame-id)
|
||||
relative-to-id (if (= :manual (:overlay-pos-type interaction))
|
||||
(:id shape) ;; manual interactions are allways from "self"
|
||||
(:position-relative-to interaction))
|
||||
(if (= (:type shape) :frame) ;; manual interactions are always from "self"
|
||||
(:frame-id shape)
|
||||
(:id shape))
|
||||
(: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)
|
||||
position (ctsi/calc-overlay-position interaction
|
||||
[position snap-to] (ctsi/calc-overlay-position interaction
|
||||
shape
|
||||
objects
|
||||
relative-to-shape
|
||||
|
@ -104,6 +109,7 @@
|
|||
(when dest-frame-id
|
||||
(st/emit! (dv/toggle-overlay dest-frame-id
|
||||
position
|
||||
snap-to
|
||||
close-click-outside
|
||||
background-overlay
|
||||
(:animation interaction)))))
|
||||
|
@ -136,29 +142,49 @@
|
|||
(st/emit! (dv/close-overlay frame-id)))
|
||||
|
||||
:toggle-overlay
|
||||
(let [frame-id (:destination interaction)
|
||||
position (:overlay-position interaction)
|
||||
close-click-outside (:close-click-outside interaction)
|
||||
background-overlay (:background-overlay interaction)]
|
||||
(when frame-id
|
||||
(st/emit! (dv/toggle-overlay frame-id
|
||||
(let [dest-frame-id (:destination interaction)
|
||||
dest-frame (get objects dest-frame-id)
|
||||
relative-to-id (if (= :manual (:overlay-pos-type interaction))
|
||||
(if (= (:type shape) :frame) ;; manual interactions are always from "self"
|
||||
(:frame-id shape)
|
||||
(:id shape))
|
||||
(: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)
|
||||
[position snap-to] (ctsi/calc-overlay-position interaction
|
||||
shape
|
||||
objects
|
||||
relative-to-shape
|
||||
relative-to-base-frame
|
||||
dest-frame
|
||||
frame-offset)
|
||||
|
||||
close-click-outside (:close-click-outside interaction)
|
||||
background-overlay (:background-overlay interaction)]
|
||||
(when dest-frame-id
|
||||
(st/emit! (dv/toggle-overlay dest-frame-id
|
||||
position
|
||||
snap-to
|
||||
close-click-outside
|
||||
background-overlay
|
||||
(:animation interaction)))))
|
||||
|
||||
|
||||
:close-overlay
|
||||
(let [dest-frame-id (:destination interaction)
|
||||
dest-frame (get objects dest-frame-id)
|
||||
relative-to-id (if (= :manual (:overlay-pos-type interaction))
|
||||
(:id shape) ;; manual interactions are allways from "self"
|
||||
(if (= (:type shape) :frame) ;; manual interactions are always from "self"
|
||||
(:frame-id shape)
|
||||
(:id shape))
|
||||
(:position-relative-to interaction))
|
||||
relative-to-shape (or (get objects relative-to-id) base-frame)
|
||||
close-click-outside (:close-click-outside interaction)
|
||||
background-overlay (:background-overlay interaction)
|
||||
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
|
||||
[position snap-to] (ctsi/calc-overlay-position interaction
|
||||
shape
|
||||
objects
|
||||
relative-to-shape
|
||||
|
@ -168,6 +194,7 @@
|
|||
(when dest-frame-id
|
||||
(st/emit! (dv/open-overlay dest-frame-id
|
||||
position
|
||||
snap-to
|
||||
close-click-outside
|
||||
background-overlay
|
||||
(:animation interaction)))))
|
||||
|
@ -266,6 +293,9 @@
|
|||
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))
|
||||
on-pointer-down
|
||||
(mf/use-fn (mf/deps shape base-frame frame-offset objects)
|
||||
#(on-pointer-down % shape base-frame frame-offset objects overlays))
|
||||
|
|
Loading…
Add table
Reference in a new issue