0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-13 02:28:18 -05:00

🐛 Fixes problem with flipped texts

This commit is contained in:
alonso.torres 2020-11-27 15:14:53 +01:00
parent 2a17f0e507
commit 0046b60c93
5 changed files with 80 additions and 72 deletions

View file

@ -44,26 +44,29 @@
(move shape (gpt/point dx dy)))) (move shape (gpt/point dx dy))))
;; --- Resize (Dimensions) ;; --- Resize (Dimensions)
;; Fixme: Improve using modifiers instead of calculating the selrect/points
(defn resize (defn resize
[shape width height] [shape width height]
(us/assert map? shape) (us/assert map? shape)
(us/assert number? width) (us/assert number? width)
(us/assert number? height) (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) (let [shape-transform (:transform shape (gmt/matrix))
points (-> selrect gpr/rect->points (gtr/transform-points center (:transform shape)))] 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 (-> shape
(assoc :width width) (update :modifiers assoc
(assoc :height height) :resize-vector scalev
(assoc :selrect selrect) :resize-origin origin
(assoc :points points)))) :resize-transform shape-transform
:resize-transform-inverse shape-transform-inv)
(gtr/transform-shape))))
(defn resize-rect (defn resize-rect
[shape attr value] [shape attr value]
@ -258,7 +261,10 @@
(defn points->selrect [points] (gpr/points->selrect points)) (defn points->selrect [points] (gpr/points->selrect points))
(defn transform-shape [shape] (gtr/transform-shape shape)) (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-point-center [point center transform] (gtr/transform-point-center point center transform))
(defn transform-rect [rect mtx] (gtr/transform-rect rect mtx)) (defn transform-rect [rect mtx] (gtr/transform-rect rect mtx))

View file

@ -22,12 +22,17 @@
(defn transform-matrix (defn transform-matrix
"Returns a transformation matrix without changing the shape properties. "Returns a transformation matrix without changing the shape properties.
The result should be used in a `transform` attribute in svg" 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) (let [shape-center (or (gco/center-shape shape)
(gpt/point 0 0))] (gpt/point 0 0))]
(-> (gmt/matrix) (-> (gmt/matrix)
(gmt/translate shape-center) (gmt/translate shape-center)
(gmt/multiply (:transform shape (gmt/matrix))) (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)))))) (gmt/translate (gpt/negate shape-center))))))
(defn transform-point-center (defn transform-point-center

View file

@ -65,52 +65,47 @@
:position :top-left :position :top-left
:props {:cx x :cy y}} :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 {:type :resize-side
:position :top :position :top
:props {:x x :y y :length width :angle 0 }} :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 {:type :resize-side
:position :right :position :right
:props {:x (+ x width) :y y :length height :angle 90 }} :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 {:type :resize-side
:position :bottom :position :bottom
:props {:x (+ x width) :y (+ y height) :length width :angle 180 }} :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 {:type :resize-side
:position :left :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]}] (mf/defc rotation-handler [{:keys [cx cy transform position rotation zoom on-rotate]}]
(let [size (/ rotation-handler-size zoom) (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]}] (mf/defc resize-side-handler [{:keys [x y length angle zoom position rotation transform on-resize]}]
(let [res-point (if (#{:top :bottom} position) (let [res-point (if (#{:top :bottom} position)
{:y y} {:y y}
{:x x})] {:x x})
[:rect {:x (+ x (/ resize-point-rect-size zoom)) 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)) :y (- y (/ resize-side-height 2 zoom))
:width (max 0 (- length (/ (* resize-point-rect-size 2) zoom))) :width width
:height (/ resize-side-height zoom) :height height
:transform (gmt/multiply transform :transform (gmt/multiply transform
(gmt/rotate-matrix angle (gpt/point x y))) (gmt/rotate-matrix angle (gpt/point x y)))
:on-mouse-down #(on-resize res-point %) :on-mouse-down #(on-resize res-point %)
@ -183,7 +180,7 @@
current-transform (mf/deref refs/current-transform) current-transform (mf/deref refs/current-transform)
selrect (:selrect shape) selrect (:selrect shape)
transform (geom/transform-matrix shape) transform (geom/transform-matrix shape {:no-flip true})
tr-shape (geom/transform-shape shape)] tr-shape (geom/transform-shape shape)]

View file

@ -10,6 +10,7 @@
(ns app.main.ui.workspace.shapes.text (ns app.main.ui.workspace.shapes.text
(:require (:require
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.common :as dwc] [app.main.data.workspace.common :as dwc]
[app.main.data.workspace.texts :as dwt] [app.main.data.workspace.texts :as dwt]
@ -40,14 +41,11 @@
;; --- Text Wrapper for workspace ;; --- 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 (let [{shape-width :width shape-height :height} selrect
undo-transaction (get-in @st/state [:workspace-undo :transaction])] undo-transaction (get-in @st/state [:workspace-undo :transaction])]
(when (not undo-transaction) (st/emit! dwc/start-undo-transaction)) (when (not undo-transaction) (st/emit! dwc/start-undo-transaction))
(when (and (> new-width 0) (when (and (> new-width 0) (> new-height 0))
(> new-height 0)
(or (not= shape-width new-width)
(not= shape-height new-height)))
(cond (cond
(and overflow-text (not= :fixed grow-type)) (and overflow-text (not= :fixed grow-type))
(st/emit! (dwt/update-overflow-text id false)) (st/emit! (dwt/update-overflow-text id false))
@ -58,17 +56,19 @@
(and (= :fixed grow-type) overflow-text (<= new-height shape-height)) (and (= :fixed grow-type) overflow-text (<= new-height shape-height))
(st/emit! (dwt/update-overflow-text id false)) (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) (st/emit! (dw/update-dimensions [id] :width new-width)
(dw/update-dimensions [id] :height new-height)) (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)))) (st/emit! (dw/update-dimensions [id] :height new-height))))
(when (not undo-transaction) (st/emit! dwc/discard-undo-transaction)))) (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/use-effect
(mf/deps shape root query) (mf/deps id selrect grow-type overflow-text root query)
(fn [] (fn []
(let [on-change (fn [entries] (let [on-change (fn [entries]
(when (seq entries) (when (seq entries)
@ -77,7 +77,7 @@
(timers/raf (timers/raf
#(let [width (obj/get-in entries [0 "contentRect" "width"]) #(let [width (obj/get-in entries [0 "contentRect" "width"])
height (obj/get-in entries [0 "contentRect" "height"])] 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) observer (js/ResizeObserver. on-change)
node (when root (dom/query root query))] node (when root (dom/query root query))]
(when node (.observe observer node)) (when node (.observe observer node))
@ -106,12 +106,9 @@
handle-double-click (use-double-click shape selected?) handle-double-click (use-double-click shape selected?)
text-ref (mf/use-ref nil) text-ref (mf/use-ref nil)
text-node (mf/ref-val text-ref) text-node (mf/ref-val text-ref)]
edit-text-ref (mf/use-ref nil)
edit-text-node (mf/ref-val edit-text-ref)]
(resize-observer shape text-node ".paragraph-set") (resize-observer shape text-node ".paragraph-set")
(resize-observer shape edit-text-node ".paragraph-set")
[:> shape-container {:shape shape} [:> shape-container {:shape shape}
[:& text/text-shape {:key "text-shape" [:& text/text-shape {:key "text-shape"
@ -121,7 +118,6 @@
:style {:display (when edition? "none")}}] :style {:display (when edition? "none")}}]
(when edition? (when edition?
[:& editor/text-shape-edit {:key "editor" [:& editor/text-shape-edit {:key "editor"
:ref edit-text-ref
:shape shape}]) :shape shape}])
(when-not edition? (when-not edition?

View file

@ -117,8 +117,13 @@
[shape props] [shape props]
(mf/html (mf/html
(let [element (obj/get props "element") (let [element (obj/get props "element")
props (obj/merge! props #js {:shape shape})] type (obj/get element "type")
(case (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] "root" [:> editor-root-node props]
"paragraph-set" [:> editor-paragraph-set-node props] "paragraph-set" [:> editor-paragraph-set-node props]
"paragraph" [:> editor-paragraph-node props] "paragraph" [:> editor-paragraph-node props]
@ -138,13 +143,12 @@
[props ref] [props ref]
(let [shape (unchecked-get props "shape") (let [shape (unchecked-get props "shape")
node-ref (unchecked-get props "node-ref") 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 {:keys [id x y width height content grow-type]} shape
zoom (mf/deref refs/selected-zoom) zoom (mf/deref refs/selected-zoom)
state (mf/use-state #(parse-content content)) state (mf/use-state #(parse-content content))
editor (mf/use-memo #(dwt/create-editor)) editor (mf/use-memo #(dwt/create-editor))
;;self-ref (mf/use-ref) self-ref (mf/use-ref)
selecting-ref (mf/use-ref) selecting-ref (mf/use-ref)
measure-ref (mf/use-ref) measure-ref (mf/use-ref)
@ -164,7 +168,7 @@
(let [sidebar (dom/get-element "settings-bar") (let [sidebar (dom/get-element "settings-bar")
assets (dom/get-element-by-class "assets-bar") assets (dom/get-element-by-class "assets-bar")
cpicker (dom/get-element-by-class "colorpicker-tooltip") 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) target (dom/get-target event)
selecting? (mf/ref-val selecting-ref)] selecting? (mf/ref-val selecting-ref)]
(when-not (or (and sidebar (.contains sidebar target)) (when-not (or (and sidebar (.contains sidebar target))
@ -227,7 +231,7 @@
(reset! state (parse-content content)) (reset! state (parse-content content))
(reset! content-var content))) (reset! content-var content)))
[:foreignObject {:ref ref [:foreignObject {:ref self-ref
:transform (gsh/transform-matrix shape) :transform (gsh/transform-matrix shape)
:x x :y y :x x :y y
:width (if (#{:auto-width} grow-type) 10000 width) :width (if (#{:auto-width} grow-type) 10000 width)