0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-13 16:21:57 -05:00

Fixes exports and preview

This commit is contained in:
alonso.torres 2020-10-15 15:44:00 +02:00
parent e961492192
commit 929d620c60
15 changed files with 255 additions and 199 deletions

View file

@ -26,7 +26,9 @@
[app.main.ui.shapes.path :as path]
[app.main.ui.shapes.rect :as rect]
[app.main.ui.shapes.text :as text]
[app.main.ui.shapes.group :as group]))
[app.main.ui.shapes.group :as group]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.context :as muc]))
(def ^:private default-color "#E8E9EA") ;; $color-canvas
@ -55,8 +57,14 @@
(mf/fnc frame-wrapper
[{:keys [shape] :as props}]
(let [childs (mapv #(get objects %) (:shapes shape))
shape (geom/transform-shape shape)]
[:& frame-shape {:shape shape :childs childs}]))))
shape (geom/transform-shape shape)
render-id (mf/use-memo #(str (uuid/next)))]
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.frame
[:defs
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
[:& frame-shape {:shape shape :childs childs}]]]))))
(defn group-wrapper-factory
[objects]
@ -79,20 +87,24 @@
(when (and shape (not (:hidden shape)))
(let [shape (geom/transform-shape frame shape)
opts #js {:shape shape}
filter-id (filters/get-filter-id)]
[:g {:filter (filters/filter-str filter-id shape)}
[:& filters/filters {:filter-id filter-id :shape shape}]
(case (:type shape)
:curve [:> path/path-shape opts]
:text [:> text/text-shape opts]
:icon [:> icon/icon-shape opts]
:rect [:> rect/rect-shape opts]
:path [:> path/path-shape opts]
:image [:> image/image-shape opts]
:circle [:> circle/circle-shape opts]
:frame [:> frame-wrapper {:shape shape}]
:group [:> group-wrapper {:shape shape :frame frame}]
nil)])))))
render-id (mf/use-memo #(str (uuid/next)))]
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g {:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
(case (:type shape)
:curve [:> path/path-shape opts]
:text [:> text/text-shape opts]
:icon [:> icon/icon-shape opts]
:rect [:> rect/rect-shape opts]
:path [:> path/path-shape opts]
:image [:> image/image-shape opts]
:circle [:> circle/circle-shape opts]
:frame [:> frame-wrapper {:shape shape}]
:group [:> group-wrapper {:shape shape :frame frame}]
nil)]])))))
(mf/defc page-svg
{::mf/wrap [mf/memo]}

View file

@ -12,3 +12,5 @@
[rumext.alpha :as mf]))
(def embed-ctx (mf/create-context false))
(def render-ctx (mf/create-context nil))

View file

