mirror of
https://github.com/penpot/penpot.git
synced 2025-01-24 23:49:45 -05:00
✨ Add import blend modes
This commit is contained in:
parent
0647fa832a
commit
e880d94f51
6 changed files with 101 additions and 79 deletions
|
@ -141,23 +141,28 @@
|
|||
styles (-> svg-attrs (:style {}) (clj->js))]
|
||||
[attrs styles]))
|
||||
|
||||
(defn add-style-attrs
|
||||
[props shape]
|
||||
(let [render-id (mf/use-ctx muc/render-ctx)
|
||||
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))
|
||||
|
||||
styles (-> (obj/get props "style" (obj/new))
|
||||
(obj/merge! svg-styles)
|
||||
(add-fill shape render-id)
|
||||
(add-stroke shape render-id)
|
||||
(add-layer-props shape))]
|
||||
|
||||
(-> props
|
||||
(obj/merge! svg-attrs)
|
||||
(add-border-radius shape)
|
||||
(obj/set! "style" styles))))
|
||||
|
||||
(defn extract-style-attrs
|
||||
([shape]
|
||||
(let [render-id (mf/use-ctx muc/render-ctx)
|
||||
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))
|
||||
|
||||
styles (-> (obj/new)
|
||||
(obj/merge! svg-styles)
|
||||
(add-fill shape render-id)
|
||||
(add-stroke shape render-id)
|
||||
(add-layer-props shape))]
|
||||
|
||||
(-> (obj/new)
|
||||
(obj/merge! svg-attrs)
|
||||
(add-border-radius shape)
|
||||
(obj/set! "style" styles)))))
|
||||
[shape]
|
||||
(-> (obj/new)
|
||||
(add-style-attrs shape)))
|
||||
|
|
|
@ -20,33 +20,29 @@
|
|||
(let [frame (unchecked-get props "frame")
|
||||
shape (unchecked-get props "shape")
|
||||
childs (unchecked-get props "childs")
|
||||
expand-mask (unchecked-get props "expand-mask")
|
||||
pointer-events (unchecked-get props "pointer-events")
|
||||
|
||||
{:keys [id x y width height]} shape
|
||||
{:keys [id x y width height masked-group?]} shape
|
||||
|
||||
show-mask? (and (:masked-group? shape) (not expand-mask))
|
||||
mask (when show-mask? (first childs))
|
||||
childs (if show-mask? (rest childs) childs)
|
||||
[mask childs] (if masked-group?
|
||||
[(first childs) (rest childs)]
|
||||
[nil childs])
|
||||
|
||||
mask-props (when (and mask (not expand-mask))
|
||||
#js {:clipPath (clip-str mask)
|
||||
:mask (mask-str mask)})
|
||||
mask-wrapper (if (and mask (not expand-mask))
|
||||
"g"
|
||||
mf/Fragment)
|
||||
[mask-wrapper mask-props]
|
||||
(if masked-group?
|
||||
["g" (-> (obj/new)
|
||||
(obj/set! "clipPath" (clip-str mask))
|
||||
(obj/set! "mask" (mask-str mask)))]
|
||||
[mf/Fragment nil])]
|
||||
|
||||
props (-> (attrs/extract-style-attrs shape))]
|
||||
[:> mask-wrapper mask-props
|
||||
(when masked-group?
|
||||
[:> render-mask #js {:frame frame :mask mask}])
|
||||
|
||||
[:> :g (attrs/extract-style-attrs shape)
|
||||
[:> mask-wrapper mask-props
|
||||
(when mask
|
||||
[:> render-mask #js {:frame frame :mask mask}])
|
||||
|
||||
(for [item childs]
|
||||
[:& shape-wrapper {:frame frame
|
||||
:shape item
|
||||
:key (:id item)}])]]))))
|
||||
(for [item childs]
|
||||
[:& shape-wrapper {:frame frame
|
||||
:shape item
|
||||
:key (:id item)}])]))))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,11 +9,12 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.ui.context :as muc]
|
||||
[app.main.ui.shapes.attrs :as attrs]
|
||||
[app.main.ui.shapes.custom-stroke :as cs]
|
||||
[app.main.ui.shapes.export :as ed]
|
||||
[app.main.ui.shapes.fill-image :as fim]
|
||||
[app.main.ui.shapes.filters :as filters]
|
||||
[app.main.ui.shapes.gradients :as grad]
|
||||
[app.main.ui.shapes.export :as ed]
|
||||
[app.main.ui.shapes.svg-defs :as defs]
|
||||
[app.util.object :as obj]
|
||||
[rumext.alpha :as mf]))
|
||||
|
@ -35,6 +36,7 @@
|
|||
|
||||
{:keys [x y width height type]} shape
|
||||
frame? (= :frame type)
|
||||
group? (= :group type)
|
||||
|
||||
wrapper-props
|
||||
(-> (obj/clone props)
|
||||
|
@ -42,16 +44,23 @@
|
|||
(obj/set! "ref" ref)
|
||||
(obj/set! "id" (str "shape-" (:id shape)))
|
||||
(obj/set! "filter" (filters/filter-str filter-id shape))
|
||||
(obj/set! "style" styles)
|
||||
(obj/set! "style" styles))
|
||||
|
||||
(cond-> frame?
|
||||
(-> (obj/set! "x" x)
|
||||
(obj/set! "y" y)
|
||||
(obj/set! "width" width)
|
||||
(obj/set! "height" height)
|
||||
(obj/set! "xmlnsXlink" "http://www.w3.org/1999/xlink")
|
||||
(obj/set! "xmlns" "http://www.w3.org/2000/svg")
|
||||
(obj/set! "xmlns:penpot" "https://penpot.app/xmlns"))))
|
||||
wrapper-props
|
||||
(cond-> wrapper-props
|
||||
frame?
|
||||
(-> (obj/set! "x" x)
|
||||
(obj/set! "y" y)
|
||||
(obj/set! "width" width)
|
||||
(obj/set! "height" height)
|
||||
(obj/set! "xmlnsXlink" "http://www.w3.org/1999/xlink")
|
||||
(obj/set! "xmlns" "http://www.w3.org/2000/svg")
|
||||
(obj/set! "xmlns:penpot" "https://penpot.app/xmlns")))
|
||||
|
||||
wrapper-props
|
||||
(cond-> wrapper-props
|
||||
group?
|
||||
(attrs/add-style-attrs shape))
|
||||
|
||||
wrapper-tag (if frame? "svg" "g")]
|
||||
|
||||
|
|
|
@ -83,20 +83,19 @@
|
|||
(when (and shape (not (:hidden shape)))
|
||||
[:*
|
||||
(if-not svg-element?
|
||||
[:g.shape-wrapper
|
||||
(case (:type shape)
|
||||
:path [:> path/path-wrapper opts]
|
||||
:text [:> text/text-wrapper opts]
|
||||
:group [:> group-wrapper opts]
|
||||
:rect [:> rect-wrapper opts]
|
||||
:image [:> image-wrapper opts]
|
||||
:circle [:> circle-wrapper opts]
|
||||
:svg-raw [:> svg-raw-wrapper opts]
|
||||
(case (:type shape)
|
||||
:path [:> path/path-wrapper opts]
|
||||
:text [:> text/text-wrapper opts]
|
||||
:group [:> group-wrapper opts]
|
||||
:rect [:> rect-wrapper opts]
|
||||
:image [:> image-wrapper opts]
|
||||
:circle [:> circle-wrapper opts]
|
||||
:svg-raw [:> svg-raw-wrapper opts]
|
||||
|
||||
;; Only used when drawing a new frame.
|
||||
:frame [:> frame-wrapper {:shape shape}]
|
||||
;; Only used when drawing a new frame.
|
||||
:frame [:> frame-wrapper {:shape shape}]
|
||||
|
||||
nil)]
|
||||
nil)
|
||||
|
||||
;; Don't wrap svg elements inside a <g> otherwise some can break
|
||||
[:> svg-raw-wrapper opts])
|
||||
|
|
|
@ -42,9 +42,8 @@
|
|||
childs (mf/deref childs-ref)]
|
||||
|
||||
[:> shape-container {:shape shape}
|
||||
[:g.group-shape
|
||||
[:& group-shape
|
||||
{:frame frame
|
||||
:shape shape
|
||||
:childs childs}]]]))))
|
||||
[:& group-shape
|
||||
{:frame frame
|
||||
:shape shape
|
||||
:childs childs}]]))))
|
||||
|
||||
|
|
|
@ -96,14 +96,15 @@
|
|||
(defn get-svg-data
|
||||
[type node]
|
||||
|
||||
(if (search-data-node? type)
|
||||
(let [data-tags #{:ellipse :rect :path :text :foreignObject :image}]
|
||||
(->> node
|
||||
(node-seq)
|
||||
(filter #(contains? data-tags (:tag %)))
|
||||
(map #(:attrs %))
|
||||
(reduce add-attrs {})))
|
||||
(:attrs node)))
|
||||
(let [node-attrs (add-attrs {} (:attrs node))]
|
||||
(if (search-data-node? type)
|
||||
(let [data-tags #{:ellipse :rect :path :text :foreignObject :image}]
|
||||
(->> node
|
||||
(node-seq)
|
||||
(filter #(contains? data-tags (:tag %)))
|
||||
(map #(:attrs %))
|
||||
(reduce add-attrs node-attrs)))
|
||||
node-attrs)))
|
||||
|
||||
(def has-position? #{:frame :rect :image :text})
|
||||
|
||||
|
@ -188,7 +189,7 @@
|
|||
(parse-path svg-data)))
|
||||
|
||||
(defn add-fill
|
||||
[props type node svg-data]
|
||||
[props node svg-data]
|
||||
|
||||
(let [fill (:fill svg-data)]
|
||||
(cond-> props
|
||||
|
@ -206,7 +207,7 @@
|
|||
:fill-opacity (-> svg-data (:fill-opacity "1") d/parse-double)))))
|
||||
|
||||
(defn add-stroke
|
||||
[props type node svg-data]
|
||||
[props node svg-data]
|
||||
|
||||
(let [stroke-style (get-meta node :stroke-style keyword)
|
||||
stroke-alignment (get-meta node :stroke-alignment keyword)
|
||||
|
@ -303,6 +304,18 @@
|
|||
(not (empty? exports))
|
||||
(assoc :exports exports))))
|
||||
|
||||
(defn add-layer-options
|
||||
[props svg-data]
|
||||
(let [blend-mode (get svg-data :mix-blend-mode)
|
||||
opacity (-> (get svg-data :opacity) d/parse-double)]
|
||||
|
||||
(cond-> props
|
||||
(some? blend-mode)
|
||||
(assoc :blend-mode (keyword blend-mode))
|
||||
|
||||
(some? opacity)
|
||||
(assoc :opacity opacity))))
|
||||
|
||||
(defn get-image-name
|
||||
[node]
|
||||
(get-in node [:attrs :penpot:name]))
|
||||
|
@ -325,8 +338,9 @@
|
|||
|
||||
(-> {}
|
||||
(add-position type node svg-data)
|
||||
(add-fill type node svg-data)
|
||||
(add-stroke type node svg-data)
|
||||
(add-fill node svg-data)
|
||||
(add-stroke node svg-data)
|
||||
(add-layer-options svg-data)
|
||||
(add-shadows node)
|
||||
(add-blur node)
|
||||
(add-exports node)
|
||||
|
|
Loading…
Add table
Reference in a new issue