mirror of
https://github.com/penpot/penpot.git
synced 2025-03-13 00:01:51 -05:00
✨ Improvements over text shape
This commit is contained in:
parent
62a2713c03
commit
df70cd5c50
6 changed files with 80 additions and 37 deletions
|
@ -1456,7 +1456,8 @@
|
|||
"a" #(st/emit! (select-for-drawing :frame))
|
||||
"b" #(st/emit! (select-for-drawing :rect))
|
||||
"e" #(st/emit! (select-for-drawing :circle))
|
||||
"t" #(st/emit! (select-for-drawing :text))
|
||||
"t" #(st/emit! dwtxt/start-edit-if-selected
|
||||
(select-for-drawing :text))
|
||||
"ctrl+c" #(st/emit! copy-selected)
|
||||
"ctrl+v" #(st/emit! paste)
|
||||
"escape" #(st/emit! :interrupt deselect-all)
|
||||
|
|
|
@ -186,3 +186,23 @@
|
|||
(defn update-root-attrs
|
||||
[options]
|
||||
(update-attrs (assoc options :pred is-root-node? :split false)))
|
||||
|
||||
(defn update-overflow-text [id value]
|
||||
(ptk/reify ::update-overflow-text
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [page-id (:current-page-id state)]
|
||||
(update-in state [:workspace-data :pages-index page-id :objects id] assoc :overflow-text value)))))
|
||||
|
||||
|
||||
(def start-edit-if-selected
|
||||
(ptk/reify ::start-edit-if-selected
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (get-in state [:workspace-data :pages-index page-id :objects])
|
||||
selected (->> state :workspace-local :selected (map #(get objects %)))]
|
||||
(cond-> state
|
||||
(and (= 1 (count selected))
|
||||
(= (-> selected first :type) :text))
|
||||
(assoc-in [:workspace-local :edition] (-> selected first :id)))))))
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
[app.common.pages-helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.snap :as snap]
|
||||
|
@ -139,8 +140,12 @@
|
|||
layout (:workspace-layout state)
|
||||
page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
resizing-shapes (map #(get objects %) ids)]
|
||||
resizing-shapes (map #(get objects %) ids)
|
||||
text-shapes-ids (->> resizing-shapes
|
||||
(filter #(= :text (:type %)))
|
||||
(map :id))]
|
||||
(rx/concat
|
||||
(rx/of (dwc/update-shapes text-shapes-ids #(assoc % :grow-type :fixed)))
|
||||
(->> ms/mouse-position
|
||||
(rx/with-latest vector ms/mouse-position-shift)
|
||||
(rx/map normalize-proportion-lock)
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
:on-mouse-down on-rotate}]))
|
||||
|
||||
(mf/defc resize-point-handler
|
||||
[{:keys [cx cy zoom position on-resize transform rotation color]}]
|
||||
[{:keys [cx cy zoom position on-resize transform rotation color overflow-text]}]
|
||||
(let [{cx' :x cy' :y} (gpt/transform (gpt/point cx cy) transform)
|
||||
rot-square (case position
|
||||
:top-left 0
|
||||
|
@ -140,7 +140,7 @@
|
|||
:vectorEffect "non-scaling-stroke"
|
||||
}
|
||||
:fill "#FFFFFF"
|
||||
:stroke color
|
||||
:stroke (if (and (= position :bottom-right) overflow-text) "red" color)
|
||||
:cx cx'
|
||||
:cy cy'}]
|
||||
|
||||
|
@ -172,7 +172,7 @@
|
|||
(mf/defc controls
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [shape (obj/get props "shape")
|
||||
(let [{:keys [overflow-text] :as shape} (obj/get props "shape")
|
||||
zoom (obj/get props "zoom")
|
||||
color (obj/get props "color")
|
||||
on-resize (obj/get props "on-resize")
|
||||
|
@ -202,7 +202,8 @@
|
|||
:on-resize (partial on-resize position)
|
||||
:transform transform
|
||||
:rotation (:rotation shape)
|
||||
:color color}
|
||||
:color color
|
||||
:overflow-text overflow-text}
|
||||
props (map->obj (merge common-props props))]
|
||||
(case type
|
||||
:rotation (when (not= :frame (:type shape)) [:> rotation-handler props])
|
||||
|
|
|
@ -61,8 +61,6 @@
|
|||
selected? (and (contains? selected id)
|
||||
(= (count selected) 1))
|
||||
|
||||
calculate-size (mf/use-state false)
|
||||
|
||||
on-mouse-down #(handle-mouse-down % shape)
|
||||
on-context-menu #(common/on-context-menu % shape)
|
||||
|
||||
|
@ -73,18 +71,13 @@
|
|||
(when selected?
|
||||
(st/emit! (dw/start-edition-mode (:id shape)))))]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps grow-type content width height)
|
||||
(fn []
|
||||
(reset! calculate-size true)
|
||||
(timers/schedule 200 (fn [] (reset! calculate-size false)))))
|
||||
|
||||
[:g.shape {:on-double-click on-double-click
|
||||
:on-mouse-down on-mouse-down
|
||||
:on-context-menu on-context-menu}
|
||||
[:*
|
||||
(when (and (not edition?) @calculate-size)
|
||||
[:g {:opacity 0}
|
||||
(when (not edition?)
|
||||
[:g {:opacity 0
|
||||
:style {:pointer-events "none"}}
|
||||
;; We only render the component for its side-effect
|
||||
[:& text-shape-edit {:shape shape
|
||||
:read-only? true}]])
|
||||
|
@ -125,7 +118,7 @@
|
|||
lh (obj/set! "lineHeight" lh))))
|
||||
|
||||
(defn- generate-text-styles
|
||||
[data]
|
||||
[data on-load-font]
|
||||
(let [letter-spacing (obj/get data "letter-spacing")
|
||||
text-decoration (obj/get data "text-decoration")
|
||||
text-transform (obj/get data "text-transform")
|
||||
|
@ -157,7 +150,7 @@
|
|||
(when (and (string? font-id)
|
||||
(pos? (alength font-id)))
|
||||
(let [font (get fontsdb font-id)]
|
||||
(fonts/ensure-loaded! font-id)
|
||||
(fonts/ensure-loaded! font-id on-load-font)
|
||||
(let [font-family (or (:family font)
|
||||
(obj/get data "fontFamily"))
|
||||
font-variant (d/seek #(= font-variant-id (:id %))
|
||||
|
@ -219,7 +212,8 @@
|
|||
(let [attrs (obj/get props "attributes")
|
||||
childs (obj/get props "children")
|
||||
data (obj/get props "leaf")
|
||||
style (generate-text-styles data)
|
||||
on-load-font (obj/get props "on-load-font")
|
||||
style (generate-text-styles data on-load-font)
|
||||
attrs (obj/set! attrs "style" style)]
|
||||
[:> :span attrs childs]))
|
||||
|
||||
|
@ -235,9 +229,10 @@
|
|||
nil))))
|
||||
|
||||
(defn- render-text
|
||||
[props]
|
||||
(mf/html
|
||||
[:> editor-text-node props]))
|
||||
[on-load-font]
|
||||
(fn [props]
|
||||
(mf/html
|
||||
[:> editor-text-node (obj/merge! props #js {:on-load-font on-load-font})])))
|
||||
|
||||
;; --- Text Shape Edit
|
||||
|
||||
|
@ -271,7 +266,7 @@
|
|||
(when (not read-only?)
|
||||
(st/emit! dw/clear-edition-mode)))
|
||||
|
||||
on-click
|
||||
on-click-outside
|
||||
(fn [event]
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
|
@ -304,7 +299,7 @@
|
|||
on-mount
|
||||
(fn []
|
||||
(when (not read-only?)
|
||||
(let [lkey1 (events/listen js/document EventType.CLICK on-click)
|
||||
(let [lkey1 (events/listen js/document EventType.CLICK on-click-outside)
|
||||
lkey2 (events/listen js/document EventType.KEYUP on-key-up)]
|
||||
(st/emit! (dwt/assign-editor id editor)
|
||||
dwc/start-undo-transaction)
|
||||
|
@ -327,22 +322,42 @@
|
|||
(let [content (js->clj val :keywordize-keys true)
|
||||
content (first content)]
|
||||
(st/emit! (dw/update-shape id {:content content}))
|
||||
(reset! state val)))))]
|
||||
(reset! state val)))))
|
||||
|
||||
loaded-fonts (mf/use-var 0)
|
||||
on-load-font #(swap! loaded-fonts inc)]
|
||||
|
||||
(mf/use-effect on-mount)
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps @state)
|
||||
(mf/deps content)
|
||||
(fn []
|
||||
(reset! state (parse-content content))))
|
||||
|
||||
;; Checks the size of the wrapper to update if it were necesary
|
||||
(mf/use-effect
|
||||
(mf/deps props @loaded-fonts)
|
||||
(fn []
|
||||
(timers/schedule
|
||||
#(if (#{:auto-width :auto-height} grow-type)
|
||||
(let [self-node (mf/ref-val self-ref)
|
||||
paragraph-node (dom/query self-node ".paragraph-set")]
|
||||
(when paragraph-node
|
||||
(let [{:keys [width height]} (dom/get-bounding-rect paragraph-node)]
|
||||
(st/emit! (dw/update-shape id (if (= grow-type :auto-width)
|
||||
{:width width :height height}
|
||||
{:height height}))))))))))
|
||||
250 ;; We need to wait to the text to be rendered. Is there a better alternative?
|
||||
#(let [self-node (mf/ref-val self-ref)
|
||||
paragraph-node (when self-node (dom/query self-node ".paragraph-set"))]
|
||||
(when paragraph-node
|
||||
(let [{:keys [width height]} (dom/get-bounding-rect paragraph-node)]
|
||||
(cond
|
||||
(and (:overflow-text shape) (not= :fixed (:grow-type shape)))
|
||||
(st/emit! (dwt/update-overflow-text id false))
|
||||
|
||||
(and (= :fixed (:grow-type shape)) (not (:overflow-text shape)) (> height (:height shape)))
|
||||
(st/emit! (dwt/update-overflow-text id true))
|
||||
|
||||
(and (= :fixed (:grow-type shape)) (:overflow-text shape) (<= height (:height shape)))
|
||||
(st/emit! (dwt/update-overflow-text id false)))
|
||||
|
||||
(if (#{:auto-width :auto-height} grow-type)
|
||||
(st/emit! (dw/update-shape id (if (= grow-type :auto-width)
|
||||
{:width width :height height}
|
||||
{:height height}))))))))))
|
||||
|
||||
[:foreignObject {:ref self-ref
|
||||
:transform (geom/transform-matrix shape)
|
||||
|
@ -358,9 +373,10 @@
|
|||
:spell-check "false"
|
||||
:on-focus on-focus
|
||||
:class "rich-text"
|
||||
:style {:cursor cur/text}
|
||||
:style {:cursor cur/text
|
||||
:width (:width shape)}
|
||||
:render-element #(render-element shape %)
|
||||
:render-leaf render-text
|
||||
:render-leaf (render-text on-load-font)
|
||||
:on-mouse-up on-mouse-up
|
||||
:on-mouse-down on-mouse-down
|
||||
:on-blur (fn [event]
|
||||
|
|
|
@ -308,7 +308,7 @@
|
|||
(st/emit! (ms/->MouseEvent :down ctrl? shift? alt?))
|
||||
|
||||
(cond
|
||||
(and (not edition) (= 1 (.-which event)))
|
||||
(and (= 1 (.-which event)))
|
||||
(if drawing-tool
|
||||
(st/emit! (dd/start-drawing drawing-tool))
|
||||
(st/emit! dw/handle-selection))
|
||||
|
|
Loading…
Add table
Reference in a new issue