@ -9,8 +9,10 @@
(ns app.main.ui.shapes.attrs
(:require
[rumext.alpha :as mf]
[cuerdas.core :as str]
[app.util.object :as obj]))
[app.util.object :as obj]
[app.main.ui.context :as muc]))
(defn- stroke-type->dasharray
[style]
@ -24,16 +26,16 @@
(obj/merge! attrs #js {:rx (:rx shape)
:ry (:ry shape)}))
(defn add-fill [attrs shape]
(let [fill-color-gradient-id (str "fill-color-gradient_" (:render-id shape))]
(defn add-fill [attrs shape render-id]
(let [fill-color-gradient-id (str "fill-color-gradient_" render-id)]
(if (:fill-color-gradient shape)
(obj/merge! attrs #js {:fill (str/format "url(#%s)" fill-color-gradient-id)})
(obj/merge! attrs #js {:fill (or (:fill-color shape) "transparent")
:fillOpacity (:fill-opacity shape nil)}))))
(defn add-stroke [attrs shape]
(defn add-stroke [attrs shape render-id]
(let [stroke-style (:stroke-style shape :none)
stroke-color-gradient-id (str "stroke-color-gradient_" (:render-id shape))]
stroke-color-gradient-id (str "stroke-color-gradient_" render-id)]
(if (not= stroke-style :none)
(if (:stroke-color-gradient shape)
(obj/merge! attrs
@ -49,7 +51,8 @@
(defn extract-style-attrs
([shape]
(-> (obj/new)
(add-border-radius shape)
(add-fill shape)
(add-stroke shape))))
(let [render-id (mf/use-ctx muc/render-ctx)]
(-> (obj/new)
(add-border-radius shape)
(add-fill shape render-id)
(add-stroke shape render-id)))))

View file

@ -123,45 +123,42 @@
[filter-x filter-y filter-width filter-height] (get-filters-bounds shape filters)]
(when (seq filters)
[:defs
[:filter {:id filter-id
:x filter-x :y filter-y
:width filter-width :height filter-height
:filterUnits "userSpaceOnUse"
:color-interpolation-filters "sRGB"}
[:filter {:id filter-id
:x filter-x :y filter-y
:width filter-width :height filter-height
:filterUnits "userSpaceOnUse"
:color-interpolation-filters "sRGB"}
(let [;; Add as a paramter the input filter
drop-shadow-filters (->> filters (filter #(= :drop-shadow (:style %))))
drop-shadow-filters (->> drop-shadow-filters
(map #(str "filter" (:id %)))
(cons "BackgroundImageFix")
(map add-in-filter drop-shadow-filters))
(let [;; Add as a paramter the input filter
drop-shadow-filters (->> filters (filter #(= :drop-shadow (:style %))))
drop-shadow-filters (->> drop-shadow-filters
(map #(str "filter" (:id %)))
(cons "BackgroundImageFix")
(map add-in-filter drop-shadow-filters))
inner-shadow-filters (->> filters (filter #(= :inner-shadow (:style %))))
inner-shadow-filters (->> inner-shadow-filters
inner-shadow-filters (->> filters (filter #(= :inner-shadow (:style %))))
inner-shadow-filters (->> inner-shadow-filters
(map #(str "filter" (:id %)))
(cons "shape")
(map add-in-filter inner-shadow-filters))]
[:*
[:feFlood {:flood-opacity 0 :result "BackgroundImageFix"}]
(for [{:keys [id type] :as filter} drop-shadow-filters]
[:& drop-shadow-filter {:key id
[:*
[:feFlood {:flood-opacity 0 :result "BackgroundImageFix"}]
(for [{:keys [id type] :as filter} drop-shadow-filters]
[:& drop-shadow-filter {:key id
:filter-id filter-id
:filter filter
:shape shape}])
[:feBlend {:mode "normal"
:in "SourceGraphic"
:in2 (if (seq drop-shadow-filters)
(str "filter" (:id (last drop-shadow-filters)))
"BackgroundImageFix")
:result "shape"}]
(for [{:keys [id type] :as filter} inner-shadow-filters]
[:& inner-shadow-filter {:key id
:filter-id filter-id
:filter filter
:shape shape}])
[:feBlend {:mode "normal"
:in "SourceGraphic"
:in2 (if (seq drop-shadow-filters)
(str "filter" (:id (last drop-shadow-filters)))
"BackgroundImageFix")
:result "shape"}]
(for [{:keys [id type] :as filter} inner-shadow-filters]
[:& inner-shadow-filter {:key id
:filter-id filter-id
:filter filter
:shape shape}])
])
]])))
:shape shape}])])])))

View file

@ -13,6 +13,7 @@
[cuerdas.core :as str]
[app.util.object :as obj]
[app.common.uuid :as uuid]
[app.main.ui.context :as muc]
[app.common.geom.point :as gpt]))
(mf/defc linear-gradient [{:keys [id gradient shape]}]
@ -32,7 +33,8 @@
(mf/defc radial-gradient [{:keys [id gradient shape]}]
(let [{:keys [x y width height]} shape]
[:defs
(let [translate-vec (gpt/point (+ x (* width (:start-x gradient)))
(let [[x y] (if (= (:type shape) :frame) [0 0] [x y])
translate-vec (gpt/point (+ x (* width (:start-x gradient)))
(+ y (* height (:start-y gradient))))
gradient-vec (gpt/to-vec (gpt/point (* width (:start-x gradient))
@ -72,13 +74,13 @@
[props]
(let [attr (obj/get props "attr")
shape (obj/get props "shape")
render-id (obj/get props "render-id")
render-id (mf/use-ctx muc/render-ctx)
id (str (name attr) "_" render-id)
gradient (get shape attr)
gradient-props #js {:id id
:gradient gradient
:shape shape}]
(case (:type gradient)
:linear [:> linear-gradient gradient-props]
:radial [:> radial-gradient gradient-props])))
(when gradient
(case (:type gradient)
:linear [:> linear-gradient gradient-props]
:radial [:> radial-gradient gradient-props]))))

View file

@ -68,9 +68,10 @@
fill-color (obj/get data "fill-color" fill)
fill-opacity (obj/get data "fill-opacity" opacity)
fill-color-gradient (obj/get data "fill-color-gradient" opacity)
fill-color-gradient (-> (js->clj fill-color-gradient :keywordize-keys true)
(update :type keyword))
fill-color-gradient (obj/get data "fill-color-gradient" nil)
fill-color-gradient (when fill-color-gradient
(-> (js->clj fill-color-gradient :keywordize-keys true)
(update :type keyword)))
fill-color-ref-id (obj/get data "fill-color-ref-id")
fill-color-ref-file (obj/get data "fill-color-ref-file")
@ -83,14 +84,9 @@
fontsdb (deref fonts/fontsdb)
base #js {:textDecoration text-decoration
;:color (str/format "rgba(%s, %s, %s, %s)" r g b a)
:textTransform text-transform
:lineHeight (or line-height "inherit")
:background background
:WebkitTextFillColor "transparent"
:WebkitBackgroundClip "text"
}]
"--text-color" background}]
(when (and (string? letter-spacing)
(pos? (alength letter-spacing)))
@ -179,8 +175,7 @@
(if (string? text)
(let [style (generate-text-styles (clj->js node))]
[:span {:style style
:key (str index "-" (:fill-color node))} (if (= text "") "\u00A0" text)])
[:span.text-node {:style style} (if (= text "") "\u00A0" text)])
(let [children (map-indexed (fn [index node]
(mf/element text-node {:index index :node node :key index}))
children)]
@ -192,13 +187,15 @@
{:key index
:style style
:xmlns "http://www.w3.org/1999/xhtml"}
(when (not (nil? @embeded-fonts))
[:style @embeded-fonts])
[:*
[:style ".text-node { background: var(--text-color); -webkit-text-fill-color: transparent; -webkit-background-clip: text;"]
(when (not (nil? @embeded-fonts))
[:style @embeded-fonts])]
children])
"paragraph-set"
(let [style #js {:display "inline-block"}]
[:div.paragraphs {:key index :style style} children])
[:div.paragraphs {:key index :style style} children])
"paragraph"
(let [style (generate-paragraph-styles (clj->js node))]

View file

@ -29,7 +29,10 @@
[app.util.object :as obj]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]))
[app.common.geom.shapes :as geom]
[app.common.uuid :as uuid]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.context :as muc]))
(defn on-mouse-down
[event {:keys [interactions] :as shape}]
@ -56,25 +59,29 @@
(mf/deps shape)
#(on-mouse-down % shape))
filter-id (filters/get-filter-id)]
render-id (mf/use-memo #(str (uuid/next)))]
[:g.shape {:on-mouse-down on-mouse-down
:cursor (when (:interactions shape) "pointer")
:filter (filters/filter-str filter-id shape)}
[:& filters/filters {:filter-id filter-id :shape shape}]
[:& component {:shape shape
:frame frame
:childs childs
:is-child-selected? true}]
(when (and (:interactions shape) show-interactions?)
[:rect {:x (- x 1)
:y (- y 1)
:width (+ width 2)
:height (+ height 2)
:fill "#31EFB8"
:stroke "#31EFB8"
:stroke-width 1
:fill-opacity 0.2}])])))
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.shape {:on-mouse-down on-mouse-down
:cursor (when (:interactions shape) "pointer")
:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
[:& component {:shape shape
:frame frame
:childs childs
:is-child-selected? true}]
(when (and (:interactions shape) show-interactions?)
[:rect {:x (- x 1)
:y (- y 1)
:width (+ width 2)
:height (+ height 2)
:fill "#31EFB8"
:stroke "#31EFB8"
:stroke-width 1
:fill-opacity 0.2}])]])))
(defn frame-wrapper
[shape-container show-interactions?]

View file

@ -369,15 +369,7 @@
(reset! dirty? (not= data new-data))
(reset! last-change new-data)
(when on-change
(on-change new-data)))
;; handle-change (fn [new-value new-opacity id file-id shift-clicked?]
;; (when (or (not= new-value value) (not= new-opacity opacity))
;; (reset! dirty? true))
;; (reset! last-change [new-value new-opacity id file-id])
;; (when on-change
;; (on-change new-value new-opacity id file-id shift-clicked?)))
]
(on-change new-data)))]
(mf/use-effect
(fn []

View file

@ -13,6 +13,7 @@
[cuerdas.core :as str]
[okulary.core :as l]
[promesa.core :as p]
[beicon.core :as rx]
[goog.events :as events]
[app.common.uuid :as uuid]
[app.util.timers :as timers]
@ -53,6 +54,19 @@
[:& shape-wrapper {:shape item
:key (:id item)}]))]]))
(defn draw-picker-canvas [svg-node canvas-node]
(let [canvas-context (.getContext canvas-node "2d")
xml (.serializeToString (js/XMLSerializer.) svg-node)
img-src (str "data:image/svg+xml;base64,"
(-> xml js/encodeURIComponent js/unescape js/btoa))
img (js/Image.)
on-error (fn [err] (.error js/console "ERROR" err))
on-load (fn [] (.drawImage canvas-context img 0 0))]
(.addEventListener img "error" on-error)
(.addEventListener img "load" on-load)
(obj/set! img "src" img-src)))
(mf/defc pixel-overlay
{::mf/wrap-props false}
[props]
@ -64,6 +78,8 @@
canvas-ref (mf/use-ref nil)
fetch-pending (mf/deref (mdf/pending-ref))
update-canvas-stream (rx/subject)
handle-keydown
(fn [event]
(when (and (kbd/esc? event))
@ -117,26 +133,30 @@
#(events/unlistenByKey listener))))
(mf/use-effect
;; Everytime we finish retrieving a new URL we redraw the canvas
;; so even if we're not finished the user can start to pick basic
;; shapes
(mf/deps fetch-pending)
(fn []
(try
(let [canvas-node (mf/ref-val canvas-ref)
canvas-context (.getContext canvas-node "2d")
svg-node (mf/ref-val svg-ref)]
(timers/schedule 100
#(let [xml (.serializeToString (js/XMLSerializer.) svg-node)
img-src (str "data:image/svg+xml;base64,"
(-> xml js/encodeURIComponent js/unescape js/btoa))
img (js/Image.)
on-error (fn [err] (.error js/console "ERROR" err))
on-load (fn [] (.drawImage canvas-context img 0 0))]
(.addEventListener img "error" on-error)
(.addEventListener img "load" on-load)
(obj/set! img "src" img-src))))
(catch :default e (.error js/console e)))))
(let [sub (->> update-canvas-stream
(rx/debounce 10)
(rx/subs #(draw-picker-canvas (mf/ref-val svg-ref)
(mf/ref-val canvas-ref))))]
#(rx/dispose! sub))))
(mf/use-effect
(mf/deps svg-ref canvas-ref)
(fn []
(when (and svg-ref canvas-ref)
(let [config (clj->js {:attributes true
:childList true
:subtree true
:characterData true})
on-svg-change (fn [mutation-list] (rx/push! update-canvas-stream :update))
observer (js/MutationObserver. on-svg-change)]
(.observe observer (mf/ref-val svg-ref) config)
;; Disconnect on unmount
#(.disconnect observer)))))
[:*
[:div.overlay
@ -154,6 +174,7 @@
:width (:width vport 0)
:height (:height vport 0)
:style {:display "none"}}]
[:& (mf/provider muc/embed-ctx) {:value true}
[:svg.viewport
{:ref svg-ref

View file

@ -284,7 +284,9 @@
(change! {:width norm-dist})))]
(when (and gradient (= id (:shape-id gradient)))
(when (and gradient
(= id (:shape-id gradient))
(not= (:type shape) :text))
[:& gradient-handler-transformed
{:editing editing-spot
:from-p from-p

View file

@ -20,7 +20,8 @@
[app.common.uuid :as uuid]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]))
[app.common.geom.shapes :as geom]
[app.main.ui.context :as muc]))
(defn- on-mouse-down
[event {:keys [id type] :as shape}]
@ -75,22 +76,15 @@
#(on-context-menu % shape))
render-id (mf/use-memo #(str (uuid/next)))]
[:g.shape {:on-mouse-down on-mouse-down
:on-context-menu on-context-menu
:filter (filters/filter-str (str "filter_" render-id) shape)}
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.shape {:on-mouse-down on-mouse-down
:on-context-menu on-context-menu
:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
[:& filters/filters {:filter-id (str "filter_" render-id) :shape shape}]
(when (:fill-color-gradient shape)
[:& grad/gradient {:attr :fill-color-gradient
:render-id render-id
:shape shape}])
(when (:stroke-color-gradient shape)
[:& grad/gradient {:attr :stroke-color-gradient
:render-id render-id
:shape shape}])
[:& component {:shape (assoc shape :render-id render-id)}]])))
[:& component {:shape shape}]]])))

