From 0046b60c93700d4fa97f7336244ecdb761f22de3 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 27 Nov 2020 15:14:53 +0100 Subject: [PATCH] :bug: Fixes problem with flipped texts --- common/app/common/geom/shapes.cljc | 32 +++++---- common/app/common/geom/shapes/transforms.cljc | 7 +- .../src/app/main/ui/workspace/selection.cljs | 71 +++++++++---------- .../app/main/ui/workspace/shapes/text.cljs | 26 +++---- .../main/ui/workspace/shapes/text/editor.cljs | 16 +++-- 5 files changed, 80 insertions(+), 72 deletions(-) diff --git a/common/app/common/geom/shapes.cljc b/common/app/common/geom/shapes.cljc index 5109d9d6a..de210cdaa 100644 --- a/common/app/common/geom/shapes.cljc +++ b/common/app/common/geom/shapes.cljc @@ -44,26 +44,29 @@ (move shape (gpt/point dx dy)))) ;; --- Resize (Dimensions) -;; Fixme: Improve using modifiers instead of calculating the selrect/points (defn resize [shape width height] (us/assert map? shape) (us/assert number? width) (us/assert number? height) - (let [selrect (-> (:selrect shape) - (assoc :width width) - (assoc :height height) - (assoc :x2 (+ (-> shape :selrect :x1) width)) - (assoc :y2 (+ (-> shape :selrect :y1) height))) - center (gco/center-selrect selrect) - points (-> selrect gpr/rect->points (gtr/transform-points center (:transform shape)))] + (let [shape-transform (:transform shape (gmt/matrix)) + shape-transform-inv (:transform-inverse shape (gmt/matrix)) + shape-center (gco/center-shape shape) + {sr-width :width sr-height :height} (:selrect shape) + origin (-> (gpt/point (:selrect shape)) + (gtr/transform-point-center shape-center shape-transform)) + + scalev (gpt/divide (gpt/point width height) + (gpt/point sr-width sr-height))] (-> shape - (assoc :width width) - (assoc :height height) - (assoc :selrect selrect) - (assoc :points points)))) + (update :modifiers assoc + :resize-vector scalev + :resize-origin origin + :resize-transform shape-transform + :resize-transform-inverse shape-transform-inv) + (gtr/transform-shape)))) (defn resize-rect [shape attr value] @@ -258,7 +261,10 @@ (defn points->selrect [points] (gpr/points->selrect points)) (defn transform-shape [shape] (gtr/transform-shape shape)) -(defn transform-matrix [shape] (gtr/transform-matrix shape)) +(defn transform-matrix + ([shape] (gtr/transform-matrix shape)) + ([shape options] (gtr/transform-matrix shape options))) + (defn transform-point-center [point center transform] (gtr/transform-point-center point center transform)) (defn transform-rect [rect mtx] (gtr/transform-rect rect mtx)) diff --git a/common/app/common/geom/shapes/transforms.cljc b/common/app/common/geom/shapes/transforms.cljc index deebb5966..b5bc71bee 100644 --- a/common/app/common/geom/shapes/transforms.cljc +++ b/common/app/common/geom/shapes/transforms.cljc @@ -22,12 +22,17 @@ (defn transform-matrix "Returns a transformation matrix without changing the shape properties. The result should be used in a `transform` attribute in svg" - ([{:keys [x y] :as shape}] + ([shape] (transform-matrix shape nil)) + ([{:keys [x y flip-x flip-y] :as shape} {:keys [no-flip]}] (let [shape-center (or (gco/center-shape shape) (gpt/point 0 0))] (-> (gmt/matrix) (gmt/translate shape-center) + (gmt/multiply (:transform shape (gmt/matrix))) + (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-point-center diff --git a/frontend/src/app/main/ui/workspace/selection.cljs b/frontend/src/app/main/ui/workspace/selection.cljs index 5ea3d5ea7..f14e5d956 100644 --- a/frontend/src/app/main/ui/workspace/selection.cljs +++ b/frontend/src/app/main/ui/workspace/selection.cljs @@ -65,52 +65,47 @@ :position :top-left :props {:cx x :cy y}} - ;; TOP + {:type :rotation + :position :top-right + :props {:cx (+ x width) :cy y}} + + {:type :resize-point + :position :top-right + :props {:cx (+ x width) :cy y}} + + {:type :rotation + :position :bottom-right + :props {:cx (+ x width) :cy (+ y height)}} + + {:type :resize-point + :position :bottom-right + :props {:cx (+ x width) :cy (+ y height)}} + + {:type :rotation + :position :bottom-left + :props {:cx x :cy (+ y height)}} + + {:type :resize-point + :position :bottom-left + :props {:cx x :cy (+ y height)}} + {:type :resize-side :position :top :props {:x x :y y :length width :angle 0 }} - ;; TOP-RIGHT - {:type :rotation - :position :top-right - :props {:cx (+ x width) :cy y}} - - {:type :resize-point - :position :top-right - :props {:cx (+ x width) :cy y}} - - ;; RIGHT {:type :resize-side :position :right :props {:x (+ x width) :y y :length height :angle 90 }} - ;; BOTTOM-RIGHT - {:type :rotation - :position :bottom-right - :props {:cx (+ x width) :cy (+ y height)}} - - {:type :resize-point - :position :bottom-right - :props {:cx (+ x width) :cy (+ y height)}} - - ;; BOTTOM {:type :resize-side :position :bottom :props {:x (+ x width) :y (+ y height) :length width :angle 180 }} - ;; BOTTOM-LEFT - {:type :rotation - :position :bottom-left - :props {:cx x :cy (+ y height)}} - - {:type :resize-point - :position :bottom-left - :props {:cx x :cy (+ y height)}} - - ;; LEFT {:type :resize-side :position :left - :props {:x x :y (+ y height) :length height :angle 270 }}]) + :props {:x x :y (+ y height) :length height :angle 270 }} + + ]) (mf/defc rotation-handler [{:keys [cx cy transform position rotation zoom on-rotate]}] (let [size (/ rotation-handler-size zoom) @@ -160,11 +155,13 @@ (mf/defc resize-side-handler [{:keys [x y length angle zoom position rotation transform on-resize]}] (let [res-point (if (#{:top :bottom} position) {:y y} - {:x x})] - [:rect {:x (+ x (/ resize-point-rect-size zoom)) + {:x x}) + width length #_(max 0 (- length (/ (* resize-point-rect-size 2) zoom))) + height (/ resize-side-height zoom)] + [:rect {:x x :y (- y (/ resize-side-height 2 zoom)) - :width (max 0 (- length (/ (* resize-point-rect-size 2) zoom))) - :height (/ resize-side-height zoom) + :width width + :height height :transform (gmt/multiply transform (gmt/rotate-matrix angle (gpt/point x y))) :on-mouse-down #(on-resize res-point %) @@ -183,7 +180,7 @@ current-transform (mf/deref refs/current-transform) selrect (:selrect shape) - transform (geom/transform-matrix shape) + transform (geom/transform-matrix shape {:no-flip true}) tr-shape (geom/transform-shape shape)] diff --git a/frontend/src/app/main/ui/workspace/shapes/text.cljs b/frontend/src/app/main/ui/workspace/shapes/text.cljs index f6b08211d..52ddeba2a 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text.cljs @@ -10,6 +10,7 @@ (ns app.main.ui.workspace.shapes.text (:require [app.common.geom.shapes :as gsh] + [app.common.math :as mth] [app.main.data.workspace :as dw] [app.main.data.workspace.common :as dwc] [app.main.data.workspace.texts :as dwt] @@ -40,14 +41,11 @@ ;; --- Text Wrapper for workspace -(defn handle-shape-resize [{:keys [name id selrect grow-type overflow-text]} new-width new-height] +(defn handle-shape-resize [{:keys [id selrect grow-type overflow-text]} new-width new-height] (let [{shape-width :width shape-height :height} selrect undo-transaction (get-in @st/state [:workspace-undo :transaction])] (when (not undo-transaction) (st/emit! dwc/start-undo-transaction)) - (when (and (> new-width 0) - (> new-height 0) - (or (not= shape-width new-width) - (not= shape-height new-height))) + (when (and (> new-width 0) (> new-height 0)) (cond (and overflow-text (not= :fixed grow-type)) (st/emit! (dwt/update-overflow-text id false)) @@ -58,17 +56,19 @@ (and (= :fixed grow-type) overflow-text (<= new-height shape-height)) (st/emit! (dwt/update-overflow-text id false)) - (= grow-type :auto-width) + (and (or (not= shape-width new-width) + (not= shape-height new-height)) + (= grow-type :auto-width)) (st/emit! (dw/update-dimensions [id] :width new-width) (dw/update-dimensions [id] :height new-height)) - (= grow-type :auto-height) + (and (not= shape-height new-height) (= grow-type :auto-height)) (st/emit! (dw/update-dimensions [id] :height new-height)))) (when (not undo-transaction) (st/emit! dwc/discard-undo-transaction)))) -(defn resize-observer [shape root query] +(defn resize-observer [{:keys [id selrect grow-type overflow-text] :as shape} root query] (mf/use-effect - (mf/deps shape root query) + (mf/deps id selrect grow-type overflow-text root query) (fn [] (let [on-change (fn [entries] (when (seq entries) @@ -77,7 +77,7 @@ (timers/raf #(let [width (obj/get-in entries [0 "contentRect" "width"]) height (obj/get-in entries [0 "contentRect" "height"])] - (handle-shape-resize shape width height))))) + (handle-shape-resize shape (mth/ceil width) (mth/ceil height)))))) observer (js/ResizeObserver. on-change) node (when root (dom/query root query))] (when node (.observe observer node)) @@ -106,12 +106,9 @@ handle-double-click (use-double-click shape selected?) text-ref (mf/use-ref nil) - text-node (mf/ref-val text-ref) - edit-text-ref (mf/use-ref nil) - edit-text-node (mf/ref-val edit-text-ref)] + text-node (mf/ref-val text-ref)] (resize-observer shape text-node ".paragraph-set") - (resize-observer shape edit-text-node ".paragraph-set") [:> shape-container {:shape shape} [:& text/text-shape {:key "text-shape" @@ -121,7 +118,6 @@ :style {:display (when edition? "none")}}] (when edition? [:& editor/text-shape-edit {:key "editor" - :ref edit-text-ref :shape shape}]) (when-not edition? 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 7aa43d8e6..c1652bffd 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/editor.cljs @@ -117,8 +117,13 @@ [shape props] (mf/html (let [element (obj/get props "element") - props (obj/merge! props #js {:shape shape})] - (case (obj/get element "type") + type (obj/get element "type") + props (obj/merge! props #js {:shape shape}) + props (cond-> props + (= type "root") (obj/set! "key" "root") + (= type "paragraph-set") (obj/set! "key" "paragraph-set"))] + + (case type "root" [:> editor-root-node props] "paragraph-set" [:> editor-paragraph-set-node props] "paragraph" [:> editor-paragraph-node props] @@ -138,13 +143,12 @@ [props ref] (let [shape (unchecked-get props "shape") node-ref (unchecked-get props "node-ref") - ;; read-only? (or (unchecked-get props "read-only?") false) {:keys [id x y width height content grow-type]} shape zoom (mf/deref refs/selected-zoom) state (mf/use-state #(parse-content content)) editor (mf/use-memo #(dwt/create-editor)) - ;;self-ref (mf/use-ref) + self-ref (mf/use-ref) selecting-ref (mf/use-ref) measure-ref (mf/use-ref) @@ -164,7 +168,7 @@ (let [sidebar (dom/get-element "settings-bar") assets (dom/get-element-by-class "assets-bar") cpicker (dom/get-element-by-class "colorpicker-tooltip") - self (when node-ref (mf/ref-val node-ref)) + self (mf/ref-val self-ref) target (dom/get-target event) selecting? (mf/ref-val selecting-ref)] (when-not (or (and sidebar (.contains sidebar target)) @@ -227,7 +231,7 @@ (reset! state (parse-content content)) (reset! content-var content))) - [:foreignObject {:ref ref + [:foreignObject {:ref self-ref :transform (gsh/transform-matrix shape) :x x :y y :width (if (#{:auto-width} grow-type) 10000 width)