0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-08 16:00:19 -05:00

🐛 Fix shadows when exporting groups

This commit is contained in:
alonso.torres 2021-03-29 12:16:14 +02:00 committed by Andrey Antukh
parent a14890f163
commit 0f6ce233bd
3 changed files with 85 additions and 66 deletions

View file

@ -63,6 +63,7 @@
- Fix issue when promoting to owner [Taiga #1494](https://tree.taiga.io/project/penpot/issue/1494)
- Fix cannot click on blocked elements in viewer [Taiga #1430](https://tree.taiga.io/project/penpot/issue/1430)
- Fix SVG not showing properties at code [Taiga #1437](https://tree.taiga.io/project/penpot/issue/1437)
- Fix shadows when exporting groups [Taiga #1495](https://tree.taiga.io/project/penpot/issue/1495)
### :arrow_up: Deps updates

View file

@ -9,18 +9,21 @@
(ns app.main.ui.render
(:require
[cljs.spec.alpha :as s]
[beicon.core :as rx]
[rumext.alpha :as mf]
[app.common.uuid :as uuid]
[app.common.pages :as cp]
[app.common.math :as mth]
[app.common.geom.shapes :as geom]
[app.common.geom.point :as gpt]
[app.common.geom.matrix :as gmt]
[app.main.ui.context :as muc]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.uuid :as uuid]
[app.main.exports :as exports]
[app.main.repo :as repo]))
[app.main.repo :as repo]
[app.main.ui.context :as muc]
[app.main.ui.shapes.filters :as filters]
[app.main.ui.shapes.shape :refer [shape-container]]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
(mf/defc object-svg
{::mf/wrap [mf/memo]}
@ -37,18 +40,23 @@
mod-ids (cons frame-id (cp/get-children frame-id objects))
updt-fn #(-> %1
(assoc-in [%2 :modifiers :displacement] modifier)
(update %2 geom/transform-shape))
(update %2 gsh/transform-shape))
objects (reduce updt-fn objects mod-ids)
object (get objects object-id)
width (* (get-in object [:selrect :width]) zoom)
height (* (get-in object [:selrect :height]) zoom)
vbox (str (get-in object [:selrect :x]) " "
(get-in object [:selrect :y]) " "
(get-in object [:selrect :width]) " "
(get-in object [:selrect :height]))
{:keys [width height]} (gsh/points->selrect (:points object))
;; We need to get the shadows/blurs paddings to create the viewbox properly
{:keys [x y width height]} (filters/get-filters-bounds object)
x (* x zoom)
y (* y zoom)
width (* width zoom)
height (* height zoom)
vbox (str/join " " [x y width height])
frame-wrapper
(mf/use-memo
@ -76,7 +84,8 @@
:xmlns "http://www.w3.org/2000/svg"}
(case (:type object)
:frame [:& frame-wrapper {:shape object :view-box vbox}]
:group [:& group-wrapper {:shape object}]
:group [:> shape-container {:shape object}
[:& group-wrapper {:shape object}]]
[:& shape-wrapper {:shape object}])]]))
(defn- adapt-root-frame
@ -84,9 +93,9 @@
(if (uuid/zero? object-id)
(let [object (get objects object-id)
shapes (cp/select-toplevel-shapes objects {:include-frames? true})
srect (geom/selection-rect shapes)
srect (gsh/selection-rect shapes)
object (merge object (select-keys srect [:x :y :width :height]))
object (geom/transform-shape object)
object (gsh/transform-shape object)
object (assoc object :fill-color "#f0f0f0")]
(assoc objects (:id object) object))
objects))

View file

@ -122,8 +122,56 @@
:x2 (+ filter-x filter-width)
:y2 (+ filter-y filter-height)}))
(defn blur-filters [type value]
(->> [value]
(remove :hidden)
(filter #(= (:type %) type))
(map #(hash-map :id (str "filter_" (:id %))
:type (:type %)
:params %))))
(defn shadow-filters [type filters]
(->> filters
(remove :hidden)
(filter #(= (:style %) type))
(map #(hash-map :id (str "filter_" (:id %))
:type (:style %)
:params %))))
(mf/defc filter-entry [{:keys [entry]}]
(let [props #js {:filter-id (:id entry)
:filter-in (:filter-in entry)
:params (:params entry)}]
(case (:type entry)
:drop-shadow [:> drop-shadow-filter props]
:inner-shadow [:> inner-shadow-filter props]
:background-blur [:> background-blur-filter props]
:layer-blur [:> layer-blur-filter props]
:image-fix [:> image-fix-filter props]
:blend-filters [:> blend-filters props])))
(defn shape->filters
[shape]
(d/concat
[]
[{:id "BackgroundImageFix" :type :image-fix}]
;; Background blur won't work in current SVG specification
;; We can revisit this in the future
#_(->> shape :blur (blur-filters :background-blur))
(->> shape :shadow (shadow-filters :drop-shadow))
[{:id "shape" :type :blend-filters}]
(->> shape :shadow (shadow-filters :inner-shadow))
(->> shape :blur (blur-filters :layer-blur))))
(defn get-filters-bounds
[shape filters blur-value]
([shape]
(let [filters (shape->filters shape)
blur-value (or (-> shape :blur :value) 0)]
(get-filters-bounds shape filters blur-value)))
([shape filters blur-value]
(let [svg-root? (and (= :svg-raw (:type shape)) (not= :svg (get-in shape [:content :tag])))
frame? (= :frame (:type shape))
@ -154,51 +202,12 @@
{:x (if frame? (- x1 x) x1)
:y (if frame? (- y1 y) y1)
:width (- x2 x1)
:height (- y2 y1)}))))
(defn blur-filters [type value]
(->> [value]
(remove :hidden)
(filter #(= (:type %) type))
(map #(hash-map :id (str "filter_" (:id %))
:type (:type %)
:params %))))
(defn shadow-filters [type filters]
(->> filters
(remove :hidden)
(filter #(= (:style %) type))
(map #(hash-map :id (str "filter_" (:id %))
:type (:style %)
:params %))))
(mf/defc filter-entry [{:keys [entry]}]
(let [props #js {:filter-id (:id entry)
:filter-in (:filter-in entry)
:params (:params entry)}]
(case (:type entry)
:drop-shadow [:> drop-shadow-filter props]
:inner-shadow [:> inner-shadow-filter props]
:background-blur [:> background-blur-filter props]
:layer-blur [:> layer-blur-filter props]
:image-fix [:> image-fix-filter props]
:blend-filters [:> blend-filters props])))
:height (- y2 y1)})))))
(mf/defc filters
[{:keys [filter-id shape]}]
(let [filters (d/concat
[]
[{:id "BackgroundImageFix" :type :image-fix}]
;; Background blur won't work in current SVG specification
;; We can revisit this in the future
#_(->> shape :blur (blur-filters :background-blur))
(->> shape :shadow (shadow-filters :drop-shadow))
[{:id "shape" :type :blend-filters}]
(->> shape :shadow (shadow-filters :inner-shadow))
(->> shape :blur (blur-filters :layer-blur)))
(let [filters (shape->filters shape)
;; Adds the previous filter as `filter-in` parameter
filters (map #(assoc %1 :filter-in %2) filters (cons nil (map :id filters)))