View file

@ -26,7 +26,9 @@
[app.common.geom.shapes :as geom]
[app.util.dom :as dom]
[app.main.streams :as ms]
[app.util.timers :as ts]))
[app.util.timers :as ts]
[app.main.ui.context :as muc]
[app.common.uuid :as uuid]))
(defn- frame-wrapper-factory-equals?
[np op]
@ -115,7 +117,7 @@
(fn []
(st/emit! (dws/change-hover-state (:id shape) false))))
filter-id (mf/use-memo filters/get-filter-id)]
render-id (mf/use-memo #(str (uuid/next)))]
(when-not (:hidden shape)
[:g {:class (when selected? "selected")
@ -128,18 +130,14 @@
:on-double-click on-double-click
:on-mouse-down on-mouse-down}]
[:g.frame {:filter (filters/filter-str filter-id shape)}
[:& filters/filters {:filter-id filter-id :shape shape}]
(when (:fill-color-gradient shape)
[:& grad/gradient {:attr :fill-color-gradient
:shape shape}])
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.frame {:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
(when (:stroke-color-gradient shape)
[:& grad/gradient {:attr :stroke-color-gradient
:shape shape}])
[:& frame-shape
{:shape shape
:childs children}]]])))))
[:& frame-shape
{:shape shape
:childs children}]]]])))))

