mirror of
https://github.com/penpot/penpot.git
synced 2026-07-22 22:17:58 +00:00
🎉 Add background blur (#10034)
* 🎉 Add background blur * 🎉 Add test * 🎉 Add background blur info to plugins API * 🎉 Suport in wasm for both layer and background blur * 🐛 Fix failing test * ♻️ Fix comments --------- Co-authored-by: alonso.torres <alonso.torres@kaleidos.net>
This commit is contained in:
parent
b391a4c8d3
commit
2a098e5b16
@ -38,13 +38,10 @@
|
||||
(d/concat-vec
|
||||
[{:id "BackgroundImageFix" :type :image-fix}]
|
||||
|
||||
;; Background blur won't work in current SVG specification
|
||||
;; We can revisit this in the future
|
||||
#_(->> shape :blur (into []) (blur-filters :background-blur))
|
||||
|
||||
(->> shape :shadow (apply-filters :style :drop-shadow))
|
||||
[{:id "shape" :type :blend-filters}]
|
||||
(->> shape :shadow (apply-filters :style :inner-shadow))
|
||||
|
||||
(->> shape :blur list (apply-filters :type :layer-blur))))
|
||||
|
||||
(defn- calculate-filter-bounds
|
||||
@ -100,17 +97,13 @@
|
||||
;; shapes because selrect stores the unrotated rectangle, not the screen-space bbox.
|
||||
(and (empty? (-> shape :shadow))
|
||||
(or (nil? (:blur shape))
|
||||
(not= :layer-blur (-> shape :blur :type))
|
||||
(zero? (-> shape :blur :value (or 0)))))
|
||||
(-> (dm/get-prop shape :points)
|
||||
(grc/points->rect))
|
||||
|
||||
:else
|
||||
(let [filters (shape->filters shape)
|
||||
blur-value (case (-> shape :blur :type)
|
||||
:layer-blur (or (-> shape :blur :value) 0)
|
||||
:background-blur 0
|
||||
0)
|
||||
blur-value (or (-> shape :blur :value) 0)
|
||||
srect (-> (dm/get-prop shape :points)
|
||||
(grc/points->rect))]
|
||||
(get-rect-filter-bounds srect filters blur-value ignore-shadow-margin?)))))
|
||||
@ -242,10 +235,7 @@
|
||||
(not (cfh/frame-shape? shape)) (or (:children-bounds shape)))
|
||||
|
||||
filters (shape->filters shape)
|
||||
blur-value (case (-> shape :blur :type)
|
||||
:layer-blur (or (-> shape :blur :value) 0)
|
||||
:background-blur 0
|
||||
0)]
|
||||
blur-value (or (-> shape :blur :value) 0)]
|
||||
|
||||
(get-rect-filter-bounds children-bounds filters blur-value ignore-shadow-margin?))))
|
||||
|
||||
|
||||
@ -24,3 +24,7 @@
|
||||
[shape scale]
|
||||
(update-in shape [:blur :value] * scale))
|
||||
|
||||
(defn update-background-blur-scale
|
||||
[shape scale]
|
||||
(update-in shape [:background-blur :value] * scale))
|
||||
|
||||
|
||||
@ -91,6 +91,7 @@
|
||||
:blend-mode :layer-effects-group
|
||||
:shadow :shadow-group
|
||||
:blur :blur-group
|
||||
:background-blur :blur-group
|
||||
:masked-group :mask-group
|
||||
:constraints-h :constraints-group
|
||||
:constraints-v :constraints-group
|
||||
|
||||
@ -692,6 +692,9 @@
|
||||
(some? (:blur shape))
|
||||
(gse/update-blur-scale value)
|
||||
|
||||
(some? (:background-blur shape))
|
||||
(gse/update-background-blur-scale value)
|
||||
|
||||
(ctl/flex-layout? shape)
|
||||
(ctl/update-flex-scale value)
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
fills)))
|
||||
|
||||
(def group-style-properties
|
||||
#{:shadow :blur})
|
||||
#{:shadow :blur :background-blur})
|
||||
|
||||
;; FIXME: revisit
|
||||
(def style-properties
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
[app.common.types.path :as path]
|
||||
[app.common.types.plugins :as ctpg]
|
||||
[app.common.types.shape.attrs :refer [default-color]]
|
||||
[app.common.types.shape.background-blur :as ctsbb]
|
||||
[app.common.types.shape.blur :as ctsb]
|
||||
[app.common.types.shape.export :as ctse]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
@ -222,6 +223,7 @@
|
||||
[:shadow {:optional true}
|
||||
[:vector {:gen/max 1} ctss/schema:shadow]]
|
||||
[:blur {:optional true} ctsb/schema:blur]
|
||||
[:background-blur {:optional true} ctsbb/schema:background-blur]
|
||||
[:grow-type {:optional true}
|
||||
[::sm/one-of grow-types]]
|
||||
[:applied-tokens {:optional true} cto/schema:applied-tokens]
|
||||
@ -415,7 +417,7 @@
|
||||
:remote-synced :shape-ref :touched :blocked :collapsed :locked
|
||||
:hidden :masked-group :fills :proportion :proportion-lock :constraints-h
|
||||
:constraints-v :fixed-scroll :r1 :r2 :r3 :r4 :rotation :opacity :grids :exports
|
||||
:strokes :blend-mode :interactions :shadow :blur :grow-type :applied-tokens
|
||||
:strokes :blend-mode :interactions :shadow :blur :background-blur :grow-type :applied-tokens
|
||||
:plugin-data})
|
||||
|
||||
(def ^:private allowed-shape-geom-attrs #{:x :y :width :height})
|
||||
@ -657,6 +659,7 @@
|
||||
;; - Contraints
|
||||
;; - Shadow
|
||||
;; - Blur
|
||||
;; - Background blur
|
||||
;; - Border radius
|
||||
(def ^:private basic-extract-props
|
||||
#{:fills
|
||||
@ -681,6 +684,7 @@
|
||||
|
||||
:shadow
|
||||
:blur
|
||||
:background-blur
|
||||
|
||||
;; Radius
|
||||
:r1
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
:shadow
|
||||
|
||||
:blur
|
||||
:background-blur
|
||||
|
||||
:fills
|
||||
:fill-color
|
||||
@ -108,6 +109,7 @@
|
||||
:shadow
|
||||
|
||||
:blur
|
||||
:background-blur
|
||||
|
||||
:exports
|
||||
|
||||
@ -166,6 +168,7 @@
|
||||
:shadow
|
||||
|
||||
:blur
|
||||
:background-blur
|
||||
|
||||
:exports
|
||||
|
||||
@ -223,6 +226,7 @@
|
||||
:shadow
|
||||
|
||||
:blur
|
||||
:background-blur
|
||||
|
||||
:exports
|
||||
|
||||
@ -280,6 +284,7 @@
|
||||
:shadow
|
||||
|
||||
:blur
|
||||
:background-blur
|
||||
|
||||
:exports
|
||||
|
||||
@ -336,6 +341,7 @@
|
||||
:shadow
|
||||
|
||||
:blur
|
||||
:background-blur
|
||||
|
||||
:typography-ref-id
|
||||
:typography-ref-file
|
||||
@ -398,6 +404,7 @@
|
||||
:shadow
|
||||
|
||||
:blur
|
||||
:background-blur
|
||||
|
||||
:exports
|
||||
|
||||
@ -456,6 +463,7 @@
|
||||
:shadow
|
||||
|
||||
:blur
|
||||
:background-blur
|
||||
|
||||
:exports
|
||||
|
||||
@ -513,6 +521,7 @@
|
||||
:shadow
|
||||
|
||||
:blur
|
||||
:background-blur
|
||||
|
||||
:exports
|
||||
|
||||
|
||||
16
common/src/app/common/types/shape/background_blur.cljc
Normal file
16
common/src/app/common/types/shape/background_blur.cljc
Normal file
@ -0,0 +1,16 @@
|
||||
;; 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) KALEIDOS INC Sucursal en España SL
|
||||
|
||||
(ns app.common.types.shape.background-blur
|
||||
(:require
|
||||
[app.common.schema :as sm]))
|
||||
|
||||
(def schema:background-blur
|
||||
[:map {:title "BackgroundBlur"}
|
||||
[:id ::sm/uuid]
|
||||
[:type [:enum :background-blur]]
|
||||
[:value ::sm/safe-number]
|
||||
[:hidden :boolean]])
|
||||
@ -8,12 +8,9 @@
|
||||
(:require
|
||||
[app.common.schema :as sm]))
|
||||
|
||||
(def schema:blur-type
|
||||
[:enum :layer-blur :background-blur])
|
||||
|
||||
(def schema:blur
|
||||
[:map {:title "Blur"}
|
||||
[:id ::sm/uuid]
|
||||
[:type schema:blur-type]
|
||||
[:type [:enum :layer-blur]]
|
||||
[:value ::sm/safe-number]
|
||||
[:hidden :boolean]])
|
||||
|
||||
@ -123,12 +123,12 @@
|
||||
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~u11813dac-4dc3-80d8-8007-b2804a521773\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14ac\",\"~u11813dac-4dc3-80d8-8007-b28053db9865\",\"~u11813dac-4dc3-80d8-8007-b2806dfd8a36\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14a4\",\"~u5b58e018-fa5e-805d-8007-b27294ad5af1\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14a7\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14af\",\"~u11813dac-4dc3-80d8-8007-b28053db9864\",\"~u11813dac-4dc3-80d8-8007-b2806dfde19d\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14aa\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14ab\"]]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b2806dfd8a36": "[\"~#shape\",[\"^ \",\"~:y\",93.99999856948853,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:index\",2,\"~:name\",\"Group\",\"~:width\",303,\"~:type\",\"~:group\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1307.9999368190765,\"~:y\",93.99999856948853]],[\"^:\",[\"^ \",\"~:x\",1610.9999368190765,\"~:y\",93.99999856948853]],[\"^:\",[\"^ \",\"~:x\",1610.9999368190765,\"~:y\",396.9999985694885]],[\"^:\",[\"^ \",\"~:x\",1307.9999368190765,\"~:y\",396.9999985694885]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u11813dac-4dc3-80d8-8007-b2806dfd8a36\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",1307.9999368190765,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1307.9999368190765,\"~:y\",93.99999856948853,\"^6\",303,\"~:height\",303,\"~:x1\",1307.9999368190765,\"~:y1\",93.99999856948853,\"~:x2\",1610.9999368190765,\"~:y2\",396.9999985694885]],\"~:fills\",[],\"~:flip-x\",null,\"^D\",303,\"~:flip-y\",null,\"~:shapes\",[\"~u11813dac-4dc3-80d8-8007-b2806dfd8a37\",\"~u11813dac-4dc3-80d8-8007-b2806dfde19c\"]]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b2806dfd8a37": "[\"~#shape\",[\"^ \",\"~:y\",93.99999856948853,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Ellipse\",\"~:width\",194,\"~:type\",\"~:circle\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1416.9999368190765,\"~:y\",93.99999856948853]],[\"^<\",[\"^ \",\"~:x\",1610.9999368190765,\"~:y\",93.99999856948853]],[\"^<\",[\"^ \",\"~:x\",1610.9999368190765,\"~:y\",293.9999985694885]],[\"^<\",[\"^ \",\"~:x\",1416.9999368190765,\"~:y\",293.9999985694885]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u11813dac-4dc3-80d8-8007-b2806dfd8a37\",\"~:parent-id\",\"~u11813dac-4dc3-80d8-8007-b2806dfd8a36\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",1416.9999368190765,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1416.9999368190765,\"~:y\",93.99999856948853,\"^8\",194,\"~:height\",200,\"~:x1\",1416.9999368190765,\"~:y1\",93.99999856948853,\"~:x2\",1610.9999368190765,\"~:y2\",293.9999985694885]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#174be9\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^F\",200,\"~:flip-y\",null]]",
|
||||
"~u5b58e018-fa5e-805d-8007-b27294ad5af1": "[\"~#shape\",[\"^ \",\"~:y\",-22.00000122055286,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",445.0000023918125,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",162.9999992063131,\"~:y\",-22.000001220552832]],[\"^<\",[\"^ \",\"~:x\",608.0000015981256,\"~:y\",-22.000001220552832]],[\"^<\",[\"^ \",\"~:x\",608.0000015981256,\"~:y\",423.0000182011825]],[\"^<\",[\"^ \",\"~:x\",162.9999992063131,\"~:y\",423.0000182011825]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",4,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u5b58e018-fa5e-805d-8007-b27294ad5af1\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",162.99999920631308,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",162.99999920631308,\"~:y\",-22.00000122055286,\"^8\",445.0000023918125,\"~:height\",445.0000194217354,\"~:x1\",162.99999920631308,\"~:y1\",-22.00000122055286,\"~:x2\",608.0000015981256,\"~:y2\",423.0000182011825]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",445.0000194217354,\"~:flip-y\",null]]",
|
||||
"~u5b58e018-fa5e-805d-8007-b27294ad5af1": "[\"~#shape\",[\"^ \",\"~:y\",-22.00000122055286,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",445.0000023918125,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",162.9999992063131,\"~:y\",-22.000001220552832]],[\"^<\",[\"^ \",\"~:x\",608.0000015981256,\"~:y\",-22.000001220552832]],[\"^<\",[\"^ \",\"~:x\",608.0000015981256,\"~:y\",423.0000182011825]],[\"^<\",[\"^ \",\"~:x\",162.9999992063131,\"~:y\",423.0000182011825]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:background-blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",4,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u5b58e018-fa5e-805d-8007-b27294ad5af1\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",162.99999920631308,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",162.99999920631308,\"~:y\",-22.00000122055286,\"^8\",445.0000023918125,\"~:height\",445.0000194217354,\"~:x1\",162.99999920631308,\"~:y1\",-22.00000122055286,\"~:x2\",608.0000015981256,\"~:y2\",423.0000182011825]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",445.0000194217354,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b2804a521773": "[\"~#shape\",[\"^ \",\"~:y\",49.00000846385956,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:index\",2,\"~:name\",\"Group\",\"~:width\",303,\"~:type\",\"~:group\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",49.00000846385956]],[\"^:\",[\"^ \",\"~:x\",537.0000004768372,\"~:y\",49.00000846385956]],[\"^:\",[\"^ \",\"~:x\",537.0000004768372,\"~:y\",352.00000846385956]],[\"^:\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",352.00000846385956]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u11813dac-4dc3-80d8-8007-b2804a521773\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",234.00000047683716,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",49.00000846385956,\"^6\",303,\"~:height\",303,\"~:x1\",234.00000047683716,\"~:y1\",49.00000846385956,\"~:x2\",537.0000004768372,\"~:y2\",352.00000846385956]],\"~:fills\",[],\"~:flip-x\",null,\"^D\",303,\"~:flip-y\",null,\"~:shapes\",[\"~u5b58e018-fa5e-805d-8007-b27288b0cd80\",\"~u5b58e018-fa5e-805d-8007-b2728b102fe6\"]]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b2806dfde19c": "[\"~#shape\",[\"^ \",\"~:y\",189.99999856948853,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",206,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1307.9999368190765,\"~:y\",189.99999856948853]],[\"^<\",[\"^ \",\"~:x\",1513.9999368190765,\"~:y\",189.99999856948853]],[\"^<\",[\"^ \",\"~:x\",1513.9999368190765,\"~:y\",396.9999985694885]],[\"^<\",[\"^ \",\"~:x\",1307.9999368190765,\"~:y\",396.9999985694885]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u11813dac-4dc3-80d8-8007-b2806dfde19c\",\"~:parent-id\",\"~u11813dac-4dc3-80d8-8007-b2806dfd8a36\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",1307.9999368190765,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1307.9999368190765,\"~:y\",189.99999856948853,\"^8\",206,\"~:height\",207,\"~:x1\",1307.9999368190765,\"~:y1\",189.99999856948853,\"~:x2\",1513.9999368190765,\"~:y2\",396.9999985694885]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#c8f00d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^J\",207,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b2806dfde19d": "[\"~#shape\",[\"^ \",\"~:y\",-32.00000238488809,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",302.9999596227117,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1307.9999330492521,\"~:y\",-32.00000238488809]],[\"^<\",[\"^ \",\"~:x\",1610.9998926719638,\"~:y\",-32.00000238488809]],[\"^<\",[\"^ \",\"~:x\",1610.9998926719638,\"~:y\",268.00000735984116]],[\"^<\",[\"^ \",\"~:x\",1307.9999330492521,\"~:y\",268.00000735984116]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",4,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u11813dac-4dc3-80d8-8007-b2806dfde19d\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",1307.9999330492521,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1307.9999330492521,\"~:y\",-32.00000238488809,\"^8\",302.9999596227117,\"~:height\",300.00000974472925,\"~:x1\",1307.9999330492521,\"~:y1\",-32.00000238488809,\"~:x2\",1610.9998926719638,\"~:y2\",268.00000735984116]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",300.00000974472925,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b2806dfde19d": "[\"~#shape\",[\"^ \",\"~:y\",-32.00000238488809,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",302.9999596227117,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1307.9999330492521,\"~:y\",-32.00000238488809]],[\"^<\",[\"^ \",\"~:x\",1610.9998926719638,\"~:y\",-32.00000238488809]],[\"^<\",[\"^ \",\"~:x\",1610.9998926719638,\"~:y\",268.00000735984116]],[\"^<\",[\"^ \",\"~:x\",1307.9999330492521,\"~:y\",268.00000735984116]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:background-blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",4,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u11813dac-4dc3-80d8-8007-b2806dfde19d\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",1307.9999330492521,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1307.9999330492521,\"~:y\",-32.00000238488809,\"^8\",302.9999596227117,\"~:height\",300.00000974472925,\"~:x1\",1307.9999330492521,\"~:y1\",-32.00000238488809,\"~:x2\",1610.9998926719638,\"~:y2\",268.00000735984116]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",300.00000974472925,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14a4": "[\"~#shape\",[\"^ \",\"~:y\",592.0000023841858,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:index\",2,\"~:name\",\"Group\",\"~:width\",303,\"~:type\",\"~:group\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",817.9999825954437,\"~:y\",592.0000023841858]],[\"^:\",[\"^ \",\"~:x\",1120.9999825954437,\"~:y\",592.0000023841858]],[\"^:\",[\"^ \",\"~:x\",1120.9999825954437,\"~:y\",895.0000023841858]],[\"^:\",[\"^ \",\"~:x\",817.9999825954437,\"~:y\",895.0000023841858]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14a4\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",817.9999825954437,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",817.9999825954437,\"~:y\",592.0000023841858,\"^6\",303,\"~:height\",303,\"~:x1\",817.9999825954437,\"~:y1\",592.0000023841858,\"~:x2\",1120.9999825954437,\"~:y2\",895.0000023841858]],\"~:fills\",[],\"~:flip-x\",null,\"^D\",303,\"~:flip-y\",null,\"~:shapes\",[\"~u11813dac-4dc3-80d8-8007-b280a6cd14a5\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14a6\"]]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b28053db9864": "[\"~#shape\",[\"^ \",\"~:y\",97.00000524450644,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",299.9999982638824,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",770.9999871603877,\"~:y\",97.00000524450644]],[\"^<\",[\"^ \",\"~:x\",1070.99998542427,\"~:y\",97.00000524450644]],[\"^<\",[\"^ \",\"~:x\",1070.99998542427,\"~:y\",397.0000149892357]],[\"^<\",[\"^ \",\"~:x\",770.9999871603877,\"~:y\",397.0000149892357]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",4,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u11813dac-4dc3-80d8-8007-b28053db9864\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",770.9999871603877,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",770.9999871603877,\"~:y\",97.00000524450644,\"^8\",299.9999982638824,\"~:height\",300.00000974472925,\"~:x1\",770.9999871603877,\"~:y1\",97.00000524450644,\"~:x2\",1070.99998542427,\"~:y2\",397.0000149892357]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",300.00000974472925,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b28053db9864": "[\"~#shape\",[\"^ \",\"~:y\",97.00000524450644,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",299.9999982638824,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",770.9999871603877,\"~:y\",97.00000524450644]],[\"^<\",[\"^ \",\"~:x\",1070.99998542427,\"~:y\",97.00000524450644]],[\"^<\",[\"^ \",\"~:x\",1070.99998542427,\"~:y\",397.0000149892357]],[\"^<\",[\"^ \",\"~:x\",770.9999871603877,\"~:y\",397.0000149892357]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:background-blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",4,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u11813dac-4dc3-80d8-8007-b28053db9864\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",770.9999871603877,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",770.9999871603877,\"~:y\",97.00000524450644,\"^8\",299.9999982638824,\"~:height\",300.00000974472925,\"~:x1\",770.9999871603877,\"~:y1\",97.00000524450644,\"~:x2\",1070.99998542427,\"~:y2\",397.0000149892357]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",300.00000974472925,\"~:flip-y\",null]]",
|
||||
"~u5b58e018-fa5e-805d-8007-b2728b102fe6": "[\"~#shape\",[\"^ \",\"~:y\",145.00000846385956,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",206,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",145.00000846385956]],[\"^<\",[\"^ \",\"~:x\",440.00000047683716,\"~:y\",145.00000846385956]],[\"^<\",[\"^ \",\"~:x\",440.00000047683716,\"~:y\",352.00000846385956]],[\"^<\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",352.00000846385956]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2728b102fe6\",\"~:parent-id\",\"~u11813dac-4dc3-80d8-8007-b2804a521773\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",234.00000047683716,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",145.00000846385956,\"^8\",206,\"~:height\",207,\"~:x1\",234.00000047683716,\"~:y1\",145.00000846385956,\"~:x2\",440.00000047683716,\"~:y2\",352.00000846385956]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#c8f00d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^J\",207,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14a5": "[\"~#shape\",[\"^ \",\"~:y\",592.0000023841858,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Ellipse\",\"~:width\",194,\"~:type\",\"~:circle\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",926.9999825954437,\"~:y\",592.0000023841858]],[\"^<\",[\"^ \",\"~:x\",1120.9999825954437,\"~:y\",592.0000023841858]],[\"^<\",[\"^ \",\"~:x\",1120.9999825954437,\"~:y\",792.0000023841858]],[\"^<\",[\"^ \",\"~:x\",926.9999825954437,\"~:y\",792.0000023841858]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14a5\",\"~:parent-id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14a4\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",926.9999825954437,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",926.9999825954437,\"~:y\",592.0000023841858,\"^8\",194,\"~:height\",200,\"~:x1\",926.9999825954437,\"~:y1\",592.0000023841858,\"~:x2\",1120.9999825954437,\"~:y2\",792.0000023841858]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#174be9\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^F\",200,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b28053db9865": "[\"~#shape\",[\"^ \",\"~:y\",48.00000238418579,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:index\",2,\"~:name\",\"Group\",\"~:width\",303,\"~:type\",\"~:group\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",817.9999825954437,\"~:y\",48.00000238418579]],[\"^:\",[\"^ \",\"~:x\",1120.9999825954437,\"~:y\",48.00000238418579]],[\"^:\",[\"^ \",\"~:x\",1120.9999825954437,\"~:y\",351.0000023841858]],[\"^:\",[\"^ \",\"~:x\",817.9999825954437,\"~:y\",351.0000023841858]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u11813dac-4dc3-80d8-8007-b28053db9865\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",817.9999825954437,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",817.9999825954437,\"~:y\",48.00000238418579,\"^6\",303,\"~:height\",303,\"~:x1\",817.9999825954437,\"~:y1\",48.00000238418579,\"~:x2\",1120.9999825954437,\"~:y2\",351.0000023841858]],\"~:fills\",[],\"~:flip-x\",null,\"^D\",303,\"~:flip-y\",null,\"~:shapes\",[\"~u11813dac-4dc3-80d8-8007-b28053db9866\",\"~u11813dac-4dc3-80d8-8007-b28053db9867\"]]]",
|
||||
@ -140,11 +140,11 @@
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14ac": "[\"~#shape\",[\"^ \",\"~:y\",593.0000084638596,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:index\",2,\"~:name\",\"Group\",\"~:width\",303,\"~:type\",\"~:group\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",593.0000084638596]],[\"^:\",[\"^ \",\"~:x\",537.0000004768372,\"~:y\",593.0000084638596]],[\"^:\",[\"^ \",\"~:x\",537.0000004768372,\"~:y\",896.0000084638596]],[\"^:\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",896.0000084638596]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14ac\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",234.00000047683716,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",593.0000084638596,\"^6\",303,\"~:height\",303,\"~:x1\",234.00000047683716,\"~:y1\",593.0000084638596,\"~:x2\",537.0000004768372,\"~:y2\",896.0000084638596]],\"~:fills\",[],\"~:flip-x\",null,\"^D\",303,\"~:flip-y\",null,\"~:shapes\",[\"~u11813dac-4dc3-80d8-8007-b280a6cd14ad\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14ae\"]]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14ad": "[\"~#shape\",[\"^ \",\"~:y\",593.0000084638596,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Ellipse\",\"~:width\",194,\"~:type\",\"~:circle\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",343.00000047683716,\"~:y\",593.0000084638596]],[\"^<\",[\"^ \",\"~:x\",537.0000004768372,\"~:y\",593.0000084638596]],[\"^<\",[\"^ \",\"~:x\",537.0000004768372,\"~:y\",793.0000084638596]],[\"^<\",[\"^ \",\"~:x\",343.00000047683716,\"~:y\",793.0000084638596]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14ad\",\"~:parent-id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14ac\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",343.00000047683716,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",343.00000047683716,\"~:y\",593.0000084638596,\"^8\",194,\"~:height\",200,\"~:x1\",343.00000047683716,\"~:y1\",593.0000084638596,\"~:x2\",537.0000004768372,\"~:y2\",793.0000084638596]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#174be9\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^F\",200,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14ae": "[\"~#shape\",[\"^ \",\"~:y\",689.0000084638596,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",206,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",689.0000084638596]],[\"^<\",[\"^ \",\"~:x\",440.00000047683716,\"~:y\",689.0000084638596]],[\"^<\",[\"^ \",\"~:x\",440.00000047683716,\"~:y\",896.0000084638596]],[\"^<\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",896.0000084638596]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14ae\",\"~:parent-id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14ac\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",234.00000047683716,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",234.00000047683716,\"~:y\",689.0000084638596,\"^8\",206,\"~:height\",207,\"~:x1\",234.00000047683716,\"~:y1\",689.0000084638596,\"~:x2\",440.00000047683716,\"~:y2\",896.0000084638596]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#c8f00d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^J\",207,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14af": "[\"~#shape\",[\"^ \",\"~:y\",512.0000283168957,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",445.0000023918125,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",157.99998871589563,\"~:y\",512.0000283168957]],[\"^<\",[\"^ \",\"~:x\",602.9999911077081,\"~:y\",512.0000283168957]],[\"^<\",[\"^ \",\"~:x\",602.9999911077081,\"~:y\",957.000047738631]],[\"^<\",[\"^ \",\"~:x\",157.99998871589563,\"~:y\",957.000047738631]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",50,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14af\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",157.9999887158956,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",157.9999887158956,\"~:y\",512.0000283168957,\"^8\",445.0000023918125,\"~:height\",445.00001942173526,\"~:x1\",157.9999887158956,\"~:y1\",512.0000283168957,\"~:x2\",602.9999911077081,\"~:y2\",957.000047738631]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",445.00001942173526,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14af": "[\"~#shape\",[\"^ \",\"~:y\",512.0000283168957,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",445.0000023918125,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",157.99998871589563,\"~:y\",512.0000283168957]],[\"^<\",[\"^ \",\"~:x\",602.9999911077081,\"~:y\",512.0000283168957]],[\"^<\",[\"^ \",\"~:x\",602.9999911077081,\"~:y\",957.000047738631]],[\"^<\",[\"^ \",\"~:x\",157.99998871589563,\"~:y\",957.000047738631]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:background-blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",50,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14af\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",157.9999887158956,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",157.9999887158956,\"~:y\",512.0000283168957,\"^8\",445.0000023918125,\"~:height\",445.00001942173526,\"~:x1\",157.9999887158956,\"~:y1\",512.0000283168957,\"~:x2\",602.9999911077081,\"~:y2\",957.000047738631]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",445.00001942173526,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14a8": "[\"~#shape\",[\"^ \",\"~:y\",637.9999985694885,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Ellipse\",\"~:width\",194,\"~:type\",\"~:circle\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1417.000058889389,\"~:y\",637.9999985694885]],[\"^<\",[\"^ \",\"~:x\",1611.000058889389,\"~:y\",637.9999985694885]],[\"^<\",[\"^ \",\"~:x\",1611.000058889389,\"~:y\",837.9999985694885]],[\"^<\",[\"^ \",\"~:x\",1417.000058889389,\"~:y\",837.9999985694885]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14a8\",\"~:parent-id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14a7\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",1417.000058889389,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1417.000058889389,\"~:y\",637.9999985694885,\"^8\",194,\"~:height\",200,\"~:x1\",1417.000058889389,\"~:y1\",637.9999985694885,\"~:x2\",1611.000058889389,\"~:y2\",837.9999985694885]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#174be9\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^F\",200,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14a9": "[\"~#shape\",[\"^ \",\"~:y\",733.9999985694885,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",206,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1308.000058889389,\"~:y\",733.9999985694885]],[\"^<\",[\"^ \",\"~:x\",1514.000058889389,\"~:y\",733.9999985694885]],[\"^<\",[\"^ \",\"~:x\",1514.000058889389,\"~:y\",940.9999985694885]],[\"^<\",[\"^ \",\"~:x\",1308.000058889389,\"~:y\",940.9999985694885]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14a9\",\"~:parent-id\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14a7\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",1308.000058889389,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1308.000058889389,\"~:y\",733.9999985694885,\"^8\",206,\"~:height\",207,\"~:x1\",1308.000058889389,\"~:y1\",733.9999985694885,\"~:x2\",1514.000058889389,\"~:y2\",940.9999985694885]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#c8f00d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^J\",207,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14aa": "[\"~#shape\",[\"^ \",\"~:y\",511.9999976151119,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",302.9999596227117,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1308.0000551195646,\"~:y\",511.9999976151119]],[\"^<\",[\"^ \",\"~:x\",1611.0000147422763,\"~:y\",511.9999976151119]],[\"^<\",[\"^ \",\"~:x\",1611.0000147422763,\"~:y\",812.0000073598412]],[\"^<\",[\"^ \",\"~:x\",1308.0000551195646,\"~:y\",812.0000073598412]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",50,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14aa\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",1308.0000551195646,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1308.0000551195646,\"~:y\",511.9999976151119,\"^8\",302.9999596227117,\"~:height\",300.0000097447293,\"~:x1\",1308.0000551195646,\"~:y1\",511.9999976151119,\"~:x2\",1611.0000147422763,\"~:y2\",812.0000073598412]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",300.0000097447293,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14ab": "[\"~#shape\",[\"^ \",\"~:y\",512.00002813269,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",299.9999982638824,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",743.9999566428096,\"~:y\",512.00002813269]],[\"^<\",[\"^ \",\"~:x\",1043.999954906692,\"~:y\",512.00002813269]],[\"^<\",[\"^ \",\"~:x\",1043.999954906692,\"~:y\",812.0000378774193]],[\"^<\",[\"^ \",\"~:x\",743.9999566428096,\"~:y\",812.0000378774193]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",50,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14ab\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",743.9999566428096,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",743.9999566428096,\"~:y\",512.00002813269,\"^8\",299.9999982638824,\"~:height\",300.00000974472937,\"~:x1\",743.9999566428096,\"~:y1\",512.00002813269,\"~:x2\",1043.999954906692,\"~:y2\",812.0000378774193]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",300.00000974472937,\"~:flip-y\",null]]"
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14aa": "[\"~#shape\",[\"^ \",\"~:y\",511.9999976151119,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",302.9999596227117,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1308.0000551195646,\"~:y\",511.9999976151119]],[\"^<\",[\"^ \",\"~:x\",1611.0000147422763,\"~:y\",511.9999976151119]],[\"^<\",[\"^ \",\"~:x\",1611.0000147422763,\"~:y\",812.0000073598412]],[\"^<\",[\"^ \",\"~:x\",1308.0000551195646,\"~:y\",812.0000073598412]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:background-blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",50,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14aa\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",1308.0000551195646,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1308.0000551195646,\"~:y\",511.9999976151119,\"^8\",302.9999596227117,\"~:height\",300.0000097447293,\"~:x1\",1308.0000551195646,\"~:y1\",511.9999976151119,\"~:x2\",1611.0000147422763,\"~:y2\",812.0000073598412]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",300.0000097447293,\"~:flip-y\",null]]",
|
||||
"~u11813dac-4dc3-80d8-8007-b280a6cd14ab": "[\"~#shape\",[\"^ \",\"~:y\",512.00002813269,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",299.9999982638824,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",743.9999566428096,\"~:y\",512.00002813269]],[\"^<\",[\"^ \",\"~:x\",1043.999954906692,\"~:y\",512.00002813269]],[\"^<\",[\"^ \",\"~:x\",1043.999954906692,\"~:y\",812.0000378774193]],[\"^<\",[\"^ \",\"~:x\",743.9999566428096,\"~:y\",812.0000378774193]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:background-blur\",[\"^ \",\"~:id\",\"~u5b58e018-fa5e-805d-8007-b2729af5ed71\",\"^9\",\"~:background-blur\",\"~:value\",50,\"~:hidden\",false],\"~:r1\",20,\"^B\",\"~u11813dac-4dc3-80d8-8007-b280a6cd14ab\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",743.9999566428096,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",743.9999566428096,\"~:y\",512.00002813269,\"^8\",299.9999982638824,\"~:height\",300.00000974472937,\"~:x1\",743.9999566428096,\"~:y1\",512.00002813269,\"~:x2\",1043.999954906692,\"~:y2\",812.0000378774193]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.30392156862745096]],\"~:flip-x\",null,\"^N\",300.00000974472937,\"~:flip-y\",null]]"
|
||||
}
|
||||
},
|
||||
"~:id": "~u93bfc923-66b2-813c-8007-b2725507ba09",
|
||||
|
||||
@ -257,12 +257,26 @@ test.describe("Background blur", () => {
|
||||
// Click the first Rectangle (which has background-blur type)
|
||||
await workspace.clickLeafLayer("Rectangle");
|
||||
|
||||
const blurSection = workspace.page.getByRole("region", {
|
||||
name: "Blur effects",
|
||||
});
|
||||
await expect(blurSection).toBeVisible();
|
||||
|
||||
// The blur type select should show "Background blur" as the current value
|
||||
const blurTypeSelect = workspace.page
|
||||
.getByTestId("blur-info")
|
||||
.getByRole("combobox");
|
||||
const blurTypeSelect = workspace.page.getByRole("combobox", {
|
||||
name: "Blur type select",
|
||||
});
|
||||
await expect(blurTypeSelect).toBeVisible();
|
||||
await expect(blurTypeSelect).toContainText("Background blur");
|
||||
|
||||
// Select first group layer, which has not blur effect
|
||||
await workspace.layers.getByTestId("layer-row").nth(5).click();
|
||||
|
||||
await expect(blurTypeSelect).not.toBeVisible();
|
||||
await blurSection.getByRole("button", { name: "Add blur" }).click();
|
||||
await expect(blurTypeSelect).toBeVisible();
|
||||
|
||||
await expect(blurTypeSelect).toContainText("Layer blur");
|
||||
});
|
||||
|
||||
test("Shows both layer-blur and background-blur options in the blur type dropdown", async ({
|
||||
@ -279,25 +293,66 @@ test.describe("Background blur", () => {
|
||||
});
|
||||
|
||||
await workspace.clickLeafLayer("Rectangle");
|
||||
const blurSection = workspace.page.getByRole("region", {
|
||||
name: "Blur effects",
|
||||
});
|
||||
await expect(blurSection).toBeVisible();
|
||||
|
||||
// Open the blur type dropdown
|
||||
const blurTypeSelect = workspace.page
|
||||
.getByTestId("blur-info")
|
||||
.getByRole("combobox");
|
||||
const blurTypeSelect = blurSection.getByRole("combobox", {
|
||||
name: "Blur type select",
|
||||
});
|
||||
await expect(blurTypeSelect).toBeVisible();
|
||||
|
||||
await blurTypeSelect.click();
|
||||
|
||||
// Both options should be visible
|
||||
const layerBlurOption = workspace.page.getByRole("option", {
|
||||
const layerBlurOption = blurSection.getByRole("option", {
|
||||
name: "Layer blur",
|
||||
});
|
||||
const backgroundBlurOption = workspace.page.getByRole("option", {
|
||||
const backgroundBlurOption = blurSection.getByRole("option", {
|
||||
name: "Background blur",
|
||||
});
|
||||
await expect(layerBlurOption).toBeVisible();
|
||||
await expect(backgroundBlurOption).toBeVisible();
|
||||
});
|
||||
|
||||
test("Does not show background blur option when background-blur flag is not active", async ({
|
||||
test("Shape can have both layer blur and background blur effects at the same time", async ({
|
||||
page,
|
||||
}) => {
|
||||
const workspace = new WasmWorkspacePage(page);
|
||||
await workspace.mockConfigFlags(["enable-background-blur", tokenInputFlag]);
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("render-wasm/get-file-background-blur.json");
|
||||
|
||||
await workspace.goToWorkspace({
|
||||
fileId: "93bfc923-66b2-813c-8007-b2725507ba08",
|
||||
pageId: "93bfc923-66b2-813c-8007-b2725507ba09",
|
||||
});
|
||||
|
||||
await workspace.clickLeafLayer("Rectangle");
|
||||
const blurSection = workspace.page.getByRole("region", {
|
||||
name: "Blur effects",
|
||||
});
|
||||
await expect(blurSection).toBeVisible();
|
||||
|
||||
const addBlurButton = blurSection.getByRole("button", { name: "Add blur" });
|
||||
await expect(addBlurButton).toBeVisible();
|
||||
await addBlurButton.click();
|
||||
|
||||
const blurTypeSelect = blurSection.getByRole("combobox", {
|
||||
name: "Blur type select",
|
||||
});
|
||||
await expect(blurTypeSelect).toHaveCount(2);
|
||||
|
||||
const backgroundBlurLabel = blurSection.getByText("Background blur");
|
||||
await expect(backgroundBlurLabel).toBeVisible();
|
||||
|
||||
const layerBlurLabel = blurSection.getByText("Layer blur");
|
||||
await expect(layerBlurLabel).toBeVisible();
|
||||
});
|
||||
|
||||
test("Show background blur disabled when flag is not active", async ({
|
||||
page,
|
||||
}) => {
|
||||
const workspace = new WasmWorkspacePage(page);
|
||||
@ -312,15 +367,42 @@ test.describe("Background blur", () => {
|
||||
|
||||
await workspace.clickLeafLayer("Rectangle");
|
||||
|
||||
// When there is no background blur flag the section has the old name "blur" instead of "blur effects"
|
||||
const blurSection = workspace.page.getByRole("region", {
|
||||
name: "Blur",
|
||||
});
|
||||
await expect(blurSection).toBeVisible();
|
||||
// Without the background-blur flag, no blur type dropdown should appear.
|
||||
// Instead, a plain "Blur" label is shown.
|
||||
const blurTypeSelect = workspace.page
|
||||
.getByTestId("blur-info")
|
||||
.getByRole("combobox");
|
||||
// Instead, a plain "Background blur" label is shown and more option button is disabled.
|
||||
const blurTypeSelect = blurSection.getByRole("combobox", {
|
||||
name: "Blur type select",
|
||||
});
|
||||
await expect(blurTypeSelect).not.toBeVisible();
|
||||
|
||||
const blurLabel = workspace.page.getByTestId("blur-info").getByText("Blur");
|
||||
await expect(blurLabel).toBeVisible();
|
||||
const backgroundBlurLabel = blurSection.getByText("Background blur");
|
||||
await expect(backgroundBlurLabel).toBeVisible();
|
||||
|
||||
const showMoreOptionsButton = blurSection.getByRole("button", {
|
||||
name: "Show/hide more options",
|
||||
});
|
||||
await expect(showMoreOptionsButton).toBeDisabled();
|
||||
|
||||
const showAndHideButton = blurSection.getByRole("button", {
|
||||
name: "Toggle blur",
|
||||
});
|
||||
await expect(showAndHideButton).toBeDisabled();
|
||||
|
||||
const addBlurButton = blurSection.getByRole("button", { name: "Add blur" });
|
||||
|
||||
// We can add a layer blur, but not a background blur, and the type select should not appear
|
||||
await expect(addBlurButton).toBeVisible();
|
||||
await addBlurButton.click();
|
||||
|
||||
await expect(blurTypeSelect).not.toBeVisible();
|
||||
await expect(backgroundBlurLabel).toBeVisible();
|
||||
|
||||
const blurLabel = blurSection.getByText("Blur", { exact: true });
|
||||
await expect(blurLabel).toHaveCount(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -73,6 +73,7 @@
|
||||
:r4
|
||||
:shadow
|
||||
:blur
|
||||
:background-blur
|
||||
:strokes
|
||||
:width
|
||||
:height
|
||||
|
||||
@ -281,7 +281,7 @@
|
||||
(grc/fix-aspect-ratio aspect-ratio))
|
||||
|
||||
;; Bounds without shadows/blur will be the bounds of the thumbnail
|
||||
bounds2 (gsb/get-object-bounds objects (dissoc frame :shadow :blur))
|
||||
bounds2 (gsb/get-object-bounds objects (dissoc frame :shadow :blur :background-blur))
|
||||
|
||||
delta-bounds (gpt/point (:x bounds) (:y bounds))
|
||||
vector (gpt/negate delta-bounds)
|
||||
|
||||
@ -14,33 +14,32 @@
|
||||
(mf/defc title-bar*
|
||||
[{:keys [class collapsable collapsed title children
|
||||
btn-icon btn-title add-icon-gap
|
||||
title-class on-collapsed on-btn-click]}]
|
||||
[:div {:class [(stl/css :title-bar)
|
||||
class]}
|
||||
title-class on-collapsed on-btn-click] :rest props}]
|
||||
(let [props (mf/spread-props props {:class (stl/css :icon-text-btn)
|
||||
:on-click on-collapsed})]
|
||||
|
||||
(if ^boolean collapsable
|
||||
[:div {:class [(stl/css :title-wrapper) title-class]}
|
||||
[:div {:class [(stl/css :title-bar) class]}
|
||||
(if ^boolean collapsable
|
||||
[:div {:class [(stl/css :title-wrapper) title-class]}
|
||||
(let [icon-id (if collapsed "arrow-right" "arrow-down")]
|
||||
[:> :button props
|
||||
[:> icon* {:icon-id icon-id
|
||||
:size "s"
|
||||
:class (stl/css :icon)}]
|
||||
[:div {:class (stl/css :title)} title]])]
|
||||
|
||||
(let [icon-id (if collapsed "arrow-right" "arrow-down")]
|
||||
[:button {:class (stl/css :icon-text-btn)
|
||||
:on-click on-collapsed}
|
||||
[:> icon* {:icon-id icon-id
|
||||
:size "s"
|
||||
:class (stl/css :icon)}]
|
||||
[:div {:class (stl/css :title)} title]])]
|
||||
[:div {:class [(stl/css-case :title-only true
|
||||
:title-only-icon-gap add-icon-gap)
|
||||
title-class]}
|
||||
title])
|
||||
|
||||
[:div {:class [(stl/css-case :title-only true
|
||||
:title-only-icon-gap add-icon-gap)
|
||||
title-class]}
|
||||
title])
|
||||
children
|
||||
|
||||
children
|
||||
|
||||
(when (some? on-btn-click)
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label btn-title
|
||||
:on-click on-btn-click
|
||||
:icon btn-icon}])])
|
||||
(when (some? on-btn-click)
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label btn-title
|
||||
:on-click on-btn-click
|
||||
:icon btn-icon}])]))
|
||||
|
||||
|
||||
(mf/defc inspect-title-bar*
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
text-align: start;
|
||||
grid-auto-flow: column;
|
||||
height: 100%;
|
||||
min-height: deprecated.$s-32;
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.config :as cf]
|
||||
[app.main.features :as features]
|
||||
[app.main.ui.components.copy-button :refer [copy-button*]]
|
||||
[app.main.ui.components.title-bar :refer [inspect-title-bar*]]
|
||||
[app.util.code-gen.style-css :as css]
|
||||
@ -15,35 +17,53 @@
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defn- has-blur? [shape]
|
||||
(:blur shape))
|
||||
|
||||
(defn- blur-css-property [shape]
|
||||
(if (= :background-blur (get-in shape [:blur :type]))
|
||||
:backdrop-filter
|
||||
:filter))
|
||||
(or (:blur shape)
|
||||
(:background-blur shape)))
|
||||
|
||||
(mf/defc blur-panel
|
||||
[{:keys [objects shapes]}]
|
||||
(let [shapes (->> shapes (filter has-blur?))]
|
||||
(let [render-wasm? (features/use-feature "render-wasm/v1")
|
||||
bg-blur? (and render-wasm?
|
||||
(contains? cf/flags :background-blur))
|
||||
shapes (->> shapes (filter #(has-blur? %)))
|
||||
title (if bg-blur?
|
||||
(tr "labels.blur-effects")
|
||||
(tr "labels.blur"))]
|
||||
(when (seq shapes)
|
||||
[:div {:class (stl/css :attributes-block)}
|
||||
[:> inspect-title-bar*
|
||||
{:title (tr "inspect.attributes.blur")
|
||||
{:title title
|
||||
:class (stl/css :title-wrapper)
|
||||
:title-class (stl/css :blur-attr-title)}
|
||||
(when (= (count shapes) 1)
|
||||
(let [prop (blur-css-property (first shapes))]
|
||||
[:> copy-button* {:data (css/get-css-property objects (first shapes) prop)
|
||||
:class (stl/css :copy-btn-title)}]))]
|
||||
(let [background-blur (:background-blur (first shapes))
|
||||
layer-blur (:blur (first shapes))]
|
||||
(when background-blur
|
||||
[:> copy-button* {:data (css/get-css-property objects (first shapes) :backdrop-filter)
|
||||
:class (stl/css :copy-btn-title)}])
|
||||
(when layer-blur
|
||||
[:> copy-button* {:data (css/get-css-property objects (first shapes) :filter)
|
||||
:class (stl/css :copy-btn-title)}])))]
|
||||
|
||||
[:div {:class (stl/css :attributes-content)}
|
||||
(for [shape shapes]
|
||||
(let [prop (blur-css-property shape)]
|
||||
(let [background-blur (:background-blur (first shapes))
|
||||
layer-blur (:blur (first shapes))]
|
||||
[:div {:class (stl/css :blur-row)
|
||||
:key (dm/str "block-" (:id shape) "-blur")}
|
||||
[:div {:class (stl/css :global/attr-label)}
|
||||
(if (= prop :backdrop-filter) "Backdrop Filter" "Filter")]
|
||||
[:div {:class (stl/css :global/attr-value)}
|
||||
[:> copy-button* {:data (css/get-css-property objects shape prop)}
|
||||
[:div {:class (stl/css :button-children)}
|
||||
(css/get-css-value objects shape prop)]]]]))]])))
|
||||
(when background-blur
|
||||
[:div {:key (dm/str "block-" (:id shape) "-background-blur")}
|
||||
[:div {:class (stl/css :global/attr-label)}
|
||||
"Backdrop Filter"]
|
||||
[:div {:class (stl/css :global/attr-value)}
|
||||
[:> copy-button* {:data (css/get-css-property objects shape :backdrop-filter)}
|
||||
[:div {:class (stl/css :button-children)}
|
||||
(css/get-css-value objects shape :backdrop-filter)]]]])
|
||||
(when layer-blur
|
||||
[:div {:key (dm/str "block-" (:id shape) "-layer-blur")}
|
||||
[:div {:class (stl/css :global/attr-label)}
|
||||
"Filter"]
|
||||
[:div {:class (stl/css :global/attr-value)}
|
||||
[:> copy-button* {:data (css/get-css-property objects shape :filter)}
|
||||
[:div {:class (stl/css :button-children)}
|
||||
(css/get-css-value objects shape :filter)]]]])]))]])))
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
:grid-column
|
||||
:grid-row])
|
||||
|
||||
|
||||
(def type->panel-group
|
||||
{:multiple [:fill :stroke :text :shadow :blur :layout-element]
|
||||
:frame [:visibility :geometry :fill :stroke :shadow :blur :layout :layout-element]
|
||||
@ -72,7 +71,8 @@
|
||||
(seq (:strokes shape)))
|
||||
|
||||
(defn- has-blur? [shape]
|
||||
(:blur shape))
|
||||
(or (:blur shape)
|
||||
(:background-blur shape)))
|
||||
|
||||
(defn- has-text? [shape]
|
||||
(:content shape))
|
||||
|
||||
@ -18,12 +18,24 @@
|
||||
[:div {:class (stl/css :blur-panel)}
|
||||
(for [shape shapes]
|
||||
[:div {:key (:id shape) :class (stl/css :blur-shape)}
|
||||
(let [property :filter
|
||||
value (css/get-css-value objects shape property)
|
||||
property-name (cmm/get-css-rule-humanized property)
|
||||
property-value (css/get-css-property objects shape property)]
|
||||
[:> properties-row* {:key (dm/str "blur-property-" property)
|
||||
:term property-name
|
||||
:detail (dm/str value)
|
||||
:property property-value
|
||||
:copiable true}])])])
|
||||
(let [blur-property :filter
|
||||
blur-value (css/get-css-value objects shape blur-property)
|
||||
background-blur-property :backdrop-filter
|
||||
blur-property-name (cmm/get-css-rule-humanized blur-property)
|
||||
blur-property-value (css/get-css-property objects shape blur-property)
|
||||
background-blur-value (css/get-css-value objects shape background-blur-property)
|
||||
background-blur-property-name (cmm/get-css-rule-humanized background-blur-property)
|
||||
background-blur-property-value (css/get-css-property objects shape background-blur-property)]
|
||||
[:div
|
||||
(when blur-property-value
|
||||
[:> properties-row* {:key (dm/str "blur-property-" blur-property)
|
||||
:term blur-property-name
|
||||
:detail (dm/str blur-value)
|
||||
:property blur-property-value
|
||||
:copiable true}])
|
||||
(when background-blur-property-value
|
||||
[:> properties-row* {:key (dm/str "blur-property-" background-blur-property)
|
||||
:term background-blur-property-name
|
||||
:detail (dm/str background-blur-value)
|
||||
:property background-blur-property-value
|
||||
:copiable true}])])])])
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.config :as cf]
|
||||
[app.main.features :as features]
|
||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
|
||||
[app.util.clipboard :as clipboard]
|
||||
@ -16,22 +18,27 @@
|
||||
|
||||
(defn- panel->title
|
||||
[type]
|
||||
(case type
|
||||
:variant (tr "inspect.tabs.styles.variants-panel")
|
||||
:token (tr "inspect.tabs.styles.token-panel")
|
||||
:geometry (tr "inspect.attributes.size")
|
||||
:fill (tr "labels.fill")
|
||||
:stroke (tr "labels.stroke")
|
||||
:text (tr "labels.text")
|
||||
:blur (tr "labels.blur")
|
||||
:shadow (tr "labels.shadow")
|
||||
:layout (tr "labels.layout")
|
||||
:flex-element "Flex Element"
|
||||
:grid-element "Grid Element"
|
||||
:layout-element "Layout Element"
|
||||
:visibility (tr "labels.visibility")
|
||||
:svg (tr "labels.svg")
|
||||
nil))
|
||||
(let [render-wasm? (features/use-feature "render-wasm/v1")
|
||||
bg-blur? (and render-wasm?
|
||||
(contains? cf/flags :background-blur))]
|
||||
(case type
|
||||
:variant (tr "inspect.tabs.styles.variants-panel")
|
||||
:token (tr "inspect.tabs.styles.token-panel")
|
||||
:geometry (tr "inspect.attributes.size")
|
||||
:fill (tr "labels.fill")
|
||||
:stroke (tr "labels.stroke")
|
||||
:text (tr "labels.text")
|
||||
:blur (if bg-blur?
|
||||
(tr "labels.blur-effects")
|
||||
(tr "labels.blur"))
|
||||
:shadow (tr "labels.shadow")
|
||||
:layout (tr "labels.layout")
|
||||
:flex-element "Flex Element"
|
||||
:grid-element "Grid Element"
|
||||
:layout-element "Layout Element"
|
||||
:visibility (tr "labels.visibility")
|
||||
:svg (tr "labels.svg")
|
||||
nil)))
|
||||
|
||||
(mf/defc style-box*
|
||||
[{:keys [panel shorthand children]}]
|
||||
|
||||
@ -183,6 +183,7 @@
|
||||
([props shape position render-id]
|
||||
(let [shape-fills (get shape :fills)
|
||||
shape-shadow (get shape :shadow)
|
||||
|
||||
shape-blur (get shape :blur)
|
||||
|
||||
svg-attrs (get-svg-props shape render-id)
|
||||
|
||||
@ -480,7 +480,8 @@
|
||||
|
||||
stroke-id (dm/str (dm/fmt "strokes-%-%" prefix shape-id))
|
||||
|
||||
shape-blur (get shape :blur)
|
||||
shape-blur (get shape :blur)
|
||||
|
||||
shape-fills (get shape :fills)
|
||||
shape-shadow (get shape :shadow)
|
||||
shape-strokes (not-empty strokes)
|
||||
@ -498,6 +499,7 @@
|
||||
|
||||
open-path? (and ^boolean (cfh/path-shape? shape)
|
||||
^boolean (path/shape-with-open-path? shape))]
|
||||
|
||||
(when-not ^boolean (cfh/frame-shape? shape)
|
||||
(when (and (some? shape-blur)
|
||||
(not ^boolean (:hidden shape-blur)))
|
||||
|
||||
@ -67,6 +67,7 @@
|
||||
|
||||
filter-id-blur (dm/fmt "filter-blur-%" render-id)
|
||||
filter-id-shadows (dm/fmt "filter-shadow-%" render-id)
|
||||
|
||||
filter-str-blur (filters/filter-str filter-id-blur (dissoc shape :shadow))
|
||||
filter-str-shadows (filters/filter-str filter-id-shadows (dissoc shape :blur))
|
||||
|
||||
|
||||
@ -14,146 +14,305 @@
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.features :as features]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input*]]
|
||||
[app.main.ui.components.select :refer [select]]
|
||||
[app.main.ui.components.title-bar :refer [title-bar*]]
|
||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||
[app.main.ui.ds.controls.numeric-input :refer [numeric-input*]]
|
||||
[app.main.ui.ds.controls.select :refer [select*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :as i]
|
||||
[app.main.ui.icons :as deprecated-icon]
|
||||
[app.main.ui.ds.tooltip.tooltip :refer [tooltip*]]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def blur-attrs [:blur])
|
||||
(def blur-attrs [:blur :background-blur])
|
||||
|
||||
(defn create-blur []
|
||||
(defn create-blur [type]
|
||||
(let [id (uuid/next)]
|
||||
{:id id
|
||||
:type :layer-blur
|
||||
:type type
|
||||
:value 4
|
||||
:hidden false}))
|
||||
|
||||
(mf/defc blur-menu* [{:keys [ids type values]}]
|
||||
(let [blur (:blur values)
|
||||
has-value? (not (nil? blur))
|
||||
render-wasm? (features/use-feature "render-wasm/v1")
|
||||
bg-blur? (and render-wasm?
|
||||
(contains? cf/flags :background-blur))
|
||||
(mf/defc blur-menu-content*
|
||||
[{:keys [blur-key value change-fn blur-values]}]
|
||||
(let [render-wasm? (features/use-feature "render-wasm/v1")
|
||||
bg-blur? (and render-wasm?
|
||||
(contains? cf/flags :background-blur))
|
||||
is-hidden (get value :hidden)
|
||||
show-more-options* (mf/use-state false)
|
||||
show-more-options (deref show-more-options*)
|
||||
toggle-more-options (mf/use-fn #(swap! show-more-options* not))
|
||||
|
||||
state* (mf/use-state {:show-content true
|
||||
:show-more-options false})
|
||||
handle-delete
|
||||
(mf/use-fn
|
||||
(mf/deps change-fn blur-key)
|
||||
(fn []
|
||||
(change-fn #(dissoc % blur-key))))
|
||||
|
||||
handle-toggle-visibility
|
||||
(mf/use-fn
|
||||
(mf/deps change-fn blur-key)
|
||||
(fn []
|
||||
(change-fn #(update-in % [blur-key :hidden] not))))
|
||||
|
||||
handle-change
|
||||
(mf/use-fn
|
||||
(mf/deps change-fn blur-key)
|
||||
(fn [value]
|
||||
(change-fn #(assoc-in % [blur-key :value] value))))
|
||||
|
||||
handle-type-change
|
||||
(mf/use-fn
|
||||
(mf/deps change-fn value blur-key)
|
||||
(fn [type]
|
||||
(let [type-kw (keyword type)
|
||||
target-key (if (= type-kw :layer-blur) :blur :background-blur)]
|
||||
(change-fn
|
||||
(fn [shape]
|
||||
(cond
|
||||
;; mismo tipo
|
||||
(= blur-key target-key)
|
||||
shape
|
||||
|
||||
;; ya existe un blur del tipo destino
|
||||
(contains? shape target-key)
|
||||
shape
|
||||
|
||||
;; blur origen no existe
|
||||
(not (contains? shape blur-key))
|
||||
shape
|
||||
|
||||
:else
|
||||
(let [blur (get shape blur-key)]
|
||||
(-> shape
|
||||
(dissoc blur-key)
|
||||
(assoc target-key
|
||||
(assoc blur :type type-kw))))))))))
|
||||
|
||||
bb-disabled? (and (= 2 (count blur-values))
|
||||
(not= blur-key :background-blur))
|
||||
lb-disabled? (and (= 2 (count blur-values))
|
||||
(not= blur-key :blur))
|
||||
label-ref (mf/use-ref nil)
|
||||
|
||||
type-options
|
||||
[{:value "layer-blur" :disabled lb-disabled? :id "layer-blur" :label (tr "workspace.options.blur-options.layer-blur")}
|
||||
{:value "background-blur" :disabled bb-disabled? :id "background-blur" :label (tr "workspace.options.blur-options.background-blur")}]
|
||||
|
||||
|
||||
background-blur-disabled?
|
||||
(and (= blur-key :background-blur)
|
||||
(not bg-blur?))
|
||||
|
||||
label-text
|
||||
(cond
|
||||
(= blur-key :background-blur)
|
||||
(tr "workspace.options.blur-options.background-blur")
|
||||
|
||||
bg-blur?
|
||||
(tr "workspace.options.blur-options.layer-blur")
|
||||
|
||||
:else
|
||||
(tr "labels.blur"))
|
||||
|
||||
label
|
||||
(mf/html [:span {:aria-labelledby "background-blur-disabled-label"
|
||||
:ref label-ref
|
||||
:class (stl/css-case :label true
|
||||
:disabled-label background-blur-disabled?)}
|
||||
label-text])]
|
||||
|
||||
[:*
|
||||
[:div {:class (stl/css-case :first-row true
|
||||
:hidden is-hidden)}
|
||||
[:div {:class (stl/css :blur-info)
|
||||
:data-testid "blur-info"}
|
||||
[:> icon-button* {:class (stl/css-case :show-more true
|
||||
:selected show-more-options)
|
||||
:on-click toggle-more-options
|
||||
:selected show-more-options
|
||||
:variant "ghost"
|
||||
:disabled (or
|
||||
is-hidden
|
||||
(and (= blur-key :background-blur)
|
||||
(= false bg-blur?)))
|
||||
:aria-label (tr "workspace.options.blur-options.toggle-more-options")
|
||||
:icon i/menu}]
|
||||
(cond bg-blur?
|
||||
[:> select*
|
||||
{:class (stl/css :blur-type-select)
|
||||
:default-selected (d/name (:type value))
|
||||
:aria-label (tr "workspace.options.blur-options.blur-type-select")
|
||||
:options type-options
|
||||
:disabled is-hidden
|
||||
:on-change handle-type-change}]
|
||||
background-blur-disabled?
|
||||
[:> tooltip*
|
||||
{:trigger-ref label-ref
|
||||
:id "background-blur-disabled-label"
|
||||
:class (stl/css :disabled-label-tooltip)
|
||||
:content (tr "workspace.options.blur-options.disabled-blur-label")}
|
||||
label]
|
||||
:else
|
||||
label)]
|
||||
|
||||
[:div {:class (stl/css :actions)}
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.blur-options.toggle-blur")
|
||||
:on-click handle-toggle-visibility
|
||||
:disabled (and (= blur-key :background-blur)
|
||||
(= false bg-blur?))
|
||||
:tooltip-placement "top-left"
|
||||
:icon (if (or is-hidden
|
||||
(and (= blur-key :background-blur)
|
||||
(= false bg-blur?))) i/hide i/shown)}]
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.blur-options.remove-blur")
|
||||
:on-click handle-delete
|
||||
:tooltip-placement "top-left"
|
||||
:icon i/remove}]]]
|
||||
|
||||
(when show-more-options
|
||||
[:div {:class (stl/css :second-row)}
|
||||
[:> numeric-input*
|
||||
{:class (stl/css :numeric-input)
|
||||
:placeholder "--"
|
||||
:min 0
|
||||
:text-icon "value"
|
||||
:on-change handle-change
|
||||
:name "blur-value"
|
||||
:value (:value value)}]])]))
|
||||
|
||||
(defn get-blurs [values]
|
||||
(cond-> []
|
||||
(:blur values)
|
||||
(conj {:key :blur
|
||||
:value (:blur values)})
|
||||
|
||||
(:background-blur values)
|
||||
(conj {:key :background-blur
|
||||
:value (:background-blur values)})))
|
||||
|
||||
(defn- check-props
|
||||
"A blur-menu specific memoize check function that only checks if
|
||||
specific values are changed on provided props. This allows pass the
|
||||
whole shape as values without adding additional rerenders when other
|
||||
shape properties changes."
|
||||
[n-props o-props]
|
||||
(and (identical? (unchecked-get n-props "ids")
|
||||
(unchecked-get o-props "ids"))
|
||||
(let [o-vals (unchecked-get o-props "values")
|
||||
n-vals (unchecked-get n-props "values")
|
||||
o-blur-values (get o-vals :blur)
|
||||
n-blur-values (get n-vals :blur)
|
||||
o-background-blur-values (get o-vals :background-blur)
|
||||
n-background-blur-values (get n-vals :background-blur)]
|
||||
(and (identical? o-blur-values n-blur-values)
|
||||
(identical? o-background-blur-values n-background-blur-values)))))
|
||||
|
||||
(mf/defc blur-menu*
|
||||
{::mf/wrap [#(mf/memo' % check-props)]}
|
||||
[{:keys [ids type values]}]
|
||||
(let [render-wasm? (features/use-feature "render-wasm/v1")
|
||||
bg-blur? (and render-wasm?
|
||||
(contains? cf/flags :background-blur))
|
||||
|
||||
|
||||
|
||||
blur-values (get-blurs values)
|
||||
|
||||
mixed-state (and (or (= :group type)
|
||||
(= :multiple type))
|
||||
(boolean
|
||||
(some #(= :multiple (:value %)) blur-values)))
|
||||
|
||||
state* (mf/use-state {:show-content true})
|
||||
state (deref state*)
|
||||
open? (:show-content state)
|
||||
more-options? (:show-more-options state)
|
||||
|
||||
toggle-content (mf/use-fn #(swap! state* update :show-content not))
|
||||
|
||||
toggle-more-options (mf/use-fn #(swap! state* update :show-more-options not))
|
||||
hidden? (:hidden blur)
|
||||
|
||||
change!
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [update-fn]
|
||||
(st/emit! (dwsh/update-shapes ids update-fn))))
|
||||
(st/emit! (dwsh/update-shapes ids update-fn)
|
||||
(udw/trigger-bounding-box-cloaking ids))))
|
||||
|
||||
handle-delete-all
|
||||
(mf/use-fn
|
||||
(mf/deps change!)
|
||||
(fn []
|
||||
(change! #(dissoc % :blur :background-blur))))
|
||||
|
||||
handle-add
|
||||
(mf/use-fn
|
||||
(mf/deps change! ids)
|
||||
(mf/deps change! blur-values)
|
||||
(fn []
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
||||
(change! #(assoc % :blur (create-blur)))))
|
||||
(cond
|
||||
(= 1 (count blur-values))
|
||||
(let [existing-key (:key (first blur-values))
|
||||
new-key (if (= existing-key :blur)
|
||||
:background-blur
|
||||
:blur)]
|
||||
(change! #(assoc % new-key (create-blur (if (= :blur new-key)
|
||||
:layer-blur
|
||||
:background-blur)))))
|
||||
(= 0 (count blur-values))
|
||||
(change! #(assoc % :blur (create-blur :layer-blur))))
|
||||
:else
|
||||
blur-values))]
|
||||
|
||||
handle-delete
|
||||
(mf/use-fn
|
||||
(mf/deps change! ids)
|
||||
(fn []
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
||||
(change! #(dissoc % :blur))))
|
||||
|
||||
handle-change
|
||||
(mf/use-fn
|
||||
(mf/deps change! ids)
|
||||
(fn [value]
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
||||
(change! #(cond-> %
|
||||
(not (contains? % :blur))
|
||||
(assoc :blur (create-blur))
|
||||
|
||||
:always
|
||||
(assoc-in [:blur :value] value)))))
|
||||
|
||||
handle-type-change
|
||||
(mf/use-fn
|
||||
(mf/deps change! ids)
|
||||
(fn [value]
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
||||
(change! #(assoc-in % [:blur :type] (keyword value)))))
|
||||
|
||||
handle-toggle-visibility
|
||||
(mf/use-fn
|
||||
(mf/deps change! ids)
|
||||
(fn []
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
||||
(change! #(update-in % [:blur :hidden] not))))
|
||||
|
||||
type-options
|
||||
(mf/with-memo [bg-blur?]
|
||||
(cond-> [{:value "layer-blur" :label (tr "workspace.options.blur-options.layer-blur")}]
|
||||
bg-blur?
|
||||
(conj {:value "background-blur" :label (tr "workspace.options.blur-options.background-blur")})))]
|
||||
|
||||
[:div {:class (stl/css :element-set)}
|
||||
[:section {:class (stl/css :element-set)
|
||||
:hidden (not open?)
|
||||
:aria-label (if bg-blur?
|
||||
(tr "labels.blur-effects")
|
||||
(tr "labels.blur"))}
|
||||
[:div {:class (stl/css :element-title)}
|
||||
[:> title-bar* {:collapsable has-value?
|
||||
[:> title-bar* {:collapsable (seq blur-values)
|
||||
:collapsed (not open?)
|
||||
:on-collapsed toggle-content
|
||||
:title (case type
|
||||
:multiple (tr "workspace.options.blur-options.title.multiple")
|
||||
:group (tr "workspace.options.blur-options.title.group")
|
||||
(tr "workspace.options.blur-options.title"))
|
||||
:class (stl/css-case :title-spacing-blur (not has-value?))}
|
||||
(when-not has-value?
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.blur-options.add-blur")
|
||||
:on-click handle-add
|
||||
:icon i/add
|
||||
:data-testid "add-blur"}])]]
|
||||
(when (and open? has-value?)
|
||||
[:div {:class (stl/css :element-set-content)}
|
||||
[:div {:class (stl/css-case :first-row true
|
||||
:hidden hidden?)}
|
||||
[:div {:class (stl/css :blur-info)
|
||||
:data-testid "blur-info"}
|
||||
[:button {:class (stl/css-case :show-more true
|
||||
:selected more-options?)
|
||||
:on-click toggle-more-options}
|
||||
deprecated-icon/menu]
|
||||
(if bg-blur?
|
||||
[:& select {:class (stl/css :blur-type-select)
|
||||
:default-value (d/name (:type blur))
|
||||
:options type-options
|
||||
:disabled hidden?
|
||||
:on-change handle-type-change}]
|
||||
[:span {:class (stl/css :label)}
|
||||
(tr "workspace.options.blur-options.title")])]
|
||||
[:div {:class (stl/css :actions)}
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.blur-options.toggle-blur")
|
||||
:on-click handle-toggle-visibility
|
||||
:icon (if hidden? i/hide i/shown)}]
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.blur-options.remove-blur")
|
||||
:on-click handle-delete
|
||||
:icon i/remove}]]]
|
||||
(when more-options?
|
||||
[:div {:class (stl/css :second-row)}
|
||||
[:label {:class (stl/css :label)
|
||||
:for "blur-input-sidebar"}
|
||||
(tr "inspect.attributes.blur.value")]
|
||||
[:> numeric-input*
|
||||
{:className (stl/css :numeric-input)
|
||||
:placeholder "--"
|
||||
:id "blur-input-sidebar"
|
||||
:min "0"
|
||||
:on-change handle-change
|
||||
:value (:value blur)}]])])]))
|
||||
:aria-expanded open?
|
||||
:aria-controls "blur-content"
|
||||
:title (if bg-blur?
|
||||
(cond
|
||||
(= type :multiple) (tr "workspace.options.blur-effects-options.title.multiple")
|
||||
(= type :group) (tr "workspace.options.blur-effects-options.title.group")
|
||||
:else (tr "labels.blur-effects"))
|
||||
(cond
|
||||
(= type :multiple) (tr "workspace.options.blur-options.title.multiple")
|
||||
(= type :group) (tr "workspace.options.blur-options.title.group")
|
||||
:else (tr "labels.blur")))
|
||||
:class (stl/css-case :title-spacing-blur (not (seq blur-values))
|
||||
:long-title true)}
|
||||
(when (and (not mixed-state)
|
||||
(if bg-blur?
|
||||
(< (count blur-values) 2)
|
||||
(nil? (:blur values))))
|
||||
[:> icon-button*
|
||||
{:variant "ghost"
|
||||
:aria-label (tr "workspace.options.blur-options.add-blur")
|
||||
:on-click handle-add
|
||||
:icon i/add
|
||||
:tooltip-placement "top-left"
|
||||
:data-testid "add-blur"}])]]
|
||||
(when (and open? (seq blur-values))
|
||||
[:div {:class (stl/css :element-set-content)
|
||||
:hidden (not open?)
|
||||
:id "blur-content"}
|
||||
(if mixed-state
|
||||
[:div {:class (stl/css :first-row)}
|
||||
[:span {:class (stl/css :mixed-label)}
|
||||
(tr "labels.mixed-values")]
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.blur-options.remove-blur")
|
||||
:on-click handle-delete-all
|
||||
:tooltip-placement "top-left"
|
||||
:icon i/remove}]]
|
||||
|
||||
(for [{:keys [key value]} blur-values]
|
||||
[:> blur-menu-content*
|
||||
{:key key
|
||||
:blur-key key
|
||||
:value value
|
||||
:blur-values blur-values
|
||||
:change-fn change!}]))])]))
|
||||
@ -4,114 +4,130 @@
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC Sucursal en España SL
|
||||
|
||||
@use "refactor/common-refactor.scss" as deprecated;
|
||||
@use "ds/_borders.scss" as *;
|
||||
@use "ds/typography.scss" as t;
|
||||
@use "ds/_sizes.scss" as *;
|
||||
@use "ds/_utils.scss" as *;
|
||||
@use "../../../sidebar/common/sidebar.scss" as sidebar;
|
||||
|
||||
.element-set {
|
||||
@include sidebar.option-grid-structure;
|
||||
}
|
||||
|
||||
.element-title {
|
||||
grid-column: span 8;
|
||||
}
|
||||
|
||||
.title-spacing-blur {
|
||||
padding-left: deprecated.$s-2;
|
||||
padding-left: var(--sp-xxs);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.element-set-content {
|
||||
@include deprecated.flex-column;
|
||||
.long-title {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
margin-bottom: deprecated.$s-8;
|
||||
.element-set-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-xs);
|
||||
margin-bottom: var(--sp-s);
|
||||
}
|
||||
|
||||
.first-row {
|
||||
@include sidebar.option-grid-structure;
|
||||
}
|
||||
|
||||
.blur-info {
|
||||
grid-column: span 6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: deprecated.$s-1;
|
||||
flex-grow: 1;
|
||||
border-radius: deprecated.$br-8;
|
||||
background-color: var(--input-details-color);
|
||||
.show-more {
|
||||
background-color: var(--color-background-tertiary);
|
||||
border: $b-1 solid var(--color-background-tertiary);
|
||||
border-radius: $br-8 0 0 $br-8;
|
||||
|
||||
.show-more {
|
||||
@extend %button-secondary;
|
||||
|
||||
height: deprecated.$s-32;
|
||||
width: deprecated.$s-28;
|
||||
border-radius: deprecated.$br-8 0 0 deprecated.$br-8;
|
||||
box-sizing: border-box;
|
||||
border: deprecated.$s-1 solid var(--button-secondary-background-color-rest);
|
||||
|
||||
svg {
|
||||
@extend %button-icon;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: var(--button-radio-background-color-active);
|
||||
|
||||
svg {
|
||||
stroke: var(--button-radio-foreground-color-active);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
@include deprecated.body-small-typography;
|
||||
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: deprecated.$s-32;
|
||||
padding: 0 deprecated.$s-8;
|
||||
border-radius: 0 deprecated.$br-8 deprecated.$br-8 0;
|
||||
background-color: var(--input-background-color);
|
||||
color: var(--menu-foreground-color);
|
||||
box-sizing: border-box;
|
||||
border: deprecated.$s-1 solid var(--input-border-color);
|
||||
}
|
||||
|
||||
.blur-type-select {
|
||||
flex-grow: 1;
|
||||
border-radius: 0 deprecated.$br-8 deprecated.$br-8 0;
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--color-background-quaternary);
|
||||
border: $b-1 solid var(--color-background-quaternary);
|
||||
}
|
||||
|
||||
.actions {
|
||||
@include deprecated.flex-row;
|
||||
&:disabled {
|
||||
background-color: var(--color-background-primary);
|
||||
border-block-start: $b-1 solid var(--color-background-quaternary);
|
||||
border-block-end: $b-1 solid var(--color-background-quaternary);
|
||||
border-inline-start: $b-1 solid var(--color-background-quaternary);
|
||||
}
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
.blur-info {
|
||||
@include deprecated.hidden-element;
|
||||
.blur-info {
|
||||
grid-column: span 6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
gap: 1px;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--color-background-primary);
|
||||
}
|
||||
|
||||
.show-more {
|
||||
@include deprecated.hidden-element;
|
||||
.mixed-label {
|
||||
@include t.use-typography("body-small");
|
||||
|
||||
border: deprecated.$s-1 solid var(--input-border-color-disabled);
|
||||
}
|
||||
grid-column: span 7;
|
||||
gap: 1px;
|
||||
border-radius: $br-8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
height: $sz-32;
|
||||
padding: 0 var(--sp-s);
|
||||
background-color: var(--color-background-tertiary);
|
||||
border: $b-1 solid var(--color-background-tertiary);
|
||||
color: var(--color-foreground-primary);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.label {
|
||||
@include deprecated.hidden-element;
|
||||
.disabled-label-tooltip {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
border: deprecated.$s-1 solid var(--input-border-color-disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
.label {
|
||||
@include t.use-typography("body-small");
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
height: $sz-32;
|
||||
padding: 0 var(--sp-s);
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
background-color: var(--color-background-tertiary);
|
||||
border: $b-1 solid var(--color-background-tertiary);
|
||||
color: var(--color-foreground-primary);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.blur-type-select {
|
||||
flex-grow: 1;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
.hidden .blur-info,
|
||||
.hidden .blur-info .label {
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
box-sizing: border-box;
|
||||
color: var(--color-foreground-secondary);
|
||||
stroke: var(--color-foreground-secondary);
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.hidden .blur-info .label {
|
||||
border: $b-1 solid var(--color-background-quaternary);
|
||||
}
|
||||
|
||||
.second-row {
|
||||
@extend %input-element;
|
||||
@include deprecated.body-small-typography;
|
||||
|
||||
width: deprecated.$s-92;
|
||||
|
||||
.label {
|
||||
padding-left: deprecated.$s-8;
|
||||
width: deprecated.$s-60;
|
||||
}
|
||||
width: var(--three-columns-width);
|
||||
}
|
||||
|
||||
.disabled-label {
|
||||
color: var(--color-foreground-secondary);
|
||||
background-color: var(--color-background-primary);
|
||||
border-top: $b-1 solid var(--color-background-quaternary);
|
||||
border-bottom: $b-1 solid var(--color-background-quaternary);
|
||||
border-right: $b-1 solid var(--color-background-quaternary);
|
||||
border-left: $b-1 solid transparent;
|
||||
}
|
||||
|
||||
@ -451,5 +451,5 @@
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "settings.select-this-color")
|
||||
:on-click handle-select
|
||||
:tooltip-position "top-left"
|
||||
:tooltip-placement "top-left"
|
||||
:icon i/move}])]))
|
||||
|
||||
@ -135,7 +135,7 @@
|
||||
|
||||
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
|
||||
[:> blur-menu* {:ids ids
|
||||
:values (select-keys shape [:blur])}]
|
||||
:values (select-keys shape [:blur :background-blur])}]
|
||||
|
||||
[:> exports-menu* {:type type
|
||||
:ids ids
|
||||
|
||||
@ -132,7 +132,7 @@
|
||||
:applied-tokens applied-tokens}]
|
||||
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
|
||||
[:> blur-menu* {:ids ids
|
||||
:values (select-keys shape [:blur])}]
|
||||
:values (select-keys shape [:blur :background-blur])}]
|
||||
[:> svg-attrs-menu* {:ids ids
|
||||
:values (select-keys shape [:svg-attrs])}]
|
||||
[:> exports-menu* {:type type
|
||||
|
||||
@ -159,7 +159,7 @@
|
||||
:libraries libraries}]
|
||||
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
|
||||
[:> blur-menu* {:ids ids
|
||||
:values (select-keys shape [:blur])}]
|
||||
:values (select-keys shape [:blur :background-blur])}]
|
||||
[:> frame-grid* {:shape shape}]
|
||||
[:> exports-menu* {:type shape-type
|
||||
:ids ids
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
:fill :shape
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
:background-blur :shape
|
||||
:stroke :shape
|
||||
:text :children
|
||||
:exports :shape
|
||||
@ -61,6 +62,7 @@
|
||||
:fill :children
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
:background-blur :shape
|
||||
:stroke :children
|
||||
:text :children
|
||||
:exports :shape
|
||||
@ -74,6 +76,7 @@
|
||||
:fill :shape
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
:background-blur :shape
|
||||
:stroke :shape
|
||||
:text :ignore
|
||||
:exports :shape
|
||||
@ -87,6 +90,7 @@
|
||||
:fill :text
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
:background-blur :shape
|
||||
:stroke :shape
|
||||
:text :text
|
||||
:exports :shape
|
||||
@ -100,6 +104,7 @@
|
||||
:fill :ignore
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
:background-blur :shape
|
||||
:stroke :ignore
|
||||
:text :ignore
|
||||
:exports :shape
|
||||
@ -113,6 +118,7 @@
|
||||
:fill :shape
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
:background-blur :shape
|
||||
:stroke :shape
|
||||
:text :ignore
|
||||
:exports :shape
|
||||
@ -126,6 +132,7 @@
|
||||
:fill :shape
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
:background-blur :shape
|
||||
:stroke :shape
|
||||
:text :ignore
|
||||
:exports :shape
|
||||
@ -139,6 +146,7 @@
|
||||
:fill :shape
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
:background-blur :shape
|
||||
:stroke :shape
|
||||
:text :ignore
|
||||
:exports :shape
|
||||
@ -152,6 +160,7 @@
|
||||
:fill :shape
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
:background-blur :shape
|
||||
:stroke :shape
|
||||
:text :ignore
|
||||
:exports :shape
|
||||
|
||||
@ -133,7 +133,7 @@
|
||||
:applied-tokens applied-tokens}]
|
||||
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
|
||||
[:> blur-menu* {:ids ids
|
||||
:values (select-keys shape [:blur])}]
|
||||
:values (select-keys shape [:blur :background-blur])}]
|
||||
[:> svg-attrs-menu* {:ids ids
|
||||
:values (select-keys shape [:svg-attrs])}]
|
||||
[:> exports-menu* {:type type
|
||||
|
||||
@ -134,7 +134,7 @@
|
||||
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
|
||||
|
||||
[:> blur-menu* {:ids ids
|
||||
:values (select-keys shape [:blur])}]
|
||||
:values (select-keys shape [:blur :background-blur])}]
|
||||
|
||||
[:> svg-attrs-menu* {:ids ids
|
||||
:values (select-keys shape [:svg-attrs])}]
|
||||
|
||||
@ -201,7 +201,7 @@
|
||||
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
|
||||
|
||||
[:> blur-menu* {:ids ids
|
||||
:values (select-keys shape [:blur])}]
|
||||
:values (select-keys shape [:blur :background-blur])}]
|
||||
|
||||
[:> svg-attrs-menu* {:ids ids
|
||||
:values (select-keys shape [:svg-attrs])}]
|
||||
|
||||
@ -211,7 +211,7 @@
|
||||
|
||||
[:> blur-menu*
|
||||
{:ids ids
|
||||
:values (select-keys shape [:blur])}]
|
||||
:values (select-keys shape [:blur :background-blur])}]
|
||||
|
||||
[:> exports-menu* {:type type
|
||||
:ids ids
|
||||
|
||||
@ -232,16 +232,14 @@
|
||||
|
||||
;; export interface Blur {
|
||||
;; id?: string;
|
||||
;; type?: 'layer-blur';
|
||||
;; value?: number;
|
||||
;; hidden?: boolean;
|
||||
;; }
|
||||
(defn format-blur
|
||||
[{:keys [id type value hidden] :as blur}]
|
||||
[{:keys [id value hidden] :as blur}]
|
||||
(when (some? blur)
|
||||
(obj/without-empty
|
||||
#js {:id (format-id id)
|
||||
:type (format-key type)
|
||||
:value value
|
||||
:hidden hidden})))
|
||||
|
||||
|
||||
@ -237,7 +237,6 @@
|
||||
|
||||
;; export interface Blur {
|
||||
;; id?: string;
|
||||
;; type?: 'layer-blur';
|
||||
;; value?: number;
|
||||
;; hidden?: boolean;
|
||||
;; }
|
||||
@ -246,7 +245,6 @@
|
||||
(when (some? blur)
|
||||
(d/without-nils
|
||||
{:id (-> (obj/get blur "id") parse-id)
|
||||
:type (-> (obj/get blur "type") parse-keyword)
|
||||
:value (obj/get blur "value")
|
||||
:hidden (obj/get blur "hidden")})))
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
[app.common.types.grid :as ctg]
|
||||
[app.common.types.path :as path]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape.background-blur :as ctsbb]
|
||||
[app.common.types.shape.blur :as ctsb]
|
||||
[app.common.types.shape.export :as ctse]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
@ -176,6 +177,15 @@
|
||||
:hidden false}
|
||||
blur))
|
||||
|
||||
(defn- background-blur-defaults
|
||||
[blur]
|
||||
(d/patch-object
|
||||
{:id (uuid/next)
|
||||
:type :background-blur
|
||||
:value 4
|
||||
:hidden false}
|
||||
blur))
|
||||
|
||||
(defn commit-fills!
|
||||
[plugin-id ^js self value]
|
||||
(let [shape (u/proxy->shape self)
|
||||
@ -499,7 +509,8 @@
|
||||
(if (nil? value)
|
||||
(st/emit! (dwsh/update-shapes [id] #(dissoc % :blur)))
|
||||
(let [id (obj/get self "$id")
|
||||
value (blur-defaults (parser/parse-blur value))]
|
||||
value (blur-defaults (parser/parse-blur value))
|
||||
value (assoc value :type :layer-blur)]
|
||||
(cond
|
||||
(not (sm/validate ctsb/schema:blur value))
|
||||
(u/not-valid plugin-id :blur value)
|
||||
@ -510,6 +521,26 @@
|
||||
:else
|
||||
(st/emit! (dwsh/update-shapes [id] #(assoc % :blur value)))))))}
|
||||
|
||||
:background-blur
|
||||
{:this true
|
||||
:get #(-> % u/proxy->shape :background-blur format/format-blur)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (nil? value)
|
||||
(st/emit! (dwsh/update-shapes [id] #(dissoc % :background-blur)))
|
||||
(let [id (obj/get self "$id")
|
||||
value (background-blur-defaults (parser/parse-blur value))
|
||||
value (assoc value :type :background-blur)]
|
||||
(cond
|
||||
(not (sm/validate ctsbb/schema:background-blur value))
|
||||
(u/not-valid plugin-id :background-blur value)
|
||||
|
||||
(not (r/check-permission plugin-id "content:write"))
|
||||
(u/not-valid plugin-id :background-blur "Plugin doesn't have 'content:write' permission")
|
||||
|
||||
:else
|
||||
(st/emit! (dwsh/update-shapes [id] #(assoc % :background-blur value)))))))}
|
||||
|
||||
:exports
|
||||
{:this true
|
||||
:get #(-> % u/proxy->shape :exports format/format-exports)
|
||||
|
||||
@ -959,12 +959,21 @@
|
||||
|
||||
(defn set-shape-blur
|
||||
[blur]
|
||||
(if (some? blur)
|
||||
(let [type (-> blur :type sr/translate-blur-type)
|
||||
hidden (:hidden blur)
|
||||
value (:value blur)]
|
||||
(h/call wasm/internal-module "_set_shape_blur" type hidden value))
|
||||
(h/call wasm/internal-module "_clear_shape_blur")))
|
||||
(let [type (sr/translate-blur-type :layer-blur)]
|
||||
(if (some? blur)
|
||||
(let [hidden (:hidden blur)
|
||||
value (:value blur)]
|
||||
(h/call wasm/internal-module "_set_shape_blur" type hidden value))
|
||||
(h/call wasm/internal-module "_clear_shape_blur" type))))
|
||||
|
||||
(defn set-shape-background-blur
|
||||
[background-blur]
|
||||
(let [type (sr/translate-blur-type :background-blur)]
|
||||
(if (some? background-blur)
|
||||
(let [hidden (:hidden background-blur)
|
||||
value (:value background-blur)]
|
||||
(h/call wasm/internal-module "_set_shape_blur" type hidden value))
|
||||
(h/call wasm/internal-module "_clear_shape_blur" type))))
|
||||
|
||||
(defn set-shape-corners
|
||||
[corners]
|
||||
@ -1346,6 +1355,7 @@
|
||||
bool-type (get shape :bool-type)
|
||||
grow-type (get shape :grow-type)
|
||||
blur (get shape :blur)
|
||||
background-blur (get shape :background-blur)
|
||||
svg-attrs (get shape :svg-attrs)
|
||||
shadows (get shape :shadow)]
|
||||
|
||||
@ -1354,6 +1364,7 @@
|
||||
;; Remaining properties that need separate calls (variable-length or conditional)
|
||||
(set-shape-children children)
|
||||
(set-shape-blur blur)
|
||||
(set-shape-background-blur background-blur)
|
||||
(when (= type :group)
|
||||
(set-masked (boolean masked)))
|
||||
(when (= type :bool)
|
||||
|
||||
@ -187,6 +187,9 @@
|
||||
:blur
|
||||
(api/set-shape-blur v)
|
||||
|
||||
:background-blur
|
||||
(api/set-shape-background-blur v)
|
||||
|
||||
:shadow
|
||||
(api/set-shape-shadows v)
|
||||
|
||||
@ -230,6 +233,7 @@
|
||||
;; Always update fills/blur/shadow to clear previous state if filters disappear
|
||||
(api/set-shape-fills id (:fills shape) false)
|
||||
(api/set-shape-blur (:blur shape))
|
||||
(api/set-shape-background-blur (:background-blur shape))
|
||||
(api/set-shape-shadows (:shadow shape)))
|
||||
|
||||
:masked-group
|
||||
|
||||
@ -45,7 +45,6 @@
|
||||
(set! context-initialized? false)
|
||||
(reset! context-lost? false))
|
||||
|
||||
|
||||
(defonce serializers
|
||||
#js {:blur-type shared/RawBlurType
|
||||
:blend-mode shared/RawBlendMode
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
:border-color :border-color
|
||||
:box-shadow :shadows
|
||||
:filter :blur
|
||||
:backdrop-filter :blur
|
||||
:backdrop-filter :background-blur
|
||||
:gap :size-array
|
||||
:row-gap :size-array
|
||||
:column-gap :size-array
|
||||
@ -202,5 +202,6 @@
|
||||
:tracks (format-tracks value)
|
||||
:shadows (format-shadow value options)
|
||||
:blur (format-blur value)
|
||||
:background-blur (format-blur value)
|
||||
:matrix (format-matrix value)
|
||||
(if (keyword? value) (d/name value) value))))
|
||||
|
||||
@ -256,14 +256,12 @@
|
||||
(defn- get-filter
|
||||
[shape]
|
||||
(when-not (cgc/svg-markup? shape)
|
||||
(when (= :layer-blur (get-in shape [:blur :type]))
|
||||
(get-in shape [:blur :value]))))
|
||||
(get-in shape [:blur :value])))
|
||||
|
||||
(defn- get-backdrop-filter
|
||||
[shape]
|
||||
(when-not (cgc/svg-markup? shape)
|
||||
(when (= :background-blur (get-in shape [:blur :type]))
|
||||
(get-in shape [:blur :value]))))
|
||||
(get-in shape [:background-blur :value])))
|
||||
|
||||
(defn- get-display
|
||||
[shape]
|
||||
|
||||
@ -190,7 +190,6 @@
|
||||
|
||||
(t/testing " - blur"
|
||||
(set! (.-blur shape) #js {:value 10})
|
||||
(t/is (= (-> (. shape -blur) (aget "type")) "layer-blur"))
|
||||
(t/is (= (-> (. shape -blur) (aget "value")) 10))
|
||||
(t/is (= (-> (. shape -blur) (aget "hidden")) false))
|
||||
(let [id (-> (. shape -blur) (aget "id") uuid/uuid)]
|
||||
|
||||
@ -2755,6 +2755,10 @@ msgstr "Bad Gateway"
|
||||
msgid "labels.blur"
|
||||
msgstr "Blur"
|
||||
|
||||
#: src/app/main/ui/inspect/styles/style_box.cljs
|
||||
msgid "labels.blur-effects"
|
||||
msgstr "Blur effects"
|
||||
|
||||
#: src/app/main/data/common.cljs:119, src/app/main/ui/dashboard/change_owner.cljs:67, src/app/main/ui/dashboard/change_owner.cljs:174, src/app/main/ui/dashboard/import.cljs:543, src/app/main/ui/dashboard/team.cljs:866, src/app/main/ui/dashboard/team.cljs:1345, src/app/main/ui/delete_shared.cljs:36, src/app/main/ui/exports/assets.cljs:163, src/app/main/ui/exports/files.cljs:167, src/app/main/ui/settings/integrations.cljs:228, src/app/main/ui/viewer/share_link.cljs:204, src/app/main/ui/workspace/sidebar/assets/groups.cljs:178, src/app/main/ui/workspace/tokens/export/modal.cljs:43, src/app/main/ui/workspace/tokens/import/modal.cljs:268, src/app/main/ui/workspace/tokens/import_from_library.cljs:88, src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs:364, src/app/main/ui/workspace/tokens/management/forms/rename_node_modal.cljs:73, src/app/main/ui/workspace/tokens/settings/menu.cljs:104, src/app/main/ui/workspace/tokens/themes/create_modal.cljs:242
|
||||
msgid "labels.cancel"
|
||||
msgstr "Cancel"
|
||||
@ -7177,10 +7181,30 @@ msgstr "Layer blur"
|
||||
msgid "workspace.options.blur-options.remove-blur"
|
||||
msgstr "Remove blur"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-options.toggle-more-options"
|
||||
msgstr "Show/hide more options"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-options.disabled-blur-label"
|
||||
msgstr "Background blur is only supported in the new render. Switch to the new render in the Preferences menu to use this effect"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs:113, src/app/main/ui/workspace/sidebar/options/menus/blur.cljs:138
|
||||
msgid "workspace.options.blur-options.title"
|
||||
msgstr "Blur"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-effects-options.title"
|
||||
msgstr "Blur effects"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-effects-options.title.group"
|
||||
msgstr "Group blur effects"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-effects-options.title.multiple"
|
||||
msgstr "Selection blur effects"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs:112
|
||||
msgid "workspace.options.blur-options.title.group"
|
||||
msgstr "Group blur"
|
||||
@ -7193,6 +7217,10 @@ msgstr "Selection blur"
|
||||
msgid "workspace.options.blur-options.toggle-blur"
|
||||
msgstr "Toggle blur"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-options.blur-type-select"
|
||||
msgstr "Blur type select"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/page.cljs:60, src/app/main/ui/workspace/sidebar/options/page.cljs:68
|
||||
msgid "workspace.options.canvas-background"
|
||||
msgstr "Canvas background"
|
||||
|
||||
@ -2685,6 +2685,10 @@ msgstr "Error del servidor (Bad Gateway)"
|
||||
msgid "labels.blur"
|
||||
msgstr "Desenfoque"
|
||||
|
||||
#: src/app/main/ui/inspect/styles/style_box.cljs
|
||||
msgid "labels.blur-effects"
|
||||
msgstr "Efectos de desenfoque"
|
||||
|
||||
#: src/app/main/data/common.cljs:119, src/app/main/ui/dashboard/change_owner.cljs:67, src/app/main/ui/dashboard/change_owner.cljs:174, src/app/main/ui/dashboard/import.cljs:543, src/app/main/ui/dashboard/team.cljs:866, src/app/main/ui/dashboard/team.cljs:1345, src/app/main/ui/delete_shared.cljs:36, src/app/main/ui/exports/assets.cljs:163, src/app/main/ui/exports/files.cljs:167, src/app/main/ui/settings/integrations.cljs:228, src/app/main/ui/viewer/share_link.cljs:204, src/app/main/ui/workspace/sidebar/assets/groups.cljs:178, src/app/main/ui/workspace/tokens/export/modal.cljs:43, src/app/main/ui/workspace/tokens/import/modal.cljs:268, src/app/main/ui/workspace/tokens/import_from_library.cljs:88, src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs:364, src/app/main/ui/workspace/tokens/management/forms/rename_node_modal.cljs:73, src/app/main/ui/workspace/tokens/settings/menu.cljs:104, src/app/main/ui/workspace/tokens/themes/create_modal.cljs:242
|
||||
msgid "labels.cancel"
|
||||
msgstr "Cancelar"
|
||||
@ -7004,10 +7008,30 @@ msgstr "Desenfoque de capa"
|
||||
msgid "workspace.options.blur-options.remove-blur"
|
||||
msgstr "Eliminar desenfoque"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-options.toggle-more-options"
|
||||
msgstr "Mostrar/ocultar más opciones"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-options.disabled-blur-label"
|
||||
msgstr "El desenfoque de fondo (Background Blur) solo está disponible en el nuevo motor de renderizado. Actívalo desde el menú de Preferencias para utilizar este efecto."
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs:113, src/app/main/ui/workspace/sidebar/options/menus/blur.cljs:138
|
||||
msgid "workspace.options.blur-options.title"
|
||||
msgstr "Desenfoque"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-effects-options.title"
|
||||
msgstr "Efectos de desenfoque"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-effects-options.title.group"
|
||||
msgstr "Efectos de desenfoque del grupo"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-effects-options.title.multiple"
|
||||
msgstr "Efectos de desenfoque de la selección"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs:112
|
||||
msgid "workspace.options.blur-options.title.group"
|
||||
msgstr "Desenfoque del grupo"
|
||||
@ -7020,6 +7044,10 @@ msgstr "Desenfoque de la selección"
|
||||
msgid "workspace.options.blur-options.toggle-blur"
|
||||
msgstr "Mostrar/ocultar desenfoque"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/blur.cljs
|
||||
msgid "workspace.options.blur-options.blur-type-select"
|
||||
msgstr "Selector de tipo de desenfoque"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/page.cljs:60, src/app/main/ui/workspace/sidebar/options/page.cljs:68
|
||||
msgid "workspace.options.canvas-background"
|
||||
msgstr "Color de fondo"
|
||||
|
||||
12
plugins/libs/plugin-types/index.d.ts
vendored
12
plugins/libs/plugin-types/index.d.ts
vendored
@ -194,11 +194,6 @@ export interface Blur {
|
||||
* The optional unique identifier for the blur effect.
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* The optional type of the blur effect.
|
||||
* Currently, only 'layer-blur' is supported.
|
||||
*/
|
||||
type?: 'layer-blur';
|
||||
/**
|
||||
* The optional intensity value of the blur effect.
|
||||
*/
|
||||
@ -3717,6 +3712,13 @@ export interface ShapeBase extends PluginData {
|
||||
*/
|
||||
blur?: Blur;
|
||||
|
||||
/**
|
||||
* The background blur effect applied to the shape.
|
||||
* Background blur creates a blur effect on the content behind the shape,
|
||||
* rather than on the shape's own content.
|
||||
*/
|
||||
backgroundBlur?: Blur;
|
||||
|
||||
/**
|
||||
* The export settings of the shape.
|
||||
*/
|
||||
|
||||
@ -649,10 +649,7 @@ impl RenderState {
|
||||
{
|
||||
return;
|
||||
}
|
||||
let blur = match shape
|
||||
.blur
|
||||
.filter(|b| !b.hidden && b.blur_type == BlurType::BackgroundBlur)
|
||||
{
|
||||
let blur = match shape.visible_background_blur() {
|
||||
Some(blur) => blur,
|
||||
None => return,
|
||||
};
|
||||
@ -1208,6 +1205,7 @@ impl RenderState {
|
||||
&& parent_shadows.is_none()
|
||||
&& !shape.needs_layer()
|
||||
&& shape.blur.is_none()
|
||||
&& shape.background_blur.is_none()
|
||||
&& !has_inherited_blur
|
||||
&& shape.shadows.is_empty()
|
||||
&& shape.transform.is_identity()
|
||||
@ -1317,20 +1315,9 @@ impl RenderState {
|
||||
// We don't want to change the value in the global state
|
||||
let mut shape: Cow<Shape> = Cow::Borrowed(shape);
|
||||
|
||||
// Remove background blur from the shape so it doesn't get processed
|
||||
// as a layer blur. The actual rendering is done before the save_layer
|
||||
// in render_background_blur() so it's independent of shape opacity.
|
||||
if !skip_effects
|
||||
&& apply_to_current_surface
|
||||
&& fills_surface_id == SurfaceId::Fills
|
||||
&& !matches!(shape.shape_type, Type::Text(_))
|
||||
&& !matches!(shape.shape_type, Type::SVGRaw(_))
|
||||
&& shape
|
||||
.blur
|
||||
.is_some_and(|b| !b.hidden && b.blur_type == BlurType::BackgroundBlur)
|
||||
{
|
||||
shape.to_mut().set_blur(None);
|
||||
}
|
||||
// Background blur is stored separately (shape.background_blur) and is
|
||||
// rendered before the save_layer in render_background_blur(), so here
|
||||
// shape.blur only ever holds a layer blur.
|
||||
|
||||
let frame_has_blur = Self::frame_clip_layer_blur(&shape).is_some();
|
||||
let shape_has_blur = shape.blur.is_some();
|
||||
@ -2838,6 +2825,7 @@ impl RenderState {
|
||||
|
||||
plain_shape_mut.clear_shadows();
|
||||
plain_shape_mut.blur = None;
|
||||
plain_shape_mut.background_blur = None;
|
||||
|
||||
// Shadow rendering uses a single render_shape call with no render_shape_exit,
|
||||
// so strokes must be drawn here. Disable clip_content to avoid skip_strokes
|
||||
@ -3641,10 +3629,8 @@ impl RenderState {
|
||||
// assigned to this tile) because the blur snapshots Current
|
||||
// which must contain the shapes behind it.
|
||||
let tile_has_bg_blur = ids.iter().any(|id| {
|
||||
tree.get(id).is_some_and(|s| {
|
||||
s.blur
|
||||
.is_some_and(|b| !b.hidden && b.blur_type == BlurType::BackgroundBlur)
|
||||
})
|
||||
tree.get(id)
|
||||
.is_some_and(|s| s.visible_background_blur().is_some())
|
||||
});
|
||||
|
||||
// We only need first level shapes, in the same order as the parent node.
|
||||
|
||||
@ -188,6 +188,7 @@ pub struct Shape {
|
||||
pub blend_mode: BlendMode,
|
||||
pub vertical_align: VerticalAlign,
|
||||
pub blur: Option<Blur>,
|
||||
pub background_blur: Option<Blur>,
|
||||
pub opacity: f32,
|
||||
pub hidden: bool,
|
||||
pub svg: Option<skia::svg::Dom>,
|
||||
@ -291,6 +292,7 @@ impl Shape {
|
||||
opacity: 1.,
|
||||
hidden: false,
|
||||
blur: None,
|
||||
background_blur: None,
|
||||
svg: None,
|
||||
svg_attrs: None,
|
||||
shadows: Vec::with_capacity(1),
|
||||
@ -314,6 +316,10 @@ impl Shape {
|
||||
blur.scale_content(value);
|
||||
}
|
||||
|
||||
if let Some(background_blur) = self.background_blur.as_mut() {
|
||||
background_blur.scale_content(value);
|
||||
}
|
||||
|
||||
self.layout_item
|
||||
.iter_mut()
|
||||
.for_each(|i| i.scale_content(value));
|
||||
@ -631,6 +637,15 @@ impl Shape {
|
||||
self.blur = blur;
|
||||
}
|
||||
|
||||
pub fn set_background_blur(&mut self, blur: Option<Blur>) {
|
||||
self.invalidate_extrect();
|
||||
self.background_blur = blur;
|
||||
}
|
||||
|
||||
pub fn visible_background_blur(&self) -> Option<Blur> {
|
||||
self.background_blur.filter(|blur| !blur.hidden)
|
||||
}
|
||||
|
||||
pub fn add_child(&mut self, id: Uuid) {
|
||||
self.children.push(id);
|
||||
}
|
||||
@ -1421,6 +1436,7 @@ impl Shape {
|
||||
}
|
||||
|
||||
self.blur.is_none()
|
||||
&& self.background_blur.is_none()
|
||||
&& self.shadows.is_empty()
|
||||
&& (self.opacity - 1.0).abs() <= 1e-4
|
||||
&& self.blend_mode().0 == skia::BlendMode::SrcOver
|
||||
@ -1665,7 +1681,7 @@ impl Shape {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.blur.is_some() {
|
||||
if self.blur.is_some() || self.background_blur.is_some() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1805,6 +1821,38 @@ mod tests {
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn layer_blur_and_background_blur_can_coexist() {
|
||||
let mut shape = any_shape();
|
||||
|
||||
let layer_blur = Blur::new(BlurType::LayerBlur, false, 4.0);
|
||||
let background_blur = Blur::new(BlurType::BackgroundBlur, false, 8.0);
|
||||
|
||||
shape.set_blur(Some(layer_blur));
|
||||
shape.set_background_blur(Some(background_blur));
|
||||
|
||||
assert_eq!(shape.blur, Some(layer_blur));
|
||||
assert_eq!(shape.background_blur, Some(background_blur));
|
||||
assert_eq!(shape.visible_background_blur(), Some(background_blur));
|
||||
|
||||
// Clearing one type must not affect the other.
|
||||
shape.set_blur(None);
|
||||
assert_eq!(shape.blur, None);
|
||||
assert_eq!(shape.background_blur, Some(background_blur));
|
||||
|
||||
shape.set_blur(Some(layer_blur));
|
||||
shape.set_background_blur(None);
|
||||
assert_eq!(shape.blur, Some(layer_blur));
|
||||
assert_eq!(shape.background_blur, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hidden_background_blur_is_not_visible() {
|
||||
let mut shape = any_shape();
|
||||
shape.set_background_blur(Some(Blur::new(BlurType::BackgroundBlur, true, 8.0)));
|
||||
assert_eq!(shape.visible_background_blur(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_corners() {
|
||||
let mut shape = any_shape();
|
||||
|
||||
@ -29,14 +29,21 @@ impl From<RawBlurType> for BlurType {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn set_shape_blur(blur_type: u8, hidden: bool, value: f32) {
|
||||
with_current_shape_mut!(state, |shape: &mut Shape| {
|
||||
let blur_type = RawBlurType::from(blur_type);
|
||||
shape.set_blur(Some(Blur::new(blur_type.into(), hidden, value)));
|
||||
let blur_type: BlurType = RawBlurType::from(blur_type).into();
|
||||
let blur = Some(Blur::new(blur_type, hidden, value));
|
||||
match blur_type {
|
||||
BlurType::LayerBlur => shape.set_blur(blur),
|
||||
BlurType::BackgroundBlur => shape.set_background_blur(blur),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn clear_shape_blur() {
|
||||
pub extern "C" fn clear_shape_blur(blur_type: u8) {
|
||||
with_current_shape_mut!(state, |shape: &mut Shape| {
|
||||
shape.set_blur(None);
|
||||
match RawBlurType::from(blur_type).into() {
|
||||
BlurType::LayerBlur => shape.set_blur(None),
|
||||
BlurType::BackgroundBlur => shape.set_background_blur(None),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user