mirror of
https://github.com/penpot/penpot.git
synced 2026-06-15 11:52:10 +00:00
🎉 Add background blur
This commit is contained in:
parent
726a0cf89f
commit
f2d58e970a
@ -38,13 +38,13 @@
|
||||
(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))
|
||||
|
||||
;; Background blur won't work in current SVG specification
|
||||
;; We can revisit this in the future
|
||||
#_(->> shape :background-blur list (apply-filters :type :background-blur))
|
||||
(->> shape :blur list (apply-filters :type :layer-blur))))
|
||||
|
||||
(defn- calculate-filter-bounds
|
||||
@ -100,17 +100,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 +238,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]])
|
||||
|
||||
@ -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 {: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 {: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)]
|
||||
[:*
|
||||
(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)))
|
||||
|
||||
@ -217,8 +217,8 @@
|
||||
:penpot:spread (str spread)}])))
|
||||
|
||||
(defn- export-blur-data [{:keys [blur]}]
|
||||
(when-let [{:keys [type hidden value]} blur]
|
||||
(mf/html
|
||||
(when-let [{:keys [type hidden value]} blur]
|
||||
(mf/html
|
||||
[:> "penpot:blur"
|
||||
#js {:penpot:blur-type (d/name type)
|
||||
:penpot:hidden (str hidden)
|
||||
|
||||
@ -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,279 @@
|
||||
[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")}]]
|
||||
|
||||
[:*
|
||||
[: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}]
|
||||
(if bg-blur?
|
||||
[:> select* {:class (stl/css :blur-type-select)
|
||||
:default-selected (d/name (:type value))
|
||||
:options type-options
|
||||
:disabled is-hidden
|
||||
:on-change handle-type-change}]
|
||||
[:> 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")}
|
||||
[:span {:aria-labelledby "background-blur-disabled-label"
|
||||
:ref label-ref
|
||||
:class (stl/css-case :label true
|
||||
:disabled-label (and (= blur-key :background-blur)
|
||||
(= false bg-blur?)))}
|
||||
(d/name (:type value))]])]
|
||||
|
||||
[: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)
|
||||
(< (count blur-values)
|
||||
(if bg-blur? 2 1)))
|
||||
[:> 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,7 +232,7 @@
|
||||
|
||||
;; export interface Blur {
|
||||
;; id?: string;
|
||||
;; type?: 'layer-blur';
|
||||
;; type?: 'layer-blur' | 'background-blur';
|
||||
;; value?: number;
|
||||
;; hidden?: boolean;
|
||||
;; }
|
||||
|
||||
@ -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)
|
||||
@ -510,6 +520,25 @@
|
||||
: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))]
|
||||
(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)
|
||||
|
||||
@ -945,12 +945,21 @@
|
||||
(defn set-shape-blur
|
||||
[blur]
|
||||
(if (some? blur)
|
||||
(let [type (-> blur :type sr/translate-blur-type)
|
||||
(let [type (sr/translate-blur-type :layer-blur)
|
||||
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")))
|
||||
|
||||
(defn set-shape-background-blur
|
||||
[background-blur]
|
||||
(if (some? background-blur)
|
||||
(let [type (sr/translate-blur-type :background-blur)
|
||||
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")))
|
||||
|
||||
(defn set-shape-corners
|
||||
[corners]
|
||||
(let [[r1 r2 r3 r4] (map #(d/nilv % 0) corners)]
|
||||
@ -1331,6 +1340,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)]
|
||||
|
||||
@ -1339,6 +1349,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)
|
||||
|
||||
@ -130,6 +130,7 @@
|
||||
(defn- set-wasm-attr!
|
||||
[shape k]
|
||||
(when wasm/context-initialized?
|
||||
;;TODO_BLUR: ask about this,
|
||||
(let [shape (case k
|
||||
:svg-attrs (svg-filters/apply-svg-derived (assoc shape :svg-attrs (get shape :svg-attrs)))
|
||||
(:fills :blur :shadow) (svg-filters/apply-svg-derived shape)
|
||||
@ -187,6 +188,9 @@
|
||||
:blur
|
||||
(api/set-shape-blur v)
|
||||
|
||||
:background-blur
|
||||
(api/set-shape-background-blur v)
|
||||
|
||||
:shadow
|
||||
(api/set-shape-shadows v)
|
||||
|
||||
@ -230,6 +234,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
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
(set! context-initialized? false)
|
||||
(reset! context-lost? false))
|
||||
|
||||
|
||||
;; TODO_BLUR: ask for blur-type??
|
||||
(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]
|
||||
|
||||
@ -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"
|
||||
@ -7159,10 +7163,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"
|
||||
|
||||
@ -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"
|
||||
@ -6986,10 +6990,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"
|
||||
|
||||
@ -24,6 +24,7 @@ use std::collections::{HashMap, HashSet};
|
||||
use options::RenderOptions;
|
||||
pub use surfaces::{SurfaceId, Surfaces};
|
||||
|
||||
// TODO_BLUR: should we add here BackgroundBlur
|
||||
use crate::error::{Error, Result};
|
||||
use crate::math;
|
||||
use crate::shapes::{
|
||||
@ -370,7 +371,7 @@ pub(crate) struct RenderState {
|
||||
// migration to remove group-level fills is completed, this code should be removed.
|
||||
// Frames contained in groups must reset this nested_fills stack pushing a new empty vector.
|
||||
pub nested_fills: Vec<Vec<Fill>>,
|
||||
pub nested_blurs: Vec<Option<Blur>>, // FIXME: why is this an option?
|
||||
pub nested_blurs: Vec<Option<Blur>>, // FIXME: why is this an option?, sholud be an option now? TODO_BLUR
|
||||
pub nested_shadows: Vec<Vec<Shadow>>,
|
||||
pub show_grid: Option<Uuid>,
|
||||
pub rulers: RulerState,
|
||||
@ -587,7 +588,7 @@ impl RenderState {
|
||||
backbuffer_crop_cache: HashMap::default(),
|
||||
})
|
||||
}
|
||||
|
||||
/// TODO_BLUR: ?
|
||||
/// Combines every visible layer blur currently active (ancestors + shape)
|
||||
/// into a single equivalent blur. Layer blur radii compound by adding their
|
||||
/// variances (σ² = radius²), so we:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user