View file

@ -23,7 +23,10 @@
[app.main.data.workspace.drawing :as dr]
[app.util.dom :as dom]
[app.main.streams :as ms]
[app.util.timers :as ts]))
[app.util.timers :as ts]
[app.common.uuid :as uuid]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.context :as muc]))
(mf/defc path-wrapper
{::mf/wrap-props false}
@ -45,21 +48,18 @@
(dom/prevent-default event)
(st/emit! (dw/start-edition-mode (:id shape)))))))
filter-id (mf/use-memo filters/get-filter-id)]
render-id (mf/use-memo #(str (uuid/next)))]
[:g.shape {:on-double-click on-double-click
:on-mouse-down on-mouse-down
:on-context-menu on-context-menu
:filter (filters/filter-str filter-id shape)}
[:& filters/filters {:filter-id filter-id :shape shape}]
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.shape {:on-double-click on-double-click
:on-mouse-down on-mouse-down
:on-context-menu on-context-menu
:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
(when (:fill-color-gradient shape)
[:& grad/gradient {:attr :fill-color-gradient
:shape shape}])
(when (:stroke-color-gradient shape)
[:& grad/gradient {:attr :stroke-color-gradient
:shape shape}])
[:& path/path-shape {:shape shape
:background? true}]]))
[:& path/path-shape {:shape shape
:background? true}]]]))

