0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-25 14:11:33 -05:00

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

View file

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

View file

@ -9,6 +9,7 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.shapes :as gsh]
[app.common.pages.helpers :as cph]
[app.main.ui.context :as muc]
[app.main.ui.shapes.attrs :as attrs]
[app.main.ui.shapes.gradients :as grad]
@ -327,8 +328,12 @@
(obj/clone))
props (cond-> props
(d/not-empty? (:shadow shape))
(obj/set! "filter" (dm/fmt "url(#filter_%)" render-id)))
(or
;; 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-attrs (:svg-attrs shape {})
@ -391,7 +396,19 @@
(obj/set! "fillOpacity" "none")))
(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}
[props]
(let [child (obj/get props "children")
@ -401,13 +418,9 @@
stroke-props (-> (obj/new)
(obj/set! "id" (dm/fmt "strokes-%" (:id shape)))
(cond->
(some? (:blur shape))
(and (some? (:blur shape)) (not (cph/frame-shape? shape)))
(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
(d/not-empty? (:strokes shape))
[:> :g stroke-props
@ -416,3 +429,16 @@
shape (assoc value :points (:points shape))]
[:& shape-custom-stroke {:shape shape :index index}
[:> 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]
(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)]
(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
@ -183,6 +182,7 @@
(map (partial filter-bounds shape)))
;; We add the selrect so the minimum size will be the selrect
filter-bounds (conj filter-bounds (-> shape :points gsh/points->selrect))
x1 (apply min (map :x1 filter-bounds))
y1 (apply min (map :y1 filter-bounds))
x2 (apply max (map :x2 filter-bounds))
@ -195,18 +195,30 @@
;; We should move the frame filter coordinates because they should be
;; relative with the frame. By default they come as absolute
{:x (if frame? (- x1 x) x1)
:y (if frame? (- y1 y) y1)
{:x x1
:y y1
:width (- x2 x1)
:height (- y2 y1)})))))
(defn calculate-padding [shape]
(let [stroke-width (apply max 0 (map #(case (:stroke-alignment % :center)
:center (/ (:stroke-width % 0) 2)
:outer (:stroke-width % 0)
0) (:strokes shape)))
margin (apply max 0 (map #(gsh/shape-stroke-margin % stroke-width) (:strokes shape)))]
(+ stroke-width margin)))
:center (/ (:stroke-width % 0) 2)
:outer (:stroke-width % 0)
0) (:strokes shape)))
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
"Adds the previous filter as `filter-in` parameter"
@ -220,10 +232,10 @@
bounds (get-filters-bounds shape filters (or (-> shape :blur :value) 0))
padding (calculate-padding shape)
selrect (:selrect shape)
filter-x (/ (- (:x bounds) (:x selrect) padding) (:width selrect))
filter-y (/ (- (:y bounds) (:y selrect) padding) (:height selrect))
filter-width (/ (+ (:width bounds) (* 2 padding)) (:width selrect))
filter-height (/ (+ (:height bounds) (* 2 padding)) (:height selrect))]
filter-x (/ (- (:x bounds) (:x selrect) (:horizontal padding)) (:width selrect))
filter-y (/ (- (:y bounds) (:y selrect) (:vertical padding)) (:height selrect))
filter-width (/ (+ (:width bounds) (* 2 (:horizontal padding))) (:width selrect))
filter-height (/ (+ (:height bounds) (* 2 (:vertical padding))) (:height selrect))]
(when (> (count filters) 2)
[:filter {:id filter-id
:x filter-x

View file

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

View file

@ -32,12 +32,17 @@
(defn- calculate-size
[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-height height
:width (* width zoom)
:height (* height zoom)
:vbox (str "0 0 " width " " height)}))
:vbox (str x " " y " " width " " height)}))
(defn- calculate-wrapper
[size1 size2 zoom]

View file

@ -21,7 +21,7 @@
(def type->options
{:multiple [:fill :stroke :image :text :shadow :blur]
:frame [:layout :fill :stroke]
:frame [:layout :fill :stroke :shadow :blur]
:group [:layout :svg]
:rect [: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.ui.shapes.bool :as bool]
[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.group :as group]
[app.main.ui.shapes.image :as image]
@ -190,9 +191,18 @@
frame (get objects (:id frame))
zoom (:zoom local 1)
width (* (:width frame) zoom)
height (* (:height frame) zoom)
vbox (str "0 0 " (:width frame 0) " " (:height frame 0))
{: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)))
vbox (str x " " y " " width " " height)
width (* width zoom)
height (* height zoom)
render (mf/use-memo
(mf/deps objects)

View file

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