🐛 Add shadow to artboard make it lose the fill

This commit is contained in:
Alejandro Alonso 2022-03-29 09:47:02 +02:00 committed by Alonso Torres
parent e601e2acca
commit 3a9d348cab
10 changed files with 113 additions and 52 deletions

View file

@ -42,6 +42,7 @@
### :bug: Bugs fixed ### :bug: Bugs fixed
- Add shadow to artboard make it lose the fill [Taiga #3139](https://tree.taiga.io/project/penpot/issue/3139)
- Avoid numeric inputs to change its value without focusing them [Taiga #3140](https://tree.taiga.io/project/penpot/issue/3140) - Avoid numeric inputs to change its value without focusing them [Taiga #3140](https://tree.taiga.io/project/penpot/issue/3140)
- Fix comments modal when changing pages [Taiga #2597](https://tree.taiga.io/project/penpot/issue/2508) - Fix comments modal when changing pages [Taiga #2597](https://tree.taiga.io/project/penpot/issue/2508)
- Copy paste inside a text layer leaves pasted text transparent [Taiga #3096](https://tree.taiga.io/project/penpot/issue/3096) - Copy paste inside a text layer leaves pasted text transparent [Taiga #3096](https://tree.taiga.io/project/penpot/issue/3096)

View file

@ -33,10 +33,10 @@
(let [xf-get-bounds (comp (map #(get objects %)) (map #(calc-bounds % objects))) (let [xf-get-bounds (comp (map #(get objects %)) (map #(calc-bounds % objects)))
padding (filters/calculate-padding object) padding (filters/calculate-padding object)
obj-bounds (-> (filters/get-filters-bounds object) obj-bounds (-> (filters/get-filters-bounds object)
(update :x - padding) (update :x - (:horizontal padding))
(update :y - padding) (update :y - (:vertical padding))
(update :width + (* 2 padding)) (update :width + (* 2 (:horizontal padding)))
(update :height + (* 2 padding)))] (update :height + (* 2 (:vertical padding))))]
(cond (cond
(and (= :group (:type object)) (and (= :group (:type object))

View file

@ -9,6 +9,7 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.pages.helpers :as cph]
[app.main.ui.context :as muc] [app.main.ui.context :as muc]
[app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.attrs :as attrs]
[app.main.ui.shapes.gradients :as grad] [app.main.ui.shapes.gradients :as grad]
@ -327,8 +328,12 @@
(obj/clone)) (obj/clone))
props (cond-> props props (cond-> props
(d/not-empty? (:shadow shape)) (or
(obj/set! "filter" (dm/fmt "url(#filter_%)" render-id))) ;; There are any shadows
(and (d/not-empty? (:shadow shape)) (not (cph/frame-shape? shape)))
;; There are no strokes and a blur
(and (some? (:blur shape)) (not (cph/frame-shape? shape)) (empty? (:strokes shape))))
(obj/set! "filter" (dm/fmt "url(#filter_%)" render-id)))
svg-defs (:svg-defs shape {}) svg-defs (:svg-defs shape {})
svg-attrs (:svg-attrs shape {}) svg-attrs (:svg-attrs shape {})
@ -391,7 +396,19 @@
(obj/set! "fillOpacity" "none"))) (obj/set! "fillOpacity" "none")))
(add-style (obj/get (attrs/extract-stroke-attrs value position render-id) "style"))))) (add-style (obj/get (attrs/extract-stroke-attrs value position render-id) "style")))))
(mf/defc shape-custom-strokes
(mf/defc shape-fills
{::mf/wrap-props false}
[props]
(let [child (obj/get props "children")
shape (obj/get props "shape")
elem-name (obj/get child "type")
render-id (mf/use-ctx muc/render-ctx)]
[:g {:id (dm/fmt "fills-%" (:id shape))}
[:> elem-name (build-fill-props shape child render-id)]]))
(mf/defc shape-strokes
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [child (obj/get props "children") (let [child (obj/get props "children")
@ -401,13 +418,9 @@
stroke-props (-> (obj/new) stroke-props (-> (obj/new)
(obj/set! "id" (dm/fmt "strokes-%" (:id shape))) (obj/set! "id" (dm/fmt "strokes-%" (:id shape)))
(cond-> (cond->
(some? (:blur shape)) (and (some? (:blur shape)) (not (cph/frame-shape? shape)))
(obj/set! "filter" (dm/fmt "url(#filter_blur_%)" render-id))))] (obj/set! "filter" (dm/fmt "url(#filter_blur_%)" render-id))))]
[:* [:*
[:g {:id (dm/fmt "fills-%" (:id shape))}
[:> elem-name (build-fill-props shape child render-id)]]
(when (when
(d/not-empty? (:strokes shape)) (d/not-empty? (:strokes shape))
[:> :g stroke-props [:> :g stroke-props
@ -416,3 +429,16 @@
shape (assoc value :points (:points shape))] shape (assoc value :points (:points shape))]
[:& shape-custom-stroke {:shape shape :index index} [:& shape-custom-stroke {:shape shape :index index}
[:> elem-name props]]))])])) [:> elem-name props]]))])]))
(mf/defc shape-custom-strokes
{::mf/wrap-props false}
[props]
(let [child (obj/get props "children")
shape (obj/get props "shape")]
[:*
[:& shape-fills {:shape shape}
child]
[:& shape-strokes {:shape shape}
child]]))

