mirror of
https://github.com/penpot/penpot.git
synced 2025-08-06 13:28:32 +02:00
Merge pull request #1911 from penpot/alotor-fix-texts
Fix problems with texts and thumbnails
This commit is contained in:
commit
180c355340
12 changed files with 59 additions and 40 deletions
|
@ -326,7 +326,7 @@
|
||||||
transform (->> svg-transform
|
transform (->> svg-transform
|
||||||
(gmt/transform-in (gpt/point svg-data)))
|
(gmt/transform-in (gpt/point svg-data)))
|
||||||
|
|
||||||
image-url (:xlink:href attrs)
|
image-url (or (:href attrs) (:xlink:href attrs))
|
||||||
image-data (get-in svg-data [:image-data image-url])
|
image-data (get-in svg-data [:image-data image-url])
|
||||||
|
|
||||||
rect (->> (select-keys attrs [:x :y :width :height])
|
rect (->> (select-keys attrs [:x :y :width :height])
|
||||||
|
@ -352,7 +352,7 @@
|
||||||
|
|
||||||
(merge rect-metadata)
|
(merge rect-metadata)
|
||||||
(assoc :svg-viewbox (select-keys rect [:x :y :width :height]))
|
(assoc :svg-viewbox (select-keys rect [:x :y :width :height]))
|
||||||
(assoc :svg-attrs (dissoc attrs :x :y :width :height :xlink:href))))))
|
(assoc :svg-attrs (dissoc attrs :x :y :width :height :href :xlink:href))))))
|
||||||
|
|
||||||
(defn parse-svg-element [frame-id svg-data element-data unames]
|
(defn parse-svg-element [frame-id svg-data element-data unames]
|
||||||
(let [{:keys [tag attrs]} element-data
|
(let [{:keys [tag attrs]} element-data
|
||||||
|
|
|
@ -13,5 +13,5 @@
|
||||||
class (str "icon-" (name id))]
|
class (str "icon-" (name id))]
|
||||||
`(rumext.alpha/html
|
`(rumext.alpha/html
|
||||||
[:svg {:width 500 :height 500 :class ~class}
|
[:svg {:width 500 :height 500 :class ~class}
|
||||||
[:use {:xlinkHref ~href}]])))
|
[:use {:href ~href}]])))
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
clip-id (str "inner-stroke-" render-id "-" (:id shape) suffix)
|
clip-id (str "inner-stroke-" render-id "-" (:id shape) suffix)
|
||||||
shape-id (str "stroke-shape-" render-id "-" (:id shape) suffix)]
|
shape-id (str "stroke-shape-" render-id "-" (:id shape) suffix)]
|
||||||
[:> "clipPath" #js {:id clip-id}
|
[:> "clipPath" #js {:id clip-id}
|
||||||
[:use {:xlinkHref (str "#" shape-id)}]]))
|
[:use {:href (str "#" shape-id)}]]))
|
||||||
|
|
||||||
(mf/defc outer-stroke-mask
|
(mf/defc outer-stroke-mask
|
||||||
[{:keys [shape render-id index]}]
|
[{:keys [shape render-id index]}]
|
||||||
|
@ -58,10 +58,10 @@
|
||||||
:width (:width bounding-box)
|
:width (:width bounding-box)
|
||||||
:height (:height bounding-box)
|
:height (:height bounding-box)
|
||||||
:maskUnits "userSpaceOnUse"}
|
:maskUnits "userSpaceOnUse"}
|
||||||
[:use {:xlinkHref (str "#" shape-id)
|
[:use {:href (str "#" shape-id)
|
||||||
:style #js {:fill "none" :stroke "white" :strokeWidth (* stroke-width 2)}}]
|
:style #js {:fill "none" :stroke "white" :strokeWidth (* stroke-width 2)}}]
|
||||||
|
|
||||||
[:use {:xlinkHref (str "#" shape-id)
|
[:use {:href (str "#" shape-id)
|
||||||
:style #js {:fill "black"
|
:style #js {:fill "black"
|
||||||
:stroke "none"}}]]))
|
:stroke "none"}}]]))
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@
|
||||||
(obj/clone)
|
(obj/clone)
|
||||||
(obj/without ["fill" "fillOpacity" "stroke" "strokeWidth" "strokeOpacity" "strokeStyle" "strokeDasharray"]))))]]
|
(obj/without ["fill" "fillOpacity" "stroke" "strokeWidth" "strokeOpacity" "strokeStyle" "strokeDasharray"]))))]]
|
||||||
|
|
||||||
[:use {:xlinkHref (str "#" shape-id)
|
[:use {:href (str "#" shape-id)
|
||||||
:mask (str "url(#" stroke-mask-id ")")
|
:mask (str "url(#" stroke-mask-id ")")
|
||||||
:style (-> (obj/get base-props "style")
|
:style (-> (obj/get base-props "style")
|
||||||
(obj/clone)
|
(obj/clone)
|
||||||
|
@ -241,7 +241,7 @@
|
||||||
(obj/without ["fill" "fillOpacity"])
|
(obj/without ["fill" "fillOpacity"])
|
||||||
(obj/set! "fill" "none"))}]
|
(obj/set! "fill" "none"))}]
|
||||||
|
|
||||||
[:use {:xlinkHref (str "#" shape-id)
|
[:use {:href (str "#" shape-id)
|
||||||
:style (-> (obj/get base-props "style")
|
:style (-> (obj/get base-props "style")
|
||||||
(obj/clone)
|
(obj/clone)
|
||||||
(obj/set! "stroke" "none"))}]]))
|
(obj/set! "stroke" "none"))}]]))
|
||||||
|
@ -277,7 +277,7 @@
|
||||||
[:& stroke-defs {:shape shape :render-id render-id :index index}]
|
[:& stroke-defs {:shape shape :render-id render-id :index index}]
|
||||||
[:> elem-name shape-props]]
|
[:> elem-name shape-props]]
|
||||||
|
|
||||||
[:use {:xlinkHref (str "#" shape-id)
|
[:use {:href (str "#" shape-id)
|
||||||
:clipPath clip-path}]]))
|
:clipPath clip-path}]]))
|
||||||
|
|
||||||
; The SVG standard does not implement yet the 'stroke-alignment'
|
; The SVG standard does not implement yet the 'stroke-alignment'
|
||||||
|
|
|
@ -43,15 +43,11 @@
|
||||||
embed (embed/use-data-uris [uri])
|
embed (embed/use-data-uris [uri])
|
||||||
transform (gsh/transform-matrix shape)
|
transform (gsh/transform-matrix shape)
|
||||||
|
|
||||||
;; When true the image has not loaded yet
|
|
||||||
loading? (and (some? uri) (not (contains? embed uri)))
|
|
||||||
|
|
||||||
pattern-attrs (cond-> #js {:patternUnits "userSpaceOnUse"
|
pattern-attrs (cond-> #js {:patternUnits "userSpaceOnUse"
|
||||||
:x x
|
:x x
|
||||||
:y y
|
:y y
|
||||||
:height height
|
:height height
|
||||||
:width width
|
:width width}
|
||||||
:data-loading loading?}
|
|
||||||
(= :path (:type shape))
|
(= :path (:type shape))
|
||||||
(obj/set! "patternTransform" transform))]
|
(obj/set! "patternTransform" transform))]
|
||||||
|
|
||||||
|
@ -79,7 +75,7 @@
|
||||||
(obj/set! "height" height))])
|
(obj/set! "height" height))])
|
||||||
|
|
||||||
(when has-image?
|
(when has-image?
|
||||||
[:image {:xlinkHref (get embed uri uri)
|
[:image {:href (get embed uri uri)
|
||||||
:preserveAspectRatio "none"
|
:preserveAspectRatio "none"
|
||||||
:width width
|
:width width
|
||||||
:height height}])]])])))))
|
:height height}])]])])))))
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
|
|
||||||
[:image.frame-thumbnail
|
[:image.frame-thumbnail
|
||||||
{:id (dm/str "thumbnail-" (:id shape))
|
{:id (dm/str "thumbnail-" (:id shape))
|
||||||
:xlinkHref (:thumbnail shape)
|
:href (:thumbnail shape)
|
||||||
:x (:x shape)
|
:x (:x shape)
|
||||||
:y (:y shape)
|
:y (:y shape)
|
||||||
:width (:width shape)
|
:width (:width shape)
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace.thumbnails :as dwt]
|
[app.main.data.workspace.thumbnails :as dwt]
|
||||||
|
[app.main.fonts :as fonts]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.ui.context :as ctx]
|
[app.main.ui.context :as ctx]
|
||||||
[app.main.ui.hooks :as hooks]
|
[app.main.ui.hooks :as hooks]
|
||||||
|
@ -27,19 +28,17 @@
|
||||||
[shape-wrapper]
|
[shape-wrapper]
|
||||||
(let [frame-shape (frame/frame-shape shape-wrapper)]
|
(let [frame-shape (frame/frame-shape shape-wrapper)]
|
||||||
(mf/fnc frame-shape-inner
|
(mf/fnc frame-shape-inner
|
||||||
{::mf/wrap [#(mf/memo' % (mf/check-props ["shape" "fonts"]))]
|
{::mf/wrap [#(mf/memo' % (mf/check-props ["shape"]))]
|
||||||
::mf/wrap-props false
|
::mf/wrap-props false
|
||||||
::mf/forward-ref true}
|
::mf/forward-ref true}
|
||||||
[props ref]
|
[props ref]
|
||||||
|
|
||||||
(let [shape (unchecked-get props "shape")
|
(let [shape (unchecked-get props "shape")
|
||||||
fonts (unchecked-get props "fonts")
|
|
||||||
childs-ref (mf/use-memo (mf/deps (:id shape)) #(refs/children-objects (:id shape)))
|
childs-ref (mf/use-memo (mf/deps (:id shape)) #(refs/children-objects (:id shape)))
|
||||||
childs (mf/deref childs-ref)]
|
childs (mf/deref childs-ref)]
|
||||||
|
|
||||||
[:& (mf/provider embed/context) {:value true}
|
[:& (mf/provider embed/context) {:value true}
|
||||||
[:& shape-container {:shape shape :ref ref}
|
[:& shape-container {:shape shape :ref ref}
|
||||||
[:& ff/fontfaces-style {:fonts fonts}]
|
|
||||||
[:& frame-shape {:shape shape :childs childs} ]]]))))
|
[:& frame-shape {:shape shape :childs childs} ]]]))))
|
||||||
|
|
||||||
(defn check-props
|
(defn check-props
|
||||||
|
@ -90,13 +89,20 @@
|
||||||
disable-thumbnail? (d/not-empty? (dm/get-in modifiers [(:id shape) :modifiers]))
|
disable-thumbnail? (d/not-empty? (dm/get-in modifiers [(:id shape) :modifiers]))
|
||||||
|
|
||||||
[on-load-frame-dom thumb-renderer]
|
[on-load-frame-dom thumb-renderer]
|
||||||
(ftr/use-render-thumbnail page-id shape node-ref rendered? thumbnail? disable-thumbnail?)
|
(ftr/use-render-thumbnail page-id shape node-ref rendered? thumbnail-data-ref disable-thumbnail?)
|
||||||
|
|
||||||
on-frame-load
|
on-frame-load
|
||||||
(fns/use-node-store thumbnail? node-ref rendered?)]
|
(fns/use-node-store thumbnail? node-ref rendered?)]
|
||||||
|
|
||||||
(fdm/use-dynamic-modifiers objects @node-ref modifiers)
|
(fdm/use-dynamic-modifiers objects @node-ref modifiers)
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(mf/deps fonts)
|
||||||
|
(fn []
|
||||||
|
(->> (rx/from fonts)
|
||||||
|
(rx/merge-map fonts/fetch-font-css)
|
||||||
|
(rx/ignore))))
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
;; When a change in the data is received a "force-render" event is emited
|
;; When a change in the data is received a "force-render" event is emited
|
||||||
|
@ -120,7 +126,10 @@
|
||||||
(when (not @rendered?) (reset! rendered? true)))))
|
(when (not @rendered?) (reset! rendered? true)))))
|
||||||
|
|
||||||
[:& (mf/provider ctx/render-ctx) {:value render-id}
|
[:& (mf/provider ctx/render-ctx) {:value render-id}
|
||||||
[:g.frame-container {:key "frame-container" :ref on-frame-load}
|
[:g.frame-container {:id (dm/str "frame-container-" (:id shape))
|
||||||
|
:key "frame-container"
|
||||||
|
:ref on-frame-load}
|
||||||
|
[:& ff/fontfaces-style {:fonts fonts}]
|
||||||
[:g.frame-thumbnail-wrapper {:id (dm/str "thumbnail-container-" (:id shape))}
|
[:g.frame-thumbnail-wrapper {:id (dm/str "thumbnail-container-" (:id shape))}
|
||||||
[:> frame/frame-thumbnail {:key (dm/str (:id shape))
|
[:> frame/frame-thumbnail {:key (dm/str (:id shape))
|
||||||
:shape (cond-> shape
|
:shape (cond-> shape
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.shapes.frame.thumbnail-render
|
(ns app.main.ui.workspace.shapes.frame.thumbnail-render
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.timers :as ts]
|
[app.util.timers :as ts]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
|
[cuerdas.core :as str]
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
|
||||||
;; (def thumbnail-scale-factor 2)
|
;; (def thumbnail-scale-factor 2)
|
||||||
|
@ -41,9 +43,19 @@
|
||||||
(.error js/console err)
|
(.error js/console err)
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
|
(defn- remove-embed-images-changes
|
||||||
|
"Remove the changes related to change a url for its embed value. This is necessary
|
||||||
|
so we don't have to recalculate the thumbnail when the image loads."
|
||||||
|
[changes]
|
||||||
|
(->> changes
|
||||||
|
(remove (fn [change]
|
||||||
|
(and (= "attributes" (.-type change))
|
||||||
|
(= "href" (.-attributeName change))
|
||||||
|
(str/starts-with? (.-oldValue change) "http"))))))
|
||||||
|
|
||||||
(defn use-render-thumbnail
|
(defn use-render-thumbnail
|
||||||
"Hook that will create the thumbnail thata"
|
"Hook that will create the thumbnail thata"
|
||||||
[page-id {:keys [id x y width height] :as shape} node-ref rendered? thumbnail? disable?]
|
[page-id {:keys [id x y width height] :as shape} node-ref rendered? thumbnail-data-ref disable?]
|
||||||
|
|
||||||
(let [frame-canvas-ref (mf/use-ref nil)
|
(let [frame-canvas-ref (mf/use-ref nil)
|
||||||
frame-image-ref (mf/use-ref nil)
|
frame-image-ref (mf/use-ref nil)
|
||||||
|
@ -58,8 +70,6 @@
|
||||||
|
|
||||||
shape-ref (hooks/use-update-var shape)
|
shape-ref (hooks/use-update-var shape)
|
||||||
|
|
||||||
thumbnail-ref? (mf/use-var thumbnail?)
|
|
||||||
|
|
||||||
updates-str (mf/use-memo #(rx/subject))
|
updates-str (mf/use-memo #(rx/subject))
|
||||||
|
|
||||||
on-image-load
|
on-image-load
|
||||||
|
@ -79,6 +89,10 @@
|
||||||
(let [node @node-ref
|
(let [node @node-ref
|
||||||
frame-html (dom/node->xml node)
|
frame-html (dom/node->xml node)
|
||||||
{:keys [x y width height]} @shape-ref
|
{:keys [x y width height]} @shape-ref
|
||||||
|
|
||||||
|
style-node (dom/query (dm/str "#frame-container-" (:id shape) " style"))
|
||||||
|
style-str (or (-> style-node dom/node->xml) "")
|
||||||
|
|
||||||
svg-node
|
svg-node
|
||||||
(-> (dom/make-node "http://www.w3.org/2000/svg" "svg")
|
(-> (dom/make-node "http://www.w3.org/2000/svg" "svg")
|
||||||
(dom/set-property! "version" "1.1")
|
(dom/set-property! "version" "1.1")
|
||||||
|
@ -86,7 +100,7 @@
|
||||||
(dom/set-property! "width" width)
|
(dom/set-property! "width" width)
|
||||||
(dom/set-property! "height" height)
|
(dom/set-property! "height" height)
|
||||||
(dom/set-property! "fill" "none")
|
(dom/set-property! "fill" "none")
|
||||||
(obj/set! "innerHTML" frame-html))
|
(obj/set! "innerHTML" (dm/str style-str frame-html)))
|
||||||
img-src (-> svg-node dom/node->xml dom/svg->data-uri)]
|
img-src (-> svg-node dom/node->xml dom/svg->data-uri)]
|
||||||
(reset! image-url img-src))))
|
(reset! image-url img-src))))
|
||||||
|
|
||||||
|
@ -94,15 +108,19 @@
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(fn [node]
|
(fn [node]
|
||||||
(when (and (some? node) (nil? @observer-ref))
|
(when (and (some? node) (nil? @observer-ref))
|
||||||
(rx/push! updates-str :update)
|
(when-not (some? @thumbnail-data-ref)
|
||||||
|
(rx/push! updates-str :update))
|
||||||
|
|
||||||
(let [observer (js/MutationObserver. (partial rx/push! updates-str))]
|
(let [observer (js/MutationObserver. (partial rx/push! updates-str))]
|
||||||
(.observe observer node #js {:childList true :attributes true :characterData true :subtree true})
|
(.observe observer node #js {:childList true :attributes true :attributeOldValue true :characterData true :subtree true})
|
||||||
(reset! observer-ref observer)))))]
|
(reset! observer-ref observer)))))]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(let [subid (->> updates-str
|
(let [subid (->> updates-str
|
||||||
(rx/debounce 200)
|
(rx/map remove-embed-images-changes)
|
||||||
|
(rx/filter d/not-empty?)
|
||||||
|
(rx/debounce 400)
|
||||||
(rx/subs on-update-frame))]
|
(rx/subs on-update-frame))]
|
||||||
#(rx/dispose! subid))))
|
#(rx/dispose! subid))))
|
||||||
|
|
||||||
|
@ -111,11 +129,6 @@
|
||||||
(fn []
|
(fn []
|
||||||
(reset! disable-ref? disable?)))
|
(reset! disable-ref? disable?)))
|
||||||
|
|
||||||
(mf/use-effect
|
|
||||||
(mf/deps thumbnail?)
|
|
||||||
(fn []
|
|
||||||
(reset! thumbnail-ref? thumbnail?)))
|
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
#(when (and (some? @node-ref) @rendered?)
|
#(when (and (some? @node-ref) @rendered?)
|
||||||
|
@ -138,7 +151,7 @@
|
||||||
[:image {:ref frame-image-ref
|
[:image {:ref frame-image-ref
|
||||||
:x (:x shape)
|
:x (:x shape)
|
||||||
:y (:y shape)
|
:y (:y shape)
|
||||||
:xlinkHref @image-url
|
:href @image-url
|
||||||
:width (:width shape)
|
:width (:width shape)
|
||||||
:height (:height shape)
|
:height (:height shape)
|
||||||
:on-load on-image-load}]]))]))
|
:on-load on-image-load}]]))]))
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
(let [modifier (get modifiers id)
|
(let [modifier (get modifiers id)
|
||||||
modifier (d/update-when modifier :modifiers dissoc :displacement :rotation)
|
modifier (d/update-when modifier :modifiers dissoc :displacement :rotation)
|
||||||
shape (cond-> shape
|
shape (cond-> shape
|
||||||
(not (gsh/empty-modifiers? modifier))
|
(not (gsh/empty-modifiers? (:modifiers modifier)))
|
||||||
(-> (assoc :grow-type :fixed)
|
(-> (assoc :grow-type :fixed)
|
||||||
(merge modifier) gsh/transform-shape))]
|
(merge modifier) gsh/transform-shape))]
|
||||||
(strip-position-data shape)))
|
(strip-position-data shape)))
|
||||||
|
|
|
@ -147,7 +147,7 @@
|
||||||
:class "workspace-frame-icon"
|
:class "workspace-frame-icon"
|
||||||
:style {:fill (when selected? "var(--color-primary-dark)")}
|
:style {:fill (when selected? "var(--color-primary-dark)")}
|
||||||
:visibility (if show-artboard-names? "visible" "hidden")}
|
:visibility (if show-artboard-names? "visible" "hidden")}
|
||||||
[:use {:xlinkHref "#icon-set-thumbnail"}]]])
|
[:use {:href "#icon-set-thumbnail"}]]])
|
||||||
[:text {:x text-pos-x
|
[:text {:x text-pos-x
|
||||||
:y 0
|
:y 0
|
||||||
:width width
|
:width width
|
||||||
|
|
|
@ -264,7 +264,7 @@
|
||||||
:embed embed}
|
:embed embed}
|
||||||
|
|
||||||
(when-let [component-id (:component-id @state)]
|
(when-let [component-id (:component-id @state)]
|
||||||
[:use {:x 0 :y 0 :xlinkHref (str "#" component-id)}])]]
|
[:use {:x 0 :y 0 :href (str "#" component-id)}])]]
|
||||||
|
|
||||||
])))
|
])))
|
||||||
|
|
||||||
|
|
|
@ -335,8 +335,9 @@
|
||||||
|
|
||||||
(defn node->xml
|
(defn node->xml
|
||||||
[node]
|
[node]
|
||||||
|
(when (some? node)
|
||||||
(-> (js/XMLSerializer.)
|
(-> (js/XMLSerializer.)
|
||||||
(.serializeToString node)))
|
(.serializeToString node))))
|
||||||
|
|
||||||
(defn svg->data-uri
|
(defn svg->data-uri
|
||||||
[svg]
|
[svg]
|
||||||
|
|
|
@ -961,5 +961,5 @@
|
||||||
(let [redfn (fn [acc {:keys [tag attrs]}]
|
(let [redfn (fn [acc {:keys [tag attrs]}]
|
||||||
(cond-> acc
|
(cond-> acc
|
||||||
(= :image tag)
|
(= :image tag)
|
||||||
(conj (:xlink:href attrs))))]
|
(conj (or (:href attrs) (:xlink:href attrs)))))]
|
||||||
(reduce-nodes redfn [] svg-data )))
|
(reduce-nodes redfn [] svg-data )))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue