diff --git a/common/src/app/common/geom/shapes.cljc b/common/src/app/common/geom/shapes.cljc index ed5c52aa9..90debd442 100644 --- a/common/src/app/common/geom/shapes.cljc +++ b/common/src/app/common/geom/shapes.cljc @@ -159,6 +159,7 @@ (dm/export gtr/move) (dm/export gtr/absolute-move) (dm/export gtr/transform-matrix) +(dm/export gtr/transform-str) (dm/export gtr/inverse-transform-matrix) (dm/export gtr/transform-point-center) (dm/export gtr/transform-rect) diff --git a/common/src/app/common/geom/shapes/transforms.cljc b/common/src/app/common/geom/shapes/transforms.cljc index 6fd41c01a..a334b3317 100644 --- a/common/src/app/common/geom/shapes/transforms.cljc +++ b/common/src/app/common/geom/shapes/transforms.cljc @@ -7,6 +7,7 @@ (ns app.common.geom.shapes.transforms (:require [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes.common :as gco] @@ -143,16 +144,29 @@ ([shape params] (transform-matrix shape params (or (gco/center-shape shape) (gpt/point 0 0)))) - ([{:keys [flip-x flip-y] :as shape} {:keys [no-flip]} shape-center] + ([{:keys [flip-x flip-y transform] :as shape} {:keys [no-flip]} shape-center] (-> (gmt/matrix) (gmt/translate shape-center) - (gmt/multiply (:transform shape (gmt/matrix))) + (cond-> (some? transform) + (gmt/multiply transform)) + (cond-> (and (not no-flip) flip-x) (gmt/scale (gpt/point -1 1)) (and (not no-flip) flip-y) (gmt/scale (gpt/point 1 -1))) (gmt/translate (gpt/negate shape-center))))) +(defn transform-str + ([shape] + (transform-str shape nil)) + + ([{:keys [transform flip-x flip-y] :as shape} {:keys [no-flip]}] + (when (and (some? shape) + (or (some? transform) + (and (not no-flip) flip-x) + (and (not no-flip) flip-y))) + (dm/str (transform-matrix shape))))) + (defn inverse-transform-matrix ([shape] (let [shape-center (or (gco/center-shape shape) diff --git a/common/src/app/common/pages/common.cljc b/common/src/app/common/pages/common.cljc index 8756ac472..1b73deac2 100644 --- a/common/src/app/common/pages/common.cljc +++ b/common/src/app/common/pages/common.cljc @@ -80,6 +80,7 @@ :x :y :rx :ry :r1 :r2 :r3 :r4 + :rotation :selrect :points :show-content diff --git a/frontend/src/app/main/data/workspace/common.cljs b/frontend/src/app/main/data/workspace/common.cljs index 5032a70fe..5bc125ce1 100644 --- a/frontend/src/app/main/data/workspace/common.cljs +++ b/frontend/src/app/main/data/workspace/common.cljs @@ -338,11 +338,9 @@ (let [page-id (:current-page-id state) objects (wsh/lookup-page-objects state page-id) - to-move-shapes (->> (cph/get-immediate-children objects) - (remove cph/frame-shape?) - (d/enumerate) - (filterv (comp shapes :id second)) - (mapv second)) + to-move-shapes (into [] + (map (d/getf objects)) + (reverse (cph/sort-z-index objects shapes))) changes (-> (pcb/empty-changes it page-id) (pcb/with-objects objects) diff --git a/frontend/src/app/main/data/workspace/drawing/box.cljs b/frontend/src/app/main/data/workspace/drawing/box.cljs index b5dcaf107..6de3726a6 100644 --- a/frontend/src/app/main/data/workspace/drawing/box.cljs +++ b/frontend/src/app/main/data/workspace/drawing/box.cljs @@ -67,15 +67,19 @@ fid (cph/frame-id-by-position objects initial) - shape (-> state - (get-in [:workspace-drawing :object]) - (cp/setup-shape {:x (:x initial) - :y (:y initial) - :width 0.01 - :height 0.01}) - (assoc :frame-id fid) - (assoc :initialized? true) - (assoc :click-draw? true))] + shape (get-in state [:workspace-drawing :object]) + shape (-> shape + (cp/setup-shape {:x (:x initial) + :y (:y initial) + :width 0.01 + :height 0.01}) + (cond-> (and (cph/frame-shape? shape) + (not= fid uuid/zero)) + (assoc :fills [] :show-content true :hide-in-viewer true)) + + (assoc :frame-id fid) + (assoc :initialized? true) + (assoc :click-draw? true))] (rx/concat ;; Add shape to drawing state (rx/of #(assoc-in state [:workspace-drawing :object] shape)) diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/frontend/src/app/main/data/workspace/libraries_helpers.cljs index 5172481ca..7fcb2cefa 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/frontend/src/app/main/data/workspace/libraries_helpers.cljs @@ -8,7 +8,7 @@ (:require [app.common.data :as d] [app.common.geom.point :as gpt] - [app.common.geom.shapes :as geom] + [app.common.geom.shapes :as gsh] [app.common.logging :as log] [app.common.pages :as cp] [app.common.pages.changes-builder :as pcb] @@ -158,7 +158,7 @@ (cond-> new-shape true (as-> $ - (geom/move $ delta) + (gsh/move $ delta) (assoc $ :frame-id frame-id) (assoc $ :parent-id (or (:parent-id $) (:frame-id $))) @@ -1150,7 +1150,7 @@ origin-root-pos (shape-pos origin-root) dest-root-pos (shape-pos dest-root) delta (gpt/subtract dest-root-pos origin-root-pos)] - (geom/move shape delta))) + (gsh/move shape delta))) (defn- make-change [container change] diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index 5a039e34e..eff690a40 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -8,7 +8,7 @@ (:require [app.common.data :as d] [app.common.geom.point :as gpt] - [app.common.geom.shapes :as geom] + [app.common.geom.shapes :as gsh] [app.common.math :as mth] [app.common.pages :as cp] [app.common.pages.changes-builder :as pcb] @@ -264,7 +264,7 @@ ;; in the later vector position selected (->> children reverse - (d/seek #(geom/has-point? % position)))] + (d/seek #(gsh/has-point? % position)))] (when selected (rx/of (select-shape (:id selected)))))))) @@ -325,7 +325,7 @@ :frame-id uuid/zero :shapes []) (dissoc :use-for-thumbnail?) - (geom/move delta) + (gsh/move delta) (d/update-when :interactions #(cti/remap-interactions % ids-map objects))) changes (-> (pcb/add-object changes new-frame) @@ -360,7 +360,7 @@ :parent-id parent-id :frame-id frame-id) (dissoc :shapes) - (geom/move delta) + (gsh/move delta) (d/update-when :interactions #(cti/remap-interactions % ids-map objects))) changes (-> (pcb/add-object changes new-obj {:ignore-touched true}) @@ -412,7 +412,7 @@ (fn [g frame] (let [new-id (ids-map (:id frame)) new-frame (-> frame - (geom/move delta)) + (gsh/move delta)) new-guides (->> guides (vals) (filter #(= (:frame-id %) (:id frame))) diff --git a/frontend/src/app/main/errors.cljs b/frontend/src/app/main/errors.cljs index 9bacf35c5..19dba98dc 100644 --- a/frontend/src/app/main/errors.cljs +++ b/frontend/src/app/main/errors.cljs @@ -7,6 +7,7 @@ (ns app.main.errors "Generic error handling" (:require + [cuerdas.core :as str] [app.common.data :as d] [app.common.data.macros :as dm] [app.common.exceptions :as ex] @@ -200,9 +201,12 @@ (defonce uncaught-error-handler (letfn [(on-error [event] - (.preventDefault ^js event) - (some-> (unchecked-get event "error") - (on-unhandled-error)))] + ;; EvalError is a debug error that happens for unknown reason + (when-not (str/includes? (.-message event) "EvalError") + (.error js/console event) + (.preventDefault ^js event) + (some-> (unchecked-get event "error") + (on-unhandled-error))))] (.addEventListener glob/window "error" on-error) (fn [] (.removeEventListener glob/window "error" on-error)))) diff --git a/frontend/src/app/main/ui/hooks/resize.cljs b/frontend/src/app/main/ui/hooks/resize.cljs index bd7268070..a2c52cd36 100644 --- a/frontend/src/app/main/ui/hooks/resize.cljs +++ b/frontend/src/app/main/ui/hooks/resize.cljs @@ -6,6 +6,7 @@ (ns app.main.ui.hooks.resize (:require + [app.main.ui.hooks :as hooks] [app.common.geom.point :as gpt] [app.common.logging :as log] [app.main.ui.context :as ctx] @@ -77,26 +78,31 @@ (let [prev-val-ref (mf/use-ref nil) current-observer-ref (mf/use-ref nil) + callback-ref (hooks/use-update-var {:callback callback}) + ;; We use the ref as a callback when the dom node is ready (or change) node-ref (mf/use-callback - (mf/deps callback) (fn [^js node] - (let [^js current-observer (mf/ref-val current-observer-ref) - ^js prev-val (mf/ref-val prev-val-ref)] + (when (some? node) + (let [^js current-observer (mf/ref-val current-observer-ref) + ^js prev-val (mf/ref-val prev-val-ref)] - (when (and (not= prev-val node) (some? current-observer)) - (log/debug :action "disconnect" :js/prev-val prev-val :js/node node) - (.disconnect current-observer) - (mf/set-ref-val! current-observer-ref nil)) + (when (and (not= prev-val node) (some? current-observer)) + (log/debug :action "disconnect" :js/prev-val prev-val :js/node node) + (.disconnect current-observer) + (mf/set-ref-val! current-observer-ref nil)) - (when (and (not= prev-val node) (some? node)) - (let [^js observer - (js/ResizeObserver. #(callback last-resize-type (dom/get-client-size node)))] - (mf/set-ref-val! current-observer-ref observer) - (log/debug :action "observe" :js/node node :js/observer observer) - (.observe observer node)))) - (mf/set-ref-val! prev-val-ref node)))] + (when (and (not= prev-val node) (some? node)) + (let [^js observer + (js/ResizeObserver. + #(let [callback (get @callback-ref :callback)] + (callback last-resize-type (dom/get-client-size node))))] + (mf/set-ref-val! current-observer-ref observer) + (log/debug :action "observe" :js/node node :js/observer observer) + (.observe observer node)))) + + (mf/set-ref-val! prev-val-ref node))))] (mf/use-effect (fn [] diff --git a/frontend/src/app/main/ui/shapes/circle.cljs b/frontend/src/app/main/ui/shapes/circle.cljs index 592476540..f5db9bf3e 100644 --- a/frontend/src/app/main/ui/shapes/circle.cljs +++ b/frontend/src/app/main/ui/shapes/circle.cljs @@ -6,7 +6,7 @@ (ns app.main.ui.shapes.circle (:require - [app.common.geom.shapes :as geom] + [app.common.geom.shapes :as gsh] [app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.custom-stroke :refer [shape-custom-strokes]] [app.util.object :as obj] @@ -17,7 +17,7 @@ [props] (let [shape (unchecked-get props "shape") {:keys [x y width height]} shape - transform (geom/transform-matrix shape) + transform (gsh/transform-str shape) cx (+ x (/ width 2)) cy (+ y (/ height 2)) diff --git a/frontend/src/app/main/ui/shapes/fills.cljs b/frontend/src/app/main/ui/shapes/fills.cljs index 788a43315..36cc2c24b 100644 --- a/frontend/src/app/main/ui/shapes/fills.cljs +++ b/frontend/src/app/main/ui/shapes/fills.cljs @@ -41,7 +41,7 @@ (cfg/resolve-file-media (:fill-image shape))) embed (embed/use-data-uris [uri]) - transform (gsh/transform-matrix shape) + transform (gsh/transform-str shape) ;; When true the image has not loaded yet loading? (and (some? uri) (not (contains? embed uri))) diff --git a/frontend/src/app/main/ui/shapes/frame.cljs b/frontend/src/app/main/ui/shapes/frame.cljs index 3275e6ab7..5eb258c54 100644 --- a/frontend/src/app/main/ui/shapes/frame.cljs +++ b/frontend/src/app/main/ui/shapes/frame.cljs @@ -28,12 +28,14 @@ [{:keys [shape render-id]}] (when (= :frame (:type shape)) (let [{:keys [x y width height]} shape + transform (gsh/transform-str shape) props (-> (attrs/extract-style-attrs shape) (obj/merge! #js {:x x :y y :width width - :height height})) + :height height + :transform transform})) path? (some? (.-d props))] [:clipPath {:id (frame-clip-id shape render-id) :class "frame-clip"} (if path? @@ -46,12 +48,12 @@ (let [shape (obj/get props "shape")] (when (:thumbnail shape) (let [{:keys [x y width height show-content]} shape - transform (gsh/transform-matrix shape) + transform (gsh/transform-str shape) props (-> (attrs/extract-style-attrs shape) (obj/merge! #js {:x x :y y - :transform (str transform) + :transform transform :width width :height height :className "frame-background"})) @@ -91,13 +93,13 @@ shape (unchecked-get props "shape") {:keys [x y width height show-content]} shape - transform (gsh/transform-matrix shape) + transform (gsh/transform-str shape) props (-> (attrs/extract-style-attrs shape) (obj/merge! #js {:x x :y y - :transform (str transform) + :transform transform :width width :height height :className "frame-background"})) diff --git a/frontend/src/app/main/ui/shapes/gradients.cljs b/frontend/src/app/main/ui/shapes/gradients.cljs index aaee2d529..a57678bf4 100644 --- a/frontend/src/app/main/ui/shapes/gradients.cljs +++ b/frontend/src/app/main/ui/shapes/gradients.cljs @@ -27,13 +27,15 @@ (obj/set! "penpot:width" (:width gradient)))) (mf/defc linear-gradient [{:keys [id gradient shape]}] - (let [transform (when (= :path (:type shape)) (gsh/transform-matrix shape nil (gpt/point 0.5 0.5))) + (let [transform (when (= :path (:type shape)) + (gsh/transform-matrix shape nil (gpt/point 0.5 0.5))) + base-props #js {:id id :x1 (:start-x gradient) :y1 (:start-y gradient) :x2 (:end-x gradient) :y2 (:end-y gradient) - :gradientTransform transform} + :gradientTransform (dm/str transform)} include-metadata? (mf/use-ctx ed/include-metadata-ctx) diff --git a/frontend/src/app/main/ui/shapes/image.cljs b/frontend/src/app/main/ui/shapes/image.cljs index 5a80f7844..c13fa3a20 100644 --- a/frontend/src/app/main/ui/shapes/image.cljs +++ b/frontend/src/app/main/ui/shapes/image.cljs @@ -18,7 +18,7 @@ (let [shape (unchecked-get props "shape") {:keys [x y width height]} shape - transform (gsh/transform-matrix shape) + transform (gsh/transform-str shape) props (-> (attrs/extract-style-attrs shape) (obj/merge! (attrs/extract-border-radius-attrs shape)) (obj/merge! diff --git a/frontend/src/app/main/ui/shapes/rect.cljs b/frontend/src/app/main/ui/shapes/rect.cljs index 8c8a24e79..e75a804ee 100644 --- a/frontend/src/app/main/ui/shapes/rect.cljs +++ b/frontend/src/app/main/ui/shapes/rect.cljs @@ -17,7 +17,7 @@ [props] (let [shape (unchecked-get props "shape") {:keys [x y width height]} shape - transform (gsh/transform-matrix shape) + transform (gsh/transform-str shape) props (-> (attrs/extract-style-attrs shape) (obj/merge! diff --git a/frontend/src/app/main/ui/shapes/svg_raw.cljs b/frontend/src/app/main/ui/shapes/svg_raw.cljs index 690ee6022..188390cac 100644 --- a/frontend/src/app/main/ui/shapes/svg_raw.cljs +++ b/frontend/src/app/main/ui/shapes/svg_raw.cljs @@ -60,7 +60,7 @@ (obj/set! "preserveAspectRatio" "none"))] [:& (mf/provider svg-ids-ctx) {:value ids-mapping} - [:g.svg-raw {:transform (dm/str (gsh/transform-matrix shape))} + [:g.svg-raw {:transform (gsh/transform-str shape)} [:> "svg" attrs children]]])) (mf/defc svg-element diff --git a/frontend/src/app/main/ui/shapes/text/fo_text.cljs b/frontend/src/app/main/ui/shapes/text/fo_text.cljs index 8f3f53575..158b6c117 100644 --- a/frontend/src/app/main/ui/shapes/text/fo_text.cljs +++ b/frontend/src/app/main/ui/shapes/text/fo_text.cljs @@ -8,7 +8,7 @@ (:require [app.common.colors :as clr] [app.common.data :as d] - [app.common.geom.shapes :as geom] + [app.common.geom.shapes :as gsh] [app.main.ui.context :as muc] [app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.text.styles :as sts] @@ -192,7 +192,7 @@ ::mf/forward-ref true} [props ref] (let [shape (obj/get props "shape") - transform (str (geom/transform-matrix shape)) + transform (gsh/transform-str shape) {:keys [id x y width height content]} shape grow-type (obj/get props "grow-type") ;; This is only needed in workspace diff --git a/frontend/src/app/main/ui/shapes/text/svg_text.cljs b/frontend/src/app/main/ui/shapes/text/svg_text.cljs index 4c8054c24..7a5fad4d2 100644 --- a/frontend/src/app/main/ui/shapes/text/svg_text.cljs +++ b/frontend/src/app/main/ui/shapes/text/svg_text.cljs @@ -60,7 +60,7 @@ {:keys [x y width height position-data]} shape - transform (str (gsh/transform-matrix shape {:no-flip true})) + transform (gsh/transform-str shape {:no-flip true}) ;; These position attributes are not really necesary but they are convenient for for the export group-props (-> #js {:transform transform diff --git a/frontend/src/app/main/ui/viewer/handoff/render.cljs b/frontend/src/app/main/ui/viewer/handoff/render.cljs index d46c2eabd..30df848d7 100644 --- a/frontend/src/app/main/ui/viewer/handoff/render.cljs +++ b/frontend/src/app/main/ui/viewer/handoff/render.cljs @@ -7,7 +7,7 @@ (ns app.main.ui.viewer.handoff.render "The main container for a frame in handoff mode" (:require - [app.common.geom.shapes :as geom] + [app.common.geom.shapes :as gsh] [app.common.pages.helpers :as cph] [app.main.data.viewer :as dv] [app.main.store :as st] @@ -87,7 +87,7 @@ [props] (let [shape (unchecked-get props "shape") childs (mapv #(get objects %) (:shapes shape)) - shape (geom/transform-shape shape) + shape (gsh/transform-shape shape) props (-> (obj/create) (obj/merge! props) @@ -166,8 +166,8 @@ (mf/use-memo (mf/deps objects) #(svg-raw-container-factory objects))] (when (and shape (not (:hidden shape))) - (let [shape (-> (geom/transform-shape shape) - (geom/translate-to-frame frame)) + (let [shape (-> (gsh/transform-shape shape) + (gsh/translate-to-frame frame)) opts #js {:shape shape :frame frame}] (case (:type shape) diff --git a/frontend/src/app/main/ui/viewer/shapes.cljs b/frontend/src/app/main/ui/viewer/shapes.cljs index 4e28186b7..3398a463e 100644 --- a/frontend/src/app/main/ui/viewer/shapes.cljs +++ b/frontend/src/app/main/ui/viewer/shapes.cljs @@ -8,7 +8,7 @@ "The main container for a frame in viewer mode" (:require [app.common.data :as d] - [app.common.geom.shapes :as geom] + [app.common.geom.shapes :as gsh] [app.common.pages.helpers :as cph] [app.common.spec.interactions :as cti] [app.main.data.viewer :as dv] @@ -204,7 +204,7 @@ :stroke-width (if interactions-show? 1 0) :fill-opacity (if interactions-show? 0.2 0) :style {:pointer-events (when frame? "none")} - :transform (geom/transform-matrix shape)}]))) + :transform (gsh/transform-str shape)}]))) (defn generic-wrapper-factory "Wrap some svg shape and add interaction controls" @@ -306,7 +306,7 @@ [props] (let [shape (obj/get props "shape") childs (mapv #(get objects %) (:shapes shape)) - shape (geom/transform-shape shape) + shape (gsh/transform-shape shape) props (obj/merge! #js {} props #js {:shape shape :childs childs @@ -384,9 +384,9 @@ (mf/use-memo (mf/deps objects) #(svg-raw-container-factory objects))] (when (and shape (not (:hidden shape))) - (let [shape (-> (geom/transform-shape shape) - (geom/translate-to-frame frame) - (cond-> fixed? (geom/move delta))) + (let [shape (-> (gsh/transform-shape shape) + (gsh/translate-to-frame frame) + (cond-> fixed? (gsh/move delta))) opts #js {:shape shape :objects objects}] diff --git a/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs b/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs index ae25c9177..1722af34e 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs @@ -89,8 +89,9 @@ frame? [shape-node (dom/query shape-node ".frame-children") - (dom/query (str "#thumbnail-container-" id)) - (dom/query (str "#thumbnail-" id))] + (dom/query (dm/str "#thumbnail-container-" id)) + (dom/query (dm/str "#thumbnail-" id)) + (dom/query (dm/str "#frame-title-" id))] ;; For groups we don't want to transform the whole group but only ;; its filters/masks diff --git a/frontend/src/app/main/ui/workspace/shapes/text/text_edition_outline.cljs b/frontend/src/app/main/ui/workspace/shapes/text/text_edition_outline.cljs index ba2bfa059..ad76c2f65 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/text_edition_outline.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/text_edition_outline.cljs @@ -23,7 +23,7 @@ (some? text-modifier) (dwt/apply-text-modifier text-modifier)) - transform (gsh/transform-matrix shape {:no-flip true}) + transform (gsh/transform-str shape {:no-flip true}) {:keys [x y width height]} shape] [:rect.main.viewport-selrect @@ -31,7 +31,7 @@ :y y :width width :height height - :transform (str transform) + :transform transform :style {:stroke "var(--color-select)" :stroke-width (/ 1 zoom) :fill "none"}}])) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 88ee7e26b..38b2b7e1f 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -311,7 +311,7 @@ :zoom zoom}]) [:& widgets/frame-titles - {:objects objects-modified + {:objects base-objects :selected selected :zoom zoom :modifiers modifiers diff --git a/frontend/src/app/main/ui/workspace/viewport/outline.cljs b/frontend/src/app/main/ui/workspace/viewport/outline.cljs index 95d58b016..ae79dcbbc 100644 --- a/frontend/src/app/main/ui/workspace/viewport/outline.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/outline.cljs @@ -23,7 +23,7 @@ zoom (obj/get props "zoom" 1) color (unchecked-get props "color") - transform (gsh/transform-matrix shape) + transform (gsh/transform-str shape) path? (= :path (:type shape)) path-data (mf/use-memo diff --git a/frontend/src/app/main/ui/workspace/viewport/selection.cljs b/frontend/src/app/main/ui/workspace/viewport/selection.cljs index 7b1a5ebd3..4a1e4f7de 100644 --- a/frontend/src/app/main/ui/workspace/viewport/selection.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/selection.cljs @@ -170,7 +170,7 @@ :height size :fill (if (debug? :handlers) "blue" "none") :stroke-width 0 - :transform (str transform) + :transform (dm/str transform) :on-mouse-down on-rotate}])) (mf/defc resize-point-handler @@ -224,7 +224,7 @@ height (/ resize-side-height zoom) offset-y (if (= align :outside) (- height) (- (/ height 2))) target-y (+ y offset-y) - transform-str (str (gmt/multiply transform (gmt/rotate-matrix angle (gpt/point x y))))] + transform-str (dm/str (gmt/multiply transform (gmt/rotate-matrix angle (gpt/point x y))))] [:g.resize-handler (when show-handler? [:circle {:r (/ resize-point-radius zoom) @@ -271,13 +271,13 @@ current-transform (mf/deref refs/current-transform) selrect (:selrect shape) - transform (gsh/transform-matrix shape {:no-flip true})] + transform (gsh/transform-str shape {:no-flip true})] (when (not (#{:move :rotate} current-transform)) [:g.controls {:pointer-events (if disable-handlers "none" "visible")} ;; Selection rect [:& selection-rect {:rect selrect - :transform (str transform) + :transform transform :zoom zoom :color color :on-move-selected on-move-selected @@ -327,7 +327,7 @@ (let [{:keys [x y width height]} shape] [:g.controls [:rect.main {:x x :y y - :transform (str (gsh/transform-matrix shape)) + :transform (gsh/transform-str shape) :width width :height height :pointer-events "visible" diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs index e62258148..314233ae4 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs @@ -94,9 +94,11 @@ (mf/defc frame-title {::mf/wrap [mf/memo]} [{:keys [frame modifiers selected? zoom show-artboard-names? on-frame-enter on-frame-leave on-frame-select]}] - (let [{:keys [width x y]} (gsh/transform-shape frame) + (let [{:keys [width x y]} frame label-pos (gpt/point x (- y (/ 10 zoom))) + frame-transform (gsh/transform-str frame) + on-mouse-down (mf/use-callback (mf/deps (:id frame) on-frame-select) @@ -137,11 +139,10 @@ text-pos-x (if (:use-for-thumbnail? frame) 15 0)] (when (not (:hidden frame)) - [:* + [:g {:id (dm/str "frame-title-" (:id frame)) + :transform frame-transform} (when (:use-for-thumbnail? frame) - [:g {:transform (str (when (and selected? modifiers) - (str (:displacement modifiers) " ")) - (text-transform label-pos zoom))} + [:g {:transform (dm/str (text-transform label-pos zoom))} [:svg {:x 0 :y -9 :width 12 @@ -155,9 +156,7 @@ :width width :height 20 :class "workspace-frame-label" - :transform (str (when (and selected? modifiers) - (str (:displacement modifiers) " ")) - (text-transform label-pos zoom)) + :transform (dm/str (text-transform label-pos zoom)) :style {:fill (when selected? "var(--color-primary-dark)")} :visibility (if show-artboard-names? "visible" "hidden") :on-mouse-down on-mouse-down