diff --git a/frontend/src/app/main/ui/shapes/attrs.cljs b/frontend/src/app/main/ui/shapes/attrs.cljs index 1da44c40f..51e84ab26 100644 --- a/frontend/src/app/main/ui/shapes/attrs.cljs +++ b/frontend/src/app/main/ui/shapes/attrs.cljs @@ -189,9 +189,8 @@ (let [svg-defs (:svg-defs shape {}) svg-attrs (:svg-attrs shape {}) - [svg-attrs svg-styles] (mf/use-memo - (mf/deps render-id svg-defs svg-attrs) - #(extract-svg-attrs render-id svg-defs svg-attrs)) + [svg-attrs svg-styles] + (extract-svg-attrs render-id svg-defs svg-attrs) styles (-> (obj/get props "style" (obj/new)) (obj/merge! svg-styles) diff --git a/frontend/src/app/main/ui/shapes/gradients.cljs b/frontend/src/app/main/ui/shapes/gradients.cljs index bd9bca876..8396ae47b 100644 --- a/frontend/src/app/main/ui/shapes/gradients.cljs +++ b/frontend/src/app/main/ui/shapes/gradients.cljs @@ -97,10 +97,10 @@ (mf/defc gradient {::mf/wrap-props false} [props] - (let [attr (obj/get props "attr") - shape (obj/get props "shape") - render-id (mf/use-ctx muc/render-ctx) - id (str (name attr) "_" render-id) + (let [attr (obj/get props "attr") + shape (obj/get props "shape") + id (obj/get props "id") + id (or id (str (name attr) "_" (mf/use-ctx muc/render-ctx))) gradient (get shape attr) gradient-props #js {:id id :gradient gradient 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 7c88c8b69..ae9929b7d 100644 --- a/frontend/src/app/main/ui/shapes/text/fo_text.cljs +++ b/frontend/src/app/main/ui/shapes/text/fo_text.cljs @@ -9,6 +9,7 @@ [app.common.colors :as clr] [app.common.data :as d] [app.common.geom.shapes :as geom] + [app.common.transit :as transit] [app.main.ui.context :as muc] [app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.text.styles :as sts] @@ -23,7 +24,12 @@ (let [node (obj/get props "node") text (:text node) style (sts/generate-text-styles node)] - [:span.text-node {:style style} + [:span.text-node {:style style + :data-fill-color (:fill-color node) + :data-fill-color-gradient (transit/encode-str (:fill-color-gradient node)) + :data-fill-color-ref-file (transit/encode-str (:fill-color-ref-file node)) + :data-fill-color-ref-id (transit/encode-str (:fill-color-ref-id node)) + :data-fill-opacity (:fill-opacity node)} (if (= text "") "\u00A0" text)])) (mf/defc render-root 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 9863c99ff..3f6ff5313 100644 --- a/frontend/src/app/main/ui/shapes/text/svg_text.cljs +++ b/frontend/src/app/main/ui/shapes/text/svg_text.cljs @@ -6,40 +6,52 @@ (ns app.main.ui.shapes.text.svg-text (:require - [app.common.geom.matrix :as gmt] + [app.common.data :as d] [app.common.geom.shapes :as gsh] - [app.main.store :as st] + [app.main.ui.context :as muc] + [app.main.ui.shapes.attrs :as attrs] + [app.main.ui.shapes.custom-stroke :refer [shape-custom-stroke]] + [app.main.ui.shapes.gradients :as grad] [app.util.object :as obj] [rumext.alpha :as mf])) +(def fill-attrs [:fill-color :fill-color-gradient :fill-opacity]) + (mf/defc text-shape {::mf/wrap-props false ::mf/wrap [mf/memo]} [props] - (let [{:keys [x y width height position-data] :as shape} (obj/get props "shape") - zoom (or (get-in @st/state [:workspace-local :zoom]) 1)] - [:text {:x x - :y y - :width width - :height height - :dominant-baseline "ideographic" - :transform (gsh/transform-matrix shape) - } - (for [data position-data] - [:tspan {:x (:x data) - :y (:y data) - :transform (:transform-inverse shape (gmt/matrix)) - :style {:fill "black" - :fill-opacity 1 - :stroke "red" - :stroke-width (/ 0.5 zoom) - :font-family (:font-family data) - :font-size (:font-size data) - :font-weight (:font-weight data) - :text-transform (:text-transform data) - :text-decoration (:text-decoration data) - :font-style (:font-style data) - :direction (if (:rtl? data) "rtl" "ltr") - :white-space "pre"}} - (:text data)])])) + (let [render-id (mf/use-ctx muc/render-ctx) + {:keys [position-data] :as shape} (obj/get props "shape") + group-props (-> #js {:transform (gsh/transform-matrix shape)} + (attrs/add-style-attrs shape render-id)) + get-gradient-id + (fn [index] + (str render-id "_" (:id shape) "_" index))] + [:* + ;; Definition of gradients for partial elements + (when (d/seek :fill-color-gradient position-data) + [:defs + (for [[index data] (d/enumerate position-data)] + (when (some? (:fill-color-gradient data)) + [:& grad/gradient {:id (str "fill-color-gradient_" (get-gradient-id index)) + :attr :fill-color-gradient + :shape data}]))]) + + [:& shape-custom-stroke {:shape shape} + [:> :g group-props + (for [[index data] (d/enumerate position-data)] + (let [props (-> #js {:x (:x data) + :y (:y data) + :dominant-baseline "ideographic" + :style (-> #js {:fontFamily (:font-family data) + :fontSize (:font-size data) + :fontWeight (:font-weight data) + :textTransform (:text-transform data) + :textDecoration (:text-decoration data) + :fontStyle (:font-style data) + :direction (if (:rtl? data) "rtl" "ltr") + :whiteSpace "pre"} + (attrs/add-fill data (get-gradient-id index)))})] + [:> :text props (:text data)]))]]])) diff --git a/frontend/src/app/main/ui/workspace/shapes/text.cljs b/frontend/src/app/main/ui/workspace/shapes/text.cljs index e9563a175..741073d0d 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text.cljs @@ -6,8 +6,10 @@ (ns app.main.ui.workspace.shapes.text (:require + [app.common.data :as d] [app.common.logging :as log] [app.common.math :as mth] + [app.common.transit :as transit] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.texts :as dwt] [app.main.refs :as refs] @@ -126,18 +128,22 @@ (let [{:keys [x y width height]} position rtl? (= "rtl" (.-dir (.-parentElement ^js node))) styles (.computedStyleMap ^js node)] - {:rtl? rtl? - :x (if rtl? (+ x width) x) - :y (+ y height) - :width width - :height height - :font-family (str (.get styles "font-family")) - :font-size (str (.get styles "font-size")) - :font-weight (str (.get styles "font-weight")) - :text-transform (str (.get styles "text-transform")) - :text-decoration (str (.get styles "text-decoration")) - :font-style (str (.get styles "font-style")) - :text text}))))] + (d/without-nils + {:rtl? rtl? + :x (if rtl? (+ x width) x) + :y (+ y height) + :width width + :height height + :font-family (str (.get styles "font-family")) + :font-size (str (.get styles "font-size")) + :font-weight (str (.get styles "font-weight")) + :text-transform (str (.get styles "text-transform")) + :text-decoration (str (.get styles "text-decoration")) + :font-style (str (.get styles "font-style")) + :fill-color (or (dom/get-attribute node "data-fill-color") "#000000") + :fill-color-gradient (transit/decode-str (dom/get-attribute node "data-fill-color-gradient")) + :fill-opacity (d/parse-double (or (:fill-opacity node) "1")) + :text text})))))] (st/emit! (dch/update-shapes [id] (fn [shape] @@ -162,7 +168,7 @@ :edition? edition? :key (str id edition?)}]] - [:g {:opacity (when edition? 0) - :pointer-events "none"} + [:g.text-svg {:opacity (when edition? 0) + :pointer-events "none"} (when (some? (:position-data shape)) [:& svg/text-shape {:shape shape}])]]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs index 804703cd6..fa1990b2a 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs @@ -16,6 +16,7 @@ [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu text-fill-attrs root-attrs paragraph-attrs text-attrs]] [rumext.alpha :as mf])) @@ -43,6 +44,8 @@ (:fill fill-values) (assoc :fill-color (:fill fill-values)) (:opacity fill-values) (assoc :fill-opacity (:fill fill-values))) + stroke-values (select-keys shape stroke-attrs) + text-values (d/merge (select-keys shape [:grow-type]) (select-keys shape fill-attrs) @@ -79,6 +82,10 @@ :values fill-values :disable-remove? true}] + [:& stroke-menu {:ids ids + :type type + :values stroke-values}] + [:& shadow-menu {:ids ids :values (select-keys shape [:shadow])}] diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index ffbdc7d39..fd6fc1afd 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -206,7 +206,8 @@ :style {:background-color background :pointer-events "none"}} - [:& use/export-page {:options options}] + (when (debug? :show-export-metadata) + [:& use/export-page {:options options}]) [:& (mf/provider use/include-metadata-ctx) {:value (debug? :show-export-metadata)} [:& (mf/provider embed/context) {:value true}