mirror of
https://github.com/penpot/penpot.git
synced 2025-06-06 18:51:41 +02:00
✨ Ability to add multiple fills to a shape
This commit is contained in:
parent
aecb8a1464
commit
23a9c74297
25 changed files with 475 additions and 243 deletions
|
@ -79,14 +79,15 @@
|
|||
"z")}))
|
||||
attrs))
|
||||
|
||||
(defn add-fill [attrs shape render-id]
|
||||
(let [fill-attrs (cond
|
||||
(defn add-fill [attrs shape render-id index]
|
||||
(let [
|
||||
fill-attrs (cond
|
||||
(contains? shape :fill-image)
|
||||
(let [fill-image-id (str "fill-image-" render-id)]
|
||||
{:fill (str/format "url(#%s)" fill-image-id)})
|
||||
|
||||
(contains? shape :fill-color-gradient)
|
||||
(let [fill-color-gradient-id (str "fill-color-gradient_" render-id)]
|
||||
(let [fill-color-gradient-id (str "fill-color-gradient_" render-id "_" index)]
|
||||
{:fill (str/format "url(#%s)" fill-color-gradient-id)})
|
||||
|
||||
(contains? shape :fill-color)
|
||||
|
@ -193,9 +194,23 @@
|
|||
|
||||
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))]
|
||||
(add-layer-props shape))
|
||||
|
||||
styles (cond (or (some? (:fill-image shape))
|
||||
(= :image (:type shape))
|
||||
(> (count (:fills shape)) 1)
|
||||
(some #(some? (:fill-color-gradient %)) (:fills shape)))
|
||||
(obj/set! styles "fill" (str "url(#fill-" render-id ")"))
|
||||
|
||||
;; imported svgs can have fill and fill-opacity attributes
|
||||
(obj/contains? svg-styles "fill")
|
||||
(-> styles
|
||||
(obj/set! "fill" (obj/get svg-styles "fill"))
|
||||
(obj/set! "fillOpacity" (obj/get svg-styles "fillOpacity")))
|
||||
|
||||
:else
|
||||
(add-fill styles (get-in shape [:fills 0]) render-id 0))]
|
||||
|
||||
(-> props
|
||||
(obj/merge! svg-attrs)
|
||||
|
@ -208,10 +223,10 @@
|
|||
(add-style-attrs shape)))
|
||||
|
||||
(defn extract-fill-attrs
|
||||
[shape]
|
||||
[shape index]
|
||||
(let [render-id (mf/use-ctx muc/render-ctx)
|
||||
fill-styles (-> (obj/get shape "style" (obj/new))
|
||||
(add-fill shape render-id))]
|
||||
(add-fill shape render-id index))]
|
||||
(-> (obj/new)
|
||||
(obj/set! "style" fill-styles))))
|
||||
|
||||
|
|
|
@ -103,11 +103,6 @@
|
|||
(-> (add! :rx)
|
||||
(add! :ry)))
|
||||
|
||||
(cond-> image?
|
||||
(-> (add! :fill-color)
|
||||
(add! :fill-opacity)
|
||||
(add! :fill-color-gradient)))
|
||||
|
||||
(cond-> path?
|
||||
(-> (add! :stroke-cap-start)
|
||||
(add! :stroke-cap-end)))
|
||||
|
@ -293,6 +288,7 @@
|
|||
:penpot:background-overlay ((d/nilf str) (:background-overlay interaction))
|
||||
:penpot:preserve-scroll ((d/nilf str) (:preserve-scroll interaction))}])])))
|
||||
|
||||
|
||||
(mf/defc export-data
|
||||
[{:keys [shape]}]
|
||||
(let [props (-> (obj/new) (add-data shape) (add-library-refs shape))]
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.shapes.fill-image
|
||||
(:require
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.config :as cfg]
|
||||
[app.main.ui.shapes.attrs :as attrs]
|
||||
[app.main.ui.shapes.embed :as embed]
|
||||
[app.util.object :as obj]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc fill-image-pattern
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
|
||||
(let [shape (obj/get props "shape")
|
||||
render-id (obj/get props "render-id")]
|
||||
(when (contains? shape :fill-image)
|
||||
(let [{:keys [x y width height]} (:selrect shape)
|
||||
fill-image-id (str "fill-image-" render-id)
|
||||
uri (cfg/resolve-file-media (:fill-image shape))
|
||||
embed (embed/use-data-uris [uri])
|
||||
transform (gsh/transform-matrix shape)
|
||||
shape-without-image (dissoc shape :fill-image)
|
||||
fill-attrs (-> (attrs/extract-fill-attrs shape-without-image)
|
||||
(obj/set! "width" width)
|
||||
(obj/set! "height" height))]
|
||||
|
||||
[:pattern {:id fill-image-id
|
||||
:patternUnits "userSpaceOnUse"
|
||||
:x x
|
||||
:y y
|
||||
:height height
|
||||
:width width
|
||||
:patternTransform transform
|
||||
:data-loading (str (not (contains? embed uri)))}
|
||||
[:g
|
||||
[:> :rect fill-attrs]
|
||||
[:image {:xlinkHref (get embed uri uri)
|
||||
:width width
|
||||
:height height}]
|
||||
]]))))
|
64
frontend/src/app/main/ui/shapes/fills.cljs
Normal file
64
frontend/src/app/main/ui/shapes/fills.cljs
Normal file
|
@ -0,0 +1,64 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.shapes.fills
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.config :as cfg]
|
||||
[app.main.ui.shapes.attrs :as attrs]
|
||||
[app.main.ui.shapes.embed :as embed]
|
||||
[app.main.ui.shapes.gradients :as grad]
|
||||
[app.util.object :as obj]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc fills
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
|
||||
(let [shape (obj/get props "shape")
|
||||
render-id (obj/get props "render-id")
|
||||
{:keys [x y width height]} (:selrect shape)
|
||||
{:keys [metadata]} shape
|
||||
fill-id (str "fill-" render-id)
|
||||
has-image (or metadata (:fill-image shape))
|
||||
uri (if metadata
|
||||
(cfg/resolve-file-media metadata)
|
||||
(cfg/resolve-file-media (:fill-image shape)))
|
||||
embed (embed/use-data-uris [uri])
|
||||
transform (gsh/transform-matrix shape)
|
||||
pattern-attrs (cond-> #js {:id fill-id
|
||||
:patternUnits "userSpaceOnUse"
|
||||
:x x
|
||||
:y y
|
||||
:height height
|
||||
:width width
|
||||
:data-loading (str (not (contains? embed uri)))}
|
||||
(= :path (:type shape))
|
||||
(obj/set! "patternTransform" transform))]
|
||||
|
||||
[:*
|
||||
(for [[index value] (-> (d/enumerate (:fills shape [])) reverse)]
|
||||
(cond (some? (:fill-color-gradient value))
|
||||
(case (:type (:fill-color-gradient value))
|
||||
:linear [:> grad/linear-gradient #js {:id (str (name :fill-color-gradient) "_" render-id "_" index)
|
||||
:gradient (:fill-color-gradient value)
|
||||
:shape shape}]
|
||||
:radial [:> grad/radial-gradient #js {:id (str (name :fill-color-gradient) "_" render-id "_" index)
|
||||
:gradient (:fill-color-gradient value)
|
||||
:shape shape}])))
|
||||
|
||||
[:> :pattern pattern-attrs
|
||||
[:g
|
||||
(for [[index value] (-> (d/enumerate (:fills shape [])) reverse)]
|
||||
[:> :rect (-> (attrs/extract-fill-attrs value index)
|
||||
(obj/set! "width" width)
|
||||
(obj/set! "height" height))])
|
||||
|
||||
(when has-image
|
||||
[:image {:xlinkHref (get embed uri uri)
|
||||
:width width
|
||||
:height height}])]]]))
|
|
@ -51,10 +51,6 @@
|
|||
shape (unchecked-get props "shape")
|
||||
{:keys [x y width height]} shape
|
||||
|
||||
has-background? (or (some? (:fill-color shape))
|
||||
(some? (:fill-color-gradient shape)))
|
||||
has-stroke? (not= :none (:stroke-style shape))
|
||||
|
||||
props (-> (attrs/extract-style-attrs shape)
|
||||
(obj/merge!
|
||||
#js {:x x
|
||||
|
@ -63,8 +59,8 @@
|
|||
:height height
|
||||
:className "frame-background"}))]
|
||||
[:*
|
||||
(when (or has-background? has-stroke?)
|
||||
[:> :rect props])
|
||||
[:> :rect props]
|
||||
|
||||
(for [item childs]
|
||||
[:& shape-wrapper {:shape item
|
||||
:key (:id item)}])])))
|
||||
|
|
|
@ -7,11 +7,8 @@
|
|||
(ns app.main.ui.shapes.image
|
||||
(:require
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.config :as cfg]
|
||||
[app.main.ui.context :as muc]
|
||||
[app.main.ui.shapes.attrs :as attrs]
|
||||
[app.main.ui.shapes.custom-stroke :refer [shape-custom-stroke]]
|
||||
[app.main.ui.shapes.embed :as embed]
|
||||
[app.util.object :as obj]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
|
@ -20,19 +17,8 @@
|
|||
[props]
|
||||
|
||||
(let [shape (unchecked-get props "shape")
|
||||
{:keys [x y width height metadata]} shape
|
||||
uri (cfg/resolve-file-media metadata)
|
||||
embed (embed/use-data-uris [uri])
|
||||
|
||||
{:keys [x y width height]} shape
|
||||
transform (gsh/transform-matrix shape)
|
||||
|
||||
fill-attrs (-> (attrs/extract-fill-attrs shape)
|
||||
(obj/set! "width" width)
|
||||
(obj/set! "height" height))
|
||||
|
||||
render-id (mf/use-ctx muc/render-ctx)
|
||||
fill-image-id (str "fill-image-" render-id)
|
||||
shape (assoc shape :fill-image fill-image-id)
|
||||
props (-> (attrs/extract-style-attrs shape)
|
||||
(obj/merge! (attrs/extract-border-radius-attrs shape))
|
||||
(obj/merge!
|
||||
|
@ -44,19 +30,6 @@
|
|||
path? (some? (.-d props))]
|
||||
|
||||
[:g
|
||||
[:defs
|
||||
[:pattern {:id fill-image-id
|
||||
:patternUnits "userSpaceOnUse"
|
||||
:x x
|
||||
:y y
|
||||
:height height
|
||||
:width width
|
||||
:data-loading (str (not (contains? embed uri)))}
|
||||
[:g
|
||||
[:> :rect fill-attrs]
|
||||
[:image {:xlinkHref (get embed uri uri)
|
||||
:width width
|
||||
:height height}]]]]
|
||||
[:& shape-custom-stroke {:shape shape}
|
||||
(if path?
|
||||
[:> :path props]
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
[app.util.path.format :as upf]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
;; --- Path Shape
|
||||
|
||||
(mf/defc path-shape
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
[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.fills :as fills]
|
||||
[app.main.ui.shapes.filters :as filters]
|
||||
[app.main.ui.shapes.frame :as frame]
|
||||
[app.main.ui.shapes.gradients :as grad]
|
||||
|
@ -63,9 +63,12 @@
|
|||
[:defs
|
||||
[:& defs/svg-defs {:shape shape :render-id render-id}]
|
||||
[:& filters/filters {:shape shape :filter-id filter-id}]
|
||||
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
|
||||
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]
|
||||
[:& fim/fill-image-pattern {:shape shape :render-id render-id}]
|
||||
(when (or (some? (:fill-image shape))
|
||||
(= :image (:type shape))
|
||||
(> (count (:fills shape)) 1)
|
||||
(some :fill-color-gradient (:fills shape)))
|
||||
[:& fills/fills {:shape shape :render-id render-id}])
|
||||
[:& cs/stroke-defs {:shape shape :render-id render-id}]
|
||||
[:& frame/frame-clip-def {:shape shape :render-id render-id}]]
|
||||
children]]))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue