diff --git a/common/src/app/common/geom/rect.cljc b/common/src/app/common/geom/rect.cljc index cd9bf6f06..adfa3114c 100644 --- a/common/src/app/common/geom/rect.cljc +++ b/common/src/app/common/geom/rect.cljc @@ -275,21 +275,19 @@ [a b] (mth/almost-zero? (- a b))) -;; FIXME: performance (defn overlaps-rects? "Check for two rects to overlap. Rects won't overlap only if one of them is fully to the left or the top" [rect-a rect-b] + (let [x1a (dm/get-prop rect-a :x) + y1a (dm/get-prop rect-a :y) + x2a (+ x1a (dm/get-prop rect-a :width)) + y2a (+ y1a (dm/get-prop rect-a :height)) - (let [x1a (:x rect-a) - y1a (:y rect-a) - x2a (+ (:x rect-a) (:width rect-a)) - y2a (+ (:y rect-a) (:height rect-a)) - - x1b (:x rect-b) - y1b (:y rect-b) - x2b (+ (:x rect-b) (:width rect-b)) - y2b (+ (:y rect-b) (:height rect-b))] + x1b (dm/get-prop rect-b :x) + y1b (dm/get-prop rect-b :y) + x2b (+ x1b (dm/get-prop rect-b :width)) + y2b (+ y1b (dm/get-prop rect-b :height))] (and (or (> x2a x1b) (s= x2a x1b)) (or (>= x2b x1a) (s= x2b x1a)) diff --git a/common/src/app/common/geom/shapes/intersect.cljc b/common/src/app/common/geom/shapes/intersect.cljc index c9e89dd6c..74da2cc3e 100644 --- a/common/src/app/common/geom/shapes/intersect.cljc +++ b/common/src/app/common/geom/shapes/intersect.cljc @@ -307,12 +307,12 @@ (defn overlaps? "General case to check for overlapping between shapes and a rectangle" [shape rect] - (let [stroke-width (/ (or (:stroke-width shape) 0) 2) - rect (-> rect - (update :x - stroke-width) - (update :y - stroke-width) - (update :width + (* 2 stroke-width)) - (update :height + (* 2 stroke-width)))] + (let [swidth (/ (or (:stroke-width shape) 0) 2) + rect (-> rect + (update :x - swidth) + (update :y - swidth) + (update :width + (* 2 swidth)) + (update :height + (* 2 swidth)))] (or (not shape) (cond (cph/path-shape? shape) diff --git a/frontend/src/app/main/ui/context.cljs b/frontend/src/app/main/ui/context.cljs index c0d1aa00e..a365ce9f3 100644 --- a/frontend/src/app/main/ui/context.cljs +++ b/frontend/src/app/main/ui/context.cljs @@ -16,6 +16,7 @@ (def current-project-id (mf/create-context nil)) (def current-page-id (mf/create-context nil)) (def current-file-id (mf/create-context nil)) +(def current-vbox (mf/create-context nil)) (def active-frames (mf/create-context nil)) (def render-thumbnails (mf/create-context nil)) diff --git a/frontend/src/app/main/ui/workspace/shapes.cljs b/frontend/src/app/main/ui/workspace/shapes.cljs index 996ec2296..fb4563e70 100644 --- a/frontend/src/app/main/ui/workspace/shapes.cljs +++ b/frontend/src/app/main/ui/workspace/shapes.cljs @@ -13,6 +13,7 @@ common." (:require [app.common.data.macros :as dm] + [app.common.geom.rect :as grc] [app.common.pages.helpers :as cph] [app.common.uuid :as uuid] [app.main.ui.context :as ctx] @@ -49,15 +50,14 @@ (let [objects (obj/get props "objects") active-frames (obj/get props "active-frames") shapes (cph/get-immediate-children objects) + vbox (mf/use-ctx ctx/current-vbox) - ;; vbox (mf/use-ctx ctx/current-vbox) - ;; shapes (mf/with-memo [shapes vbox] - ;; (if (some? vbox) - ;; (filter (fn [shape] - ;; (grc/overlaps-rects? vbox (dm/get-prop shape :selrect))) - ;; shapes) - ;; shapes)) - ] + shapes (mf/with-memo [shapes vbox] + (if (some? vbox) + (filter (fn [shape] + (grc/overlaps-rects? vbox (dm/get-prop shape :selrect))) + shapes) + shapes))] [:g {:id (dm/str "shape-" uuid/zero)} [:& (mf/provider ctx/active-frames) {:value active-frames} diff --git a/frontend/src/app/main/ui/workspace/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/shapes/frame.cljs index c210ef5d8..0fc57d3e6 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame.cljs @@ -73,6 +73,7 @@ (fdm/use-dynamic-modifiers objects (mf/ref-val node-ref) modifiers) [:& frame-shape {:shape shape :ref node-ref}])))) + (defn root-frame-wrapper-factory [shape-wrapper] @@ -86,9 +87,9 @@ thumbnail? (unchecked-get props "thumbnail?") page-id (mf/use-ctx ctx/current-page-id) - frame-id (:id shape) + frame-id (dm/get-prop shape :id) - objects (wsh/lookup-page-objects @st/state) + objects (wsh/lookup-page-objects @st/state page-id) node-ref (mf/use-ref nil) root-ref (mf/use-ref nil) @@ -114,6 +115,7 @@ on-frame-load (fns/use-node-store node-ref rendered-ref thumbnail? render-frame?) + ] (fdm/use-dynamic-modifiers objects (mf/ref-val node-ref) modifiers) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 275d9f4a0..d2982a10c 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -88,6 +88,8 @@ show-distances? picking-color?]} wglobal + vbox' (mf/use-debounce 100 vbox) + ;; CONTEXT page-id (mf/use-ctx ctx/current-page-id) @@ -323,12 +325,13 @@ :y (:y vbox 0) :fill background}] - [:& (mf/provider use/include-metadata-ctx) {:value (debug? :show-export-metadata)} - [:& (mf/provider embed/context) {:value true} - ;; Render root shape - [:& shapes/root-shape {:key page-id - :objects base-objects - :active-frames @active-frames}]]]] + [:& (mf/provider ctx/current-vbox) {:value vbox'} + [:& (mf/provider use/include-metadata-ctx) {:value (debug? :show-export-metadata)} + [:& (mf/provider embed/context) {:value true} + ;; Render root shape + [:& shapes/root-shape {:key page-id + :objects base-objects + :active-frames @active-frames}]]]]] [:svg.viewport-controls {:xmlns "http://www.w3.org/2000/svg" diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index a4db28c8b..1d283d90d 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -409,10 +409,11 @@ (defn bounding-rect->rect [rect] (when (some? rect) - {:x (or (.-left rect) (:left rect) 0) - :y (or (.-top rect) (:top rect) 0) - :width (or (.-width rect) (:width rect) 1) - :height (or (.-height rect) (:height rect) 1)})) + (grc/make-rect + (or (.-left rect) (:left rect) 0) + (or (.-top rect) (:top rect) 0) + (or (.-width rect) (:width rect) 1) + (or (.-height rect) (:height rect) 1)))) (defn get-window-size [] diff --git a/frontend/src/app/util/text_svg_position.cljs b/frontend/src/app/util/text_svg_position.cljs index a79f49b06..8c4477131 100644 --- a/frontend/src/app/util/text_svg_position.cljs +++ b/frontend/src/app/util/text_svg_position.cljs @@ -88,28 +88,28 @@ (defn calc-position-data [shape-id] - (when (some? shape-id) - (p/let [text-data (calc-text-node-positions shape-id)] - (->> text-data - (mapv (fn [{:keys [node position text direction]}] - (let [{:keys [x y width height]} position - styles (js/getComputedStyle ^js node) - get (fn [prop] - (let [value (.getPropertyValue styles prop)] - (when (and value (not= value "")) - value)))] - (d/without-nils - {:x x - :y (+ y height) - :width width - :height height - :direction direction - :font-family (str (get "font-family")) - :font-size (str (get "font-size")) - :font-weight (str (get "font-weight")) - :text-transform (str (get "text-transform")) - :text-decoration (str (get "text-decoration")) - :letter-spacing (str (get "letter-spacing")) - :font-style (str (get "font-style")) - :fills (transit/decode-str (get "--fills")) - :text text})))))))) + (letfn [(get-prop [styles prop] + (let [value (.getPropertyValue styles prop)] + (when (and (some? value) (not= value "")) + value))) + + (transform-data [{:keys [node position text direction]}] + (let [styles (js/getComputedStyle ^js node) + position (assoc position :y (+ (dm/get-prop position :y) + (dm/get-prop position :height)))] + (into position (filter val) + {:direction direction + :font-family (dm/str (get-prop styles "font-family")) + :font-size (dm/str (get-prop styles "font-size")) + :font-weight (dm/str (get-prop styles "font-weight")) + :text-transform (dm/str (get-prop styles "text-transform")) + :text-decoration (dm/str (get-prop styles "text-decoration")) + :letter-spacing (dm/str (get-prop styles "letter-spacing")) + :font-style (dm/str (get-prop styles "font-style")) + :fills (transit/decode-str (get-prop styles "--fills")) + :text text})))] + + (when (some? shape-id) + (->> (calc-text-node-positions shape-id) + (p/fmap (fn [text-data] + (mapv transform-data text-data)))))))