From d83459f67403b7a9e348fe8bf202389072b0246b Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 17 Feb 2022 09:23:08 +0100 Subject: [PATCH] :sparkle: Change mutation listener --- .../app/main/ui/hooks/mutable_observer.cljs | 12 ++++--- .../app/main/ui/workspace/shapes/text.cljs | 29 +++++++-------- .../main/ui/workspace/shapes/text/editor.cljs | 35 +++++++++---------- frontend/src/app/util/dom.cljs | 9 ++--- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/frontend/src/app/main/ui/hooks/mutable_observer.cljs b/frontend/src/app/main/ui/hooks/mutable_observer.cljs index 42f8b2c1b..f9852fea9 100644 --- a/frontend/src/app/main/ui/hooks/mutable_observer.cljs +++ b/frontend/src/app/main/ui/hooks/mutable_observer.cljs @@ -6,6 +6,7 @@ (ns app.main.ui.hooks.mutable-observer (:require + [app.common.data :as d] [app.common.logging :as log] [rumext.alpha :as mf])) @@ -20,9 +21,12 @@ on-mutation (mf/use-callback (mf/deps on-change) - (fn [mutation] - (log/debug :action "mutation" :js/mutation mutation) - (on-change (mf/ref-val node-ref)))) + (fn [mutations] + (let [mutations + (->> mutations + (remove #(= "transform" (.-attributeName ^js %))))] + (when (d/not-empty? mutations) + (on-change (mf/ref-val node-ref)))))) set-node (mf/use-callback @@ -51,4 +55,4 @@ (.disconnect prev-obs) (mf/set-ref-val! prev-obs-ref nil))))) - set-node)) + [node-ref set-node])) diff --git a/frontend/src/app/main/ui/workspace/shapes/text.cljs b/frontend/src/app/main/ui/workspace/shapes/text.cljs index c31e71ad8..b2589c91e 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text.cljs @@ -125,14 +125,13 @@ (let [{:keys [id dirty?] :as shape} (unchecked-get props "shape") edition-ref (mf/use-memo (mf/deps id) #(l/derived (fn [o] (= id (:edition o))) refs/workspace-local)) edition? (mf/deref edition-ref) - shape-ref (mf/use-ref nil) local-position-data (mf/use-state nil) handle-change-foreign-object (fn [node] (when (some? node) - (mf/set-ref-val! shape-ref node) + (prn "change!") (let [position-data (utp/calc-position-data node) parent (dom/get-parent node) parent-transform (dom/get-attribute parent "transform") @@ -152,28 +151,30 @@ (gsh/transform-rect mtx)))))] (reset! local-position-data position-data)))) - on-change-node (use-mutable-observer handle-change-foreign-object)] + [shape-ref on-change-node] (use-mutable-observer handle-change-foreign-object)] ;; When the text is "dirty?" we get recalculate the positions (mf/use-layout-effect (mf/deps id dirty?) (fn [] - (let [node (mf/ref-val shape-ref) - position-data (utp/calc-position-data node)] - (reset! local-position-data nil) - (st/emit! (dch/update-shapes - [id] - (fn [shape] - (-> shape - (dissoc :dirty?) - (assoc :position-data position-data)))))))) + (let [node (mf/ref-val shape-ref)] + (when (and dirty? (some? node)) + (let [position-data (utp/calc-position-data node)] + (reset! local-position-data nil) + (st/emit! (dch/update-shapes + [id] + (fn [shape] + (-> shape + (dissoc :dirty?) + (assoc :position-data position-data))) + {:save-undo? false}))))))) [:> shape-container {:shape shape} ;; We keep hidden the shape when we're editing so it keeps track of the size ;; and updates the selrect accordingly [:* [:g.text-shape {:ref on-change-node - :opacity (when (or edition? (some? (:position-data shape))) 0) + :opacity (when (or edition? (some? (:position-data shape))) 0.2) :pointer-events "none"} ;; The `:key` prop here is mandatory because the @@ -186,7 +187,7 @@ :edition? edition? :key (str id edition?)}]] - (when (and (not edition?) (or (some? (:position-data shape)) (some? local-position-data))) + (when (and (or (some? (:position-data shape)) (some? local-position-data))) (let [shape (cond-> shape (some? @local-position-data) diff --git a/frontend/src/app/main/ui/workspace/shapes/text/editor.cljs b/frontend/src/app/main/ui/workspace/shapes/text/editor.cljs index f1179f7e7..4278a005c 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/editor.cljs @@ -241,25 +241,24 @@ clip-id (str "clip-" id) - shape-ref (mf/use-ref nil) - local-position-data (mf/use-state nil) + ;; local-position-data (mf/use-state nil) - handle-change-foreign-object - (mf/use-callback - (fn [node] - (when node - (mf/set-ref-val! shape-ref node) - (let [position-data (utp/calc-position-data node)] - (reset! local-position-data position-data))))) + ;;handle-change-foreign-object + ;;(mf/use-callback + ;; (fn [node] + ;; (when node + ;; (let [position-data (utp/calc-position-data node)] + ;; (reset! local-position-data position-data))))) + ;; + ;;[shape-ref on-change-node] (use-mutable-observer handle-change-foreign-object) - handle-interaction - (mf/use-callback - (fn [] - (handle-change-foreign-object (mf/ref-val shape-ref)))) + ;;handle-interaction + ;;(mf/use-callback + ;; (fn [] + ;; (handle-change-foreign-object (mf/ref-val shape-ref)))) + ] - on-change-node (use-mutable-observer handle-change-foreign-object)] - - (mf/use-effect + #_(mf/use-effect (mf/use-callback handle-interaction) (fn [] (let [keys [(events/listen js/document EventType.KEYUP handle-interaction) @@ -268,14 +267,14 @@ #(doseq [key keys] (events/unlistenByKey key))))) [:* - [:> shape-container {:shape shape + #_[:> shape-container {:shape shape :pointer-events "none"} [:& svg/text-shape {:shape (cond-> shape (some? @local-position-data) (assoc :position-data @local-position-data))}]] [:g.text-editor {:clip-path (str "url(#" clip-id ")") - :ref on-change-node + ;; :ref on-change-node :key (str "editor-" id)} [:defs ;; This clippath will cut the huge foreign object we use to calculate the automatic resize diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index d35c8c3ae..b8af3ed89 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -265,10 +265,11 @@ (defn bounding-rect->rect [rect] - {:x (or (.-left rect) (:left rect)) - :y (or (.-top rect) (:top rect)) - :width (or (.-width rect) (:width rect)) - :height (or (.-height rect) (:height rect))}) + (when (some? rect) + {:x (or (.-left rect) (:left rect)) + :y (or (.-top rect) (:top rect)) + :width (or (.-width rect) (:width rect)) + :height (or (.-height rect) (:height rect))})) (defn get-window-size []