View file

@ -170,7 +170,6 @@
([shape filters blur-value] ([shape filters blur-value]
(let [svg-root? (and (= :svg-raw (:type shape)) (not= :svg (get-in shape [:content :tag]))) (let [svg-root? (and (= :svg-raw (:type shape)) (not= :svg (get-in shape [:content :tag])))
frame? (= :frame (:type shape))
{:keys [x y width height]} (:selrect shape)] {:keys [x y width height]} (:selrect shape)]
(if svg-root? (if svg-root?
;; When is a raw-svg but not the root we use the whole svg as bound for the filter. Is the maximum ;; When is a raw-svg but not the root we use the whole svg as bound for the filter. Is the maximum
@ -183,6 +182,7 @@
(map (partial filter-bounds shape))) (map (partial filter-bounds shape)))
;; We add the selrect so the minimum size will be the selrect ;; We add the selrect so the minimum size will be the selrect
filter-bounds (conj filter-bounds (-> shape :points gsh/points->selrect)) filter-bounds (conj filter-bounds (-> shape :points gsh/points->selrect))
x1 (apply min (map :x1 filter-bounds)) x1 (apply min (map :x1 filter-bounds))
y1 (apply min (map :y1 filter-bounds)) y1 (apply min (map :y1 filter-bounds))
x2 (apply max (map :x2 filter-bounds)) x2 (apply max (map :x2 filter-bounds))
@ -195,18 +195,30 @@
;; We should move the frame filter coordinates because they should be ;; We should move the frame filter coordinates because they should be
;; relative with the frame. By default they come as absolute ;; relative with the frame. By default they come as absolute
{:x (if frame? (- x1 x) x1) {:x x1
:y (if frame? (- y1 y) y1) :y y1
:width (- x2 x1) :width (- x2 x1)
:height (- y2 y1)}))))) :height (- y2 y1)})))))
(defn calculate-padding [shape] (defn calculate-padding [shape]
(let [stroke-width (apply max 0 (map #(case (:stroke-alignment % :center) (let [stroke-width (apply max 0 (map #(case (:stroke-alignment % :center)
:center (/ (:stroke-width % 0) 2) :center (/ (:stroke-width % 0) 2)
:outer (:stroke-width % 0) :outer (:stroke-width % 0)
0) (:strokes shape))) 0) (:strokes shape)))
margin (apply max 0 (map #(gsh/shape-stroke-margin % stroke-width) (:strokes shape)))]
(+ stroke-width margin))) margin (apply max 0 (map #(gsh/shape-stroke-margin % stroke-width) (:strokes shape)))
shadow-width (apply max 0 (map #(case (:style % :drop-shadow)
:drop-shadow (+ (mth/abs (:offset-x %)) (* (:spread %) 2) (* (:blur %) 2) 10)
0) (:shadow shape)))
shadow-height (apply max 0 (map #(case (:style % :drop-shadow)
:drop-shadow (+ (mth/abs (:offset-y %)) (* (:spread %) 2) (* (:blur %) 2) 10)
0) (:shadow shape)))]
{:horizontal (+ stroke-width margin shadow-width)
:vertical (+ stroke-width margin shadow-height)}))
(defn change-filter-in (defn change-filter-in
"Adds the previous filter as `filter-in` parameter" "Adds the previous filter as `filter-in` parameter"
@ -220,10 +232,10 @@
bounds (get-filters-bounds shape filters (or (-> shape :blur :value) 0)) bounds (get-filters-bounds shape filters (or (-> shape :blur :value) 0))
padding (calculate-padding shape) padding (calculate-padding shape)
selrect (:selrect shape) selrect (:selrect shape)
filter-x (/ (- (:x bounds) (:x selrect) padding) (:width selrect)) filter-x (/ (- (:x bounds) (:x selrect) (:horizontal padding)) (:width selrect))
filter-y (/ (- (:y bounds) (:y selrect) padding) (:height selrect)) filter-y (/ (- (:y bounds) (:y selrect) (:vertical padding)) (:height selrect))
filter-width (/ (+ (:width bounds) (* 2 padding)) (:width selrect)) filter-width (/ (+ (:width bounds) (* 2 (:horizontal padding))) (:width selrect))
filter-height (/ (+ (:height bounds) (* 2 padding)) (:height selrect))] filter-height (/ (+ (:height bounds) (* 2 (:vertical padding))) (:height selrect))]
(when (> (count filters) 2) (when (> (count filters) 2)
[:filter {:id filter-id [:filter {:id filter-id
:x filter-x :x filter-x

View file

@ -7,9 +7,10 @@
(ns app.main.ui.shapes.frame (ns app.main.ui.shapes.frame
(:require (:require
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.geom.shapes :as gsh]
[app.main.ui.context :as muc]
[app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.attrs :as attrs]
[app.main.ui.shapes.custom-stroke :refer [shape-custom-strokes]] [app.main.ui.shapes.custom-stroke :refer [shape-fills shape-strokes]]
[app.main.ui.shapes.filters :as filters]
[app.util.object :as obj] [app.util.object :as obj]
[debug :refer [debug?]] [debug :refer [debug?]]
[rumext.alpha :as mf])) [rumext.alpha :as mf]))
@ -27,13 +28,12 @@
[{:keys [shape render-id]}] [{:keys [shape render-id]}]
(when (= :frame (:type shape)) (when (= :frame (:type shape))
(let [{:keys [x y width height]} shape (let [{:keys [x y width height]} shape
padding (filters/calculate-padding shape)
props (-> (attrs/extract-style-attrs shape) props (-> (attrs/extract-style-attrs shape)
(obj/merge! (obj/merge!
#js {:x (- x padding) #js {:x x
:y (- y padding) :y y
:width (+ width (* 2 padding)) :width width
:height (+ height (* 2 padding))})) :height height}))
path? (some? (.-d props))] path? (some? (.-d props))]
[:clipPath {:id (frame-clip-id shape render-id) :class "frame-clip"} [:clipPath {:id (frame-clip-id shape render-id) :class "frame-clip"}
(if path? (if path?
@ -63,22 +63,32 @@
(let [childs (unchecked-get props "childs") (let [childs (unchecked-get props "childs")
shape (unchecked-get props "shape") shape (unchecked-get props "shape")
{:keys [x y width height]} shape {:keys [x y width height]} shape
transform (gsh/transform-matrix shape)
props (-> (attrs/extract-style-attrs shape) props (-> (attrs/extract-style-attrs shape)
(obj/merge! (obj/merge!
#js {:x x #js {:x x
:y y :y y
:transform transform
:width width :width width
:height height :height height
:className "frame-background"})) :className "frame-background"}))
path? (some? (.-d props))] path? (some? (.-d props))
render-id (mf/use-ctx muc/render-ctx)]
[:* [:*
[:& shape-custom-strokes {:shape shape} [:g {:clip-path (frame-clip-url shape render-id)}
(if path? [:*
[:> :path props] [:& shape-fills {:shape shape}
[:> :rect props])] (if path?
(for [item childs] [:> :path props]
[:& shape-wrapper {:shape item [:> :rect props])]
:key (dm/str (:id item))}])])))
(for [item childs]
[:& shape-wrapper {:shape item
:key (dm/str (:id item))}])
[:& shape-strokes {:shape shape}
(if path?
[:> :path props]
[:> :rect props])]]]])))

View file

@ -50,14 +50,11 @@
wrapper-props wrapper-props
(cond-> wrapper-props (cond-> wrapper-props
(some #(= (:type shape) %) [:group :svg-raw]) (some #(= (:type shape) %) [:group :svg-raw :frame])
(obj/set! "filter" (filters/filter-str filter-id shape))) (obj/set! "filter" (filters/filter-str filter-id shape)))
wrapper-props wrapper-props
(cond-> wrapper-props (cond-> wrapper-props
(= :frame type)
(obj/set! "clipPath" (frame/frame-clip-url shape render-id))
(= :group type) (= :group type)
(attrs/add-style-attrs shape render-id))] (attrs/add-style-attrs shape render-id))]

View file

@ -32,12 +32,17 @@
(defn- calculate-size (defn- calculate-size
[frame zoom] [frame zoom]
(let [{:keys [_ _ width height]} (filters/get-filters-bounds frame)] (let [{:keys [_ _ width height]} (filters/get-filters-bounds frame)
padding (filters/calculate-padding frame)
x (- (:horizontal padding))
y (- (:vertical padding))
width (+ width (* 2 (:horizontal padding)))
height (+ height (* 2 (:vertical padding)))]
{:base-width width {:base-width width
:base-height height :base-height height
:width (* width zoom) :width (* width zoom)
:height (* height zoom) :height (* height zoom)
:vbox (str "0 0 " width " " height)})) :vbox (str x " " y " " width " " height)}))
(defn- calculate-wrapper (defn- calculate-wrapper
[size1 size2 zoom] [size1 size2 zoom]

View file

@ -21,7 +21,7 @@
(def type->options (def type->options
{:multiple [:fill :stroke :image :text :shadow :blur] {:multiple [:fill :stroke :image :text :shadow :blur]
:frame [:layout :fill :stroke] :frame [:layout :fill :stroke :shadow :blur]
:group [:layout :svg] :group [:layout :svg]
:rect [:layout :fill :stroke :shadow :blur :svg] :rect [:layout :fill :stroke :shadow :blur :svg]
:circle [:layout :fill :stroke :shadow :blur :svg] :circle [:layout :fill :stroke :shadow :blur :svg]

View file

@ -13,6 +13,7 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.shapes.bool :as bool] [app.main.ui.shapes.bool :as bool]
[app.main.ui.shapes.circle :as circle] [app.main.ui.shapes.circle :as circle]
[app.main.ui.shapes.filters :as filters]
[app.main.ui.shapes.frame :as frame] [app.main.ui.shapes.frame :as frame]
[app.main.ui.shapes.group :as group] [app.main.ui.shapes.group :as group]
[app.main.ui.shapes.image :as image] [app.main.ui.shapes.image :as image]
@ -190,9 +191,18 @@
frame (get objects (:id frame)) frame (get objects (:id frame))
zoom (:zoom local 1) zoom (:zoom local 1)
width (* (:width frame) zoom)
height (* (:height frame) zoom) {:keys [_ _ width height]} (filters/get-filters-bounds frame)
vbox (str "0 0 " (:width frame 0) " " (:height frame 0)) padding (filters/calculate-padding frame)
x (- (:horizontal padding))
y (- (:vertical padding))
width (+ width (* 2 (:horizontal padding)))
height (+ height (* 2 (:vertical padding)))
vbox (str x " " y " " width " " height)
width (* width zoom)
height (* height zoom)
render (mf/use-memo render (mf/use-memo
(mf/deps objects) (mf/deps objects)

View file

@ -403,9 +403,9 @@
modifier-ids (into [frame-id] (cph/get-children-ids objects frame-id)) modifier-ids (into [frame-id] (cph/get-children-ids objects frame-id))
objects (reduce update-fn objects modifier-ids) objects (reduce update-fn objects modifier-ids)
frame (assoc-in frame [:modifiers :displacement] modifier) frame (assoc-in frame [:modifiers :displacement] modifier)
width (* (:width frame) zoom) width (* (:width frame) zoom)
height (* (:height frame) zoom) height (* (:height frame) zoom)
vbox (str "0 0 " (:width frame 0) vbox (str "0 0 " (:width frame 0)
" " (:height frame 0)) " " (:height frame 0))
wrapper (mf/use-memo wrapper (mf/use-memo