mirror of
https://github.com/penpot/penpot.git
synced 2025-06-09 21:01:40 +02:00
✨ Fix masks for Firefox
This commit is contained in:
parent
96eacb6efe
commit
d0e008665f
3 changed files with 64 additions and 29 deletions
|
@ -17,11 +17,15 @@
|
||||||
:width width
|
:width width
|
||||||
:height height})
|
:height height})
|
||||||
|
|
||||||
(defn position-data-bounding-box
|
(defn position-data-points
|
||||||
[{:keys [position-data] :as shape}]
|
[{:keys [position-data] :as shape}]
|
||||||
(let [points (->> position-data
|
(let [points (->> position-data
|
||||||
(mapcat (comp gpr/rect->points position-data->rect)))
|
(mapcat (comp gpr/rect->points position-data->rect)))
|
||||||
transform (gtr/transform-matrix shape)
|
transform (gtr/transform-matrix shape)]
|
||||||
points (gco/transform-points points transform)]
|
(gco/transform-points points transform)))
|
||||||
(gpr/points->selrect points)))
|
|
||||||
|
(defn position-data-bounding-box
|
||||||
|
[shape]
|
||||||
|
(gpr/points->selrect (position-data-points shape)))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
(ns app.main.ui.shapes.mask
|
(ns app.main.ui.shapes.mask
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.geom.shapes.text :as gst]
|
||||||
[app.main.ui.context :as muc]
|
[app.main.ui.context :as muc]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
@ -29,6 +31,17 @@
|
||||||
(defn filter-url [render-id mask]
|
(defn filter-url [render-id mask]
|
||||||
(str "url(#" (filter-id render-id mask) ")"))
|
(str "url(#" (filter-id render-id mask) ")"))
|
||||||
|
|
||||||
|
(defn set-white-fill
|
||||||
|
[shape]
|
||||||
|
(let [update-color
|
||||||
|
(fn [data]
|
||||||
|
(-> data
|
||||||
|
(dissoc :fill-color :fill-opacity :fill-color-gradient)
|
||||||
|
(assoc :fill-color "#FFFFFF" :fill-opacity 1)))]
|
||||||
|
(-> shape
|
||||||
|
(d/update-when :position-data #(mapv update-color %))
|
||||||
|
(assoc :stroke-color "#FFFFFF" :stroke-opacity 1))))
|
||||||
|
|
||||||
(defn mask-factory
|
(defn mask-factory
|
||||||
[shape-wrapper]
|
[shape-wrapper]
|
||||||
(mf/fnc mask-shape
|
(mf/fnc mask-shape
|
||||||
|
@ -36,7 +49,23 @@
|
||||||
[props]
|
[props]
|
||||||
(let [mask (unchecked-get props "mask")
|
(let [mask (unchecked-get props "mask")
|
||||||
render-id (mf/use-ctx muc/render-ctx)
|
render-id (mf/use-ctx muc/render-ctx)
|
||||||
mask' (gsh/transform-shape mask)]
|
svg-text? (and (= :text (:type mask)) (some? (:position-data mask)))
|
||||||
|
|
||||||
|
mask (cond-> mask svg-text? set-white-fill)
|
||||||
|
|
||||||
|
mask-bb
|
||||||
|
(cond
|
||||||
|
svg-text?
|
||||||
|
(gst/position-data-points mask)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(-> (gsh/transform-shape mask)
|
||||||
|
(:points)))]
|
||||||
|
[:*
|
||||||
|
[:g {:opacity 0}
|
||||||
|
[:g {:id (str "shape-" (mask-id render-id mask))}
|
||||||
|
[:& shape-wrapper {:shape (dissoc mask :shadow :blur)}]]]
|
||||||
|
|
||||||
[:defs
|
[:defs
|
||||||
[:filter {:id (filter-id render-id mask)}
|
[:filter {:id (filter-id render-id mask)}
|
||||||
[:feFlood {:flood-color "white"
|
[:feFlood {:flood-color "white"
|
||||||
|
@ -50,11 +79,14 @@
|
||||||
;; we cannot use clips instead of mask because clips can only be simple shapes
|
;; we cannot use clips instead of mask because clips can only be simple shapes
|
||||||
[:clipPath {:class "mask-clip-path"
|
[:clipPath {:class "mask-clip-path"
|
||||||
:id (clip-id render-id mask)}
|
:id (clip-id render-id mask)}
|
||||||
[:polyline {:points (->> (:points mask')
|
[:polyline {:points (->> mask-bb
|
||||||
(map #(str (:x %) "," (:y %)))
|
(map #(str (:x %) "," (:y %)))
|
||||||
(str/join " "))}]]
|
(str/join " "))}]]
|
||||||
|
|
||||||
[:mask {:class "mask-shape"
|
[:mask {:class "mask-shape"
|
||||||
:id (mask-id render-id mask)}
|
:id (mask-id render-id mask)}
|
||||||
[:g {:filter (filter-url render-id mask)}
|
;; SVG texts are broken in Firefox with the filter. When the masking shapes is a text
|
||||||
[:& shape-wrapper {:shape (dissoc mask :shadow :blur)}]]]])))
|
;; we use the `set-white-fill` instead of using the filter
|
||||||
|
[:g {:filter (when-not svg-text? (filter-url render-id mask))}
|
||||||
|
[:use {:href (str "#shape-" (mask-id render-id mask))}]]]]])))
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
(ns app.main.ui.workspace.shapes.text
|
(ns app.main.ui.workspace.shapes.text
|
||||||
(:require
|
(:require
|
||||||
[app.common.attrs :as attrs]
|
[app.common.attrs :as attrs]
|
||||||
[app.common.data :as d]
|
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.logging :as log]
|
[app.common.logging :as log]
|
||||||
|
@ -123,7 +122,7 @@
|
||||||
(mf/defc text-wrapper
|
(mf/defc text-wrapper
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[props]
|
[props]
|
||||||
(let [{:keys [id content points] :as shape} (unchecked-get props "shape")
|
(let [{:keys [id] :as shape} (unchecked-get props "shape")
|
||||||
edition-ref (mf/use-memo (mf/deps id) #(l/derived (fn [o] (= id (:edition o))) refs/workspace-local))
|
edition-ref (mf/use-memo (mf/deps id) #(l/derived (fn [o] (= id (:edition o))) refs/workspace-local))
|
||||||
edition? (mf/deref edition-ref)
|
edition? (mf/deref edition-ref)
|
||||||
|
|
||||||
|
@ -150,7 +149,7 @@
|
||||||
(gsh/transform-rect mtx)))))]
|
(gsh/transform-rect mtx)))))]
|
||||||
(reset! local-position-data position-data))))
|
(reset! local-position-data position-data))))
|
||||||
|
|
||||||
[shape-ref on-change-node] (use-mutable-observer handle-change-foreign-object)
|
[_ on-change-node] (use-mutable-observer handle-change-foreign-object)
|
||||||
|
|
||||||
show-svg-text? (or (some? (:position-data shape)) (some? @local-position-data))
|
show-svg-text? (or (some? (:position-data shape)) (some? @local-position-data))
|
||||||
|
|
||||||
|
@ -170,7 +169,7 @@
|
||||||
(fn []
|
(fn []
|
||||||
;; Timer to update the shape. We do this so a lot of changes won't produce
|
;; Timer to update the shape. We do this so a lot of changes won't produce
|
||||||
;; a lot of updates (kind of a debounce)
|
;; a lot of updates (kind of a debounce)
|
||||||
(let [sid (timers/schedule 250 update-position-data)]
|
(let [sid (timers/schedule 100 update-position-data)]
|
||||||
(fn []
|
(fn []
|
||||||
(rx/dispose! sid)))))
|
(rx/dispose! sid)))))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue