0
Fork 0
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:
alonso.torres 2021-06-08 12:23:50 +02:00
parent 0647fa832a
commit e880d94f51
6 changed files with 101 additions and 79 deletions

View file

@ -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)))

View file

@ -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)}])]))))

View file

@ -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")]

View file

@ -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])

View file

@ -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}]]))))

View file

@ -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)