View file

@ -34,7 +34,10 @@
[app.util.color :as uc]
[app.util.timers :as timers]
["slate" :as slate]
["slate-react" :as rslate])
["slate-react" :as rslate]
[app.common.uuid :as uuid]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.context :as muc])
(:import
goog.events.EventType
goog.events.KeyCodes))
@ -80,7 +83,7 @@
(when selected?
(st/emit! (dw/start-edition-mode (:id shape)))))
filter-id (mf/use-memo filters/get-filter-id)]
render-id (mf/use-memo #(str (uuid/next)))]
(mf/use-effect
(mf/deps shape edition selected? current-transform)
@ -91,23 +94,27 @@
(nil? current-transform))]
(timers/schedule #(reset! render-editor check?)))))
[:g.shape {:on-double-click on-double-click
:on-mouse-down on-mouse-down
:on-context-menu on-context-menu
:filter (filters/filter-str filter-id shape)}
[:& filters/filters {:filter-id filter-id :shape shape}]
[:*
(when @render-editor
[:g {:opacity 0
:style {:pointer-events "none"}}
;; We only render the component for its side-effect
[:& text-shape-edit {:shape shape
:read-only? true}]])
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.shape {:on-double-click on-double-click
:on-mouse-down on-mouse-down
:on-context-menu on-context-menu
:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
[:*
(when @render-editor
[:g {:opacity 0
:style {:pointer-events "none"}}
;; We only render the component for its side-effect
[:& text-shape-edit {:shape shape
:read-only? true}]])
(if edition?
[:& text-shape-edit {:shape shape}]
[:& text/text-shape {:shape shape
:selected? selected?}])]]))
(if edition?
[:& text-shape-edit {:shape shape}]
[:& text/text-shape {:shape shape
:selected? selected?}])]]]))
;; --- Text Editor Rendering
@ -158,17 +165,25 @@
fill-color (obj/get data "fill-color" fill)
fill-opacity (obj/get data "fill-opacity" opacity)
fill-color-gradient (obj/get data "fill-color-gradient" nil)
fill-color-gradient (when fill-color-gradient
(-> (js->clj fill-color-gradient :keywordize-keys true)
(update :type keyword)))
fill-color-ref-id (obj/get data "fill-color-ref-id")
fill-color-ref-file (obj/get data "fill-color-ref-file")
[r g b a] (uc/hex->rgba fill-color fill-opacity)
background (if fill-color-gradient
(uc/gradient->css (js->clj fill-color-gradient))
(str/format "rgba(%s, %s, %s, %s)" r g b a))
fontsdb (deref fonts/fontsdb)
base #js {:textDecoration text-decoration
:color (str/format "rgba(%s, %s, %s, %s)" r g b a)
:textTransform text-transform
:lineHeight (or line-height "inherit")}]
:lineHeight (or line-height "inherit")
"--text-color" background}]
(when (and (string? letter-spacing)
(pos? (alength letter-spacing)))
@ -243,7 +258,9 @@
childs (obj/get props "children")
data (obj/get props "leaf")
style (generate-text-styles data)
attrs (obj/set! attrs "style" style)]
attrs (-> attrs
(obj/set! "style" style)
(obj/set! "className" "text-node"))]
[:> :span attrs childs]))
(defn- render-element
@ -284,6 +301,14 @@
children-count (->> node :children (map content-size) (reduce +))]
(+ current children-count)))
(defn fix-gradients
"Fix for the gradient types that need to be keywords"
[content]
(let [fix-node
(fn [node]
(d/update-in-when node [:fill-color-gradient :type] keyword))]
(ut/map-node fix-node content)))
(mf/defc text-shape-edit
{::mf/wrap [mf/memo]}
[{:keys [shape read-only?] :or {read-only? false} :as props}]
@ -364,7 +389,8 @@
(fn [val]
(when (not read-only?)
(let [content (js->clj val :keywordize-keys true)
content (first content)]
content (first content)
content (fix-gradients content)]
;; Append timestamp so we can react to cursor change events
(st/emit! (dw/update-shape id {:content (assoc content :ts (js->clj (.now js/Date)))}))
(reset! state val)
@ -419,7 +445,8 @@
:x x :y y
:width (if (= :auto-width grow-type) 10000 width)
:height height}
[:style "span { line-height: inherit; }"]
[:style "span { line-height: inherit; }
.text-node { background: var(--text-color); -webkit-text-fill-color: transparent; -webkit-background-clip: text;"]
[:> rslate/Slate {:editor editor
:value @state
:on-change on-change}

View file

@ -290,6 +290,8 @@
:shape shape
:attrs text-fill-attrs})
fill-values (d/update-in-when fill-values [:fill-color-gradient :type] keyword)
fill-values (cond-> fill-values
;; Keep for backwards compatibility
(:fill fill-values) (assoc :fill-color (:fill fill-values))