mirror of
https://github.com/penpot/penpot.git
synced 2025-03-11 23:31:21 -05:00
Merge pull request #739 from penpot/feat/blending-modes
Opacity and blending modes
This commit is contained in:
commit
f0eaf9aa20
32 changed files with 555 additions and 227 deletions
|
@ -9,6 +9,7 @@
|
|||
- Duplicate and move files and projects [Taiga #267](https://tree.taiga.io/project/penpot/us/267)
|
||||
- Import SVG will create Penpot's shapes
|
||||
- Improve french translations [#731](https://github.com/penpot/penpot/pull/731)
|
||||
- Add layer opacity and blend mode to shapes
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
|
|
|
@ -394,13 +394,15 @@
|
|||
|
||||
(defn name
|
||||
"Improved version of name that won't fail if the input is not a keyword"
|
||||
[maybe-keyword]
|
||||
(cond
|
||||
(keyword? maybe-keyword)
|
||||
(core/name maybe-keyword)
|
||||
([maybe-keyword] (name maybe-keyword nil))
|
||||
([maybe-keyword default-value]
|
||||
(cond
|
||||
(keyword? maybe-keyword)
|
||||
(core/name maybe-keyword)
|
||||
|
||||
(nil? maybe-keyword) nil
|
||||
(nil? maybe-keyword) default-value
|
||||
|
||||
:else
|
||||
(str maybe-keyword)))
|
||||
:else
|
||||
(or default-value
|
||||
(str maybe-keyword)))))
|
||||
|
||||
|
|
|
@ -5545,5 +5545,140 @@
|
|||
"zh_cn" : "居中"
|
||||
},
|
||||
"permanent": true
|
||||
},
|
||||
|
||||
"workspace.options.layer-options.blend-mode.color" : {
|
||||
"translations" : {
|
||||
"en" : "Color",
|
||||
"es" : "Color"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
|
||||
"workspace.options.layer-options.blend-mode.color-burn" : {
|
||||
"translations" : {
|
||||
"en" : "Color burn",
|
||||
"es" : "Color más oscuro"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.color-dodge" : {
|
||||
"translations" : {
|
||||
"en" : "Color dodge",
|
||||
"es" : "Color más suave"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.darken" : {
|
||||
"translations" : {
|
||||
"en" : "Darken",
|
||||
"es" : "Oscurecer"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.difference" : {
|
||||
"translations" : {
|
||||
"en" : "Difference",
|
||||
"es" : "Diferencia"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.exclusion" : {
|
||||
"translations" : {
|
||||
"en" : "Exclusion",
|
||||
"en" : "Exclusión"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.hard-light" : {
|
||||
"translations" : {
|
||||
"en" : "Hard light",
|
||||
"es" : "Luz fuerte"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.hue" : {
|
||||
"translations" : {
|
||||
"en" : "Hue",
|
||||
"es" : "Tono"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.lighten" : {
|
||||
"translations" : {
|
||||
"en" : "Lighten",
|
||||
"es" : "Aclarar"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.luminosity" : {
|
||||
"translations" : {
|
||||
"en" : "Luminosity",
|
||||
"es" : "Luminosidad"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.multiply" : {
|
||||
"translations" : {
|
||||
"en" : "Multiply",
|
||||
"es" : "Multiplicar"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.normal" : {
|
||||
"translations" : {
|
||||
"en" : "Normal",
|
||||
"es" : "Normal"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.overlay" : {
|
||||
"translations" : {
|
||||
"en" : "Overlay",
|
||||
"en" : "Superponer"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.saturation" : {
|
||||
"translations" : {
|
||||
"en" : "Saturation",
|
||||
"es" : "Saturación"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.screen" : {
|
||||
"translations" : {
|
||||
"en" : "Screen",
|
||||
"en" : "Trama"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.blend-mode.soft-light" : {
|
||||
"translations" : {
|
||||
"en" : "Soft light",
|
||||
"es" : "Luz suave"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.title" : {
|
||||
"translations" : {
|
||||
"en" : "Layer",
|
||||
"es" : "Capa"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.title.group" : {
|
||||
"translations" : {
|
||||
"en" : "Group layers",
|
||||
"es" : "Capas de grupo"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
},
|
||||
"workspace.options.layer-options.title.multiple" : {
|
||||
"translations" : {
|
||||
"en" : "Selected layers",
|
||||
"es" : "Capas seleccionadas"
|
||||
},
|
||||
"used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -910,14 +910,16 @@
|
|||
.element-set-actions {
|
||||
display: flex;
|
||||
visibility: hidden;
|
||||
|
||||
}
|
||||
|
||||
.row-flex-removable:hover .element-set-actions,
|
||||
.element-set-options-group:hover .element-set-actions {
|
||||
visibility: visible;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.layer-actions {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.typography-entry {
|
||||
margin: 0.5rem 0.3rem;
|
||||
|
|
|
@ -96,6 +96,25 @@
|
|||
(merge {:stroke-style :svg} shape)
|
||||
shape)))
|
||||
|
||||
(defn setup-opacity [shape]
|
||||
(cond-> shape
|
||||
(get-in shape [:svg-attrs :opacity])
|
||||
(-> (update :svg-attrs dissoc :opacity)
|
||||
(assoc :opacity (get-in shape [:svg-attrs :opacity])))
|
||||
|
||||
(get-in shape [:svg-attrs :style :opacity])
|
||||
(-> (update-in [:svg-attrs :style] dissoc :opacity)
|
||||
(assoc :opacity (get-in shape [:svg-attrs :style :opacity])))
|
||||
|
||||
|
||||
(get-in shape [:svg-attrs :mix-blend-mode])
|
||||
(-> (update :svg-attrs dissoc :mix-blend-mode)
|
||||
(assoc :blend-mode (-> (get-in shape [:svg-attrs :mix-blend-mode]) keyword)))
|
||||
|
||||
(get-in shape [:svg-attrs :style :mix-blend-mode])
|
||||
(-> (update-in [:svg-attrs :style] dissoc :mix-blend-mode)
|
||||
(assoc :blend-mode (-> (get-in shape [:svg-attrs :style :mix-blend-mode]) keyword)))))
|
||||
|
||||
(defn create-raw-svg [name frame-id svg-data {:keys [attrs] :as data}]
|
||||
(let [{:keys [x y width height offset-x offset-y]} svg-data]
|
||||
(-> {:id (uuid/next)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
[app.util.dom :as dom]
|
||||
[app.main.store :as st]
|
||||
[app.main.data.messages :as dm]
|
||||
[app.main.ui.workspace.sidebar.options.exports :as we]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.exports :as we]))
|
||||
|
||||
(mf/defc exports
|
||||
[{:keys [shape page-id file-id] :as props}]
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[cuerdas.core :as str]
|
||||
[app.common.data :as d]
|
||||
[app.util.object :as obj]
|
||||
[app.main.ui.context :as muc]
|
||||
[app.util.svg :as usvg]))
|
||||
|
@ -86,7 +87,7 @@
|
|||
;; If contains svg-attrs the origin is svg. If it's not svg origin
|
||||
;; we setup the default fill as transparent (instead of black)
|
||||
(and (not (contains? shape :svg-attrs))
|
||||
(not (= :svg-raw (:type shape))))
|
||||
(not (#{ :svg-raw :group } (:type shape))))
|
||||
{:fill "transparent"}
|
||||
|
||||
:else
|
||||
|
@ -120,6 +121,14 @@
|
|||
(obj/merge! attrs (clj->js stroke-attrs)))
|
||||
attrs)))
|
||||
|
||||
(defn add-layer-props [attrs shape]
|
||||
(cond-> attrs
|
||||
(:opacity shape)
|
||||
(obj/set! "opacity" (:opacity shape))
|
||||
|
||||
(and (:blend-mode shape) (not= (:blend-mode shape) :normal))
|
||||
(obj/set! "mixBlendMode" (d/name (:blend-mode shape)))))
|
||||
|
||||
(defn extract-svg-attrs
|
||||
[render-id svg-defs svg-attrs]
|
||||
(let [replace-id (fn [id]
|
||||
|
@ -147,7 +156,8 @@
|
|||
styles (-> (obj/new)
|
||||
(obj/merge! svg-styles)
|
||||
(add-fill shape render-id)
|
||||
(add-stroke shape render-id))]
|
||||
(add-stroke shape render-id)
|
||||
(add-layer-props shape))]
|
||||
|
||||
(-> (obj/new)
|
||||
(obj/merge! svg-attrs)
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.typography :refer [typography-entry]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry]]
|
||||
[app.util.data :refer [matches-search]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.dom.dnd :as dnd]
|
||||
|
|
|
@ -17,19 +17,18 @@
|
|||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.align :refer [align-options]]
|
||||
[app.main.ui.workspace.sidebar.options.circle :as circle]
|
||||
[app.main.ui.workspace.sidebar.options.exports :refer [exports-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.frame :as frame]
|
||||
[app.main.ui.workspace.sidebar.options.group :as group]
|
||||
[app.main.ui.workspace.sidebar.options.icon :as icon]
|
||||
[app.main.ui.workspace.sidebar.options.image :as image]
|
||||
[app.main.ui.workspace.sidebar.options.interactions :refer [interactions-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.multiple :as multiple]
|
||||
[app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.interactions :refer [interactions-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.page :as page]
|
||||
[app.main.ui.workspace.sidebar.options.path :as path]
|
||||
[app.main.ui.workspace.sidebar.options.rect :as rect]
|
||||
[app.main.ui.workspace.sidebar.options.text :as text]
|
||||
[app.main.ui.workspace.sidebar.options.svg-raw :as svg-raw]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.circle :as circle]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.frame :as frame]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.group :as group]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.image :as image]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.multiple :as multiple]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.path :as path]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.rect :as rect]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.svg-raw :as svg-raw]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.text :as text]
|
||||
[app.util.i18n :as i18n :refer [tr t]]
|
||||
[app.util.object :as obj]
|
||||
[beicon.core :as rx]
|
||||
|
@ -46,7 +45,6 @@
|
|||
:group [:& group/options {:shape shape :shape-with-children shapes-with-children}]
|
||||
:text [:& text/options {:shape shape}]
|
||||
:rect [:& rect/options {:shape shape}]
|
||||
:icon [:& icon/options {:shape shape}]
|
||||
:circle [:& circle/options {:shape shape}]
|
||||
:path [:& path/options {:shape shape}]
|
||||
:image [:& image/options {:shape shape}]
|
||||
|
@ -106,4 +104,3 @@
|
|||
:page-id page-id
|
||||
:section section}]))
|
||||
|
||||
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.icon
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
measure-values (select-keys shape measure-attrs)
|
||||
stroke-values (select-keys shape stroke-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:ids ids
|
||||
:type type
|
||||
:values measure-values}]
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values (select-keys shape fill-attrs)}]
|
||||
[:& stroke-menu {:ids ids
|
||||
:type type
|
||||
:values stroke-values}]]))
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.blur
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.blur
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.component
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.component
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.pages :as cp]
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.exports
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.exports
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[beicon.core :as rx]
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.fill
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.fill
|
||||
(:require
|
||||
[app.common.pages :as cp]
|
||||
[app.main.data.colors :as dc]
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.frame-grid
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.frame-grid
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[okulary.core :as l]
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.interactions
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.interactions
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
|
@ -0,0 +1,141 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2020-2021 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.layer
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.math :as mth]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(def layer-attrs [:opacity :blend-mode :blocked :hidden])
|
||||
|
||||
(defn opacity->string [opacity]
|
||||
(if (= opacity :multiple)
|
||||
""
|
||||
(str (-> opacity
|
||||
(d/coalesce 1)
|
||||
(* 100)
|
||||
(mth/round)))))
|
||||
|
||||
(defn select-all [event]
|
||||
(dom/select-text! (dom/get-target event)))
|
||||
|
||||
(mf/defc layer-menu [{:keys [ids type values]}]
|
||||
(let [change!
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [prop value]
|
||||
(st/emit! (dwc/update-shapes ids #(assoc % prop value)))))
|
||||
|
||||
handle-change-blend-mode
|
||||
(mf/use-callback
|
||||
(mf/deps change!)
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target-val event) (keyword))]
|
||||
(change! :blend-mode value))))
|
||||
|
||||
handle-opacity-change
|
||||
(mf/use-callback
|
||||
(mf/deps change!)
|
||||
(fn [value]
|
||||
(let [value (-> value (/ 100))]
|
||||
(change! :opacity value))))
|
||||
|
||||
handle-set-hidden
|
||||
(mf/use-callback
|
||||
(mf/deps change!)
|
||||
(fn [event]
|
||||
(change! :hidden true)))
|
||||
|
||||
handle-set-visible
|
||||
(mf/use-callback
|
||||
(mf/deps change!)
|
||||
(fn [event]
|
||||
(change! :hidden false)))
|
||||
|
||||
handle-set-blocked
|
||||
(mf/use-callback
|
||||
(mf/deps change!)
|
||||
(fn [event]
|
||||
(change! :blocked true)))
|
||||
|
||||
handle-set-unblocked
|
||||
(mf/use-callback
|
||||
(mf/deps change!)
|
||||
(fn [event]
|
||||
(change! :blocked false)))]
|
||||
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
[:span
|
||||
(case type
|
||||
:multiple (tr "workspace.options.layer-options.title.multiple")
|
||||
:group (tr "workspace.options.layer-options.title.group")
|
||||
(tr "workspace.options.layer-options.title"))]]
|
||||
|
||||
[:div.element-set-content
|
||||
[:div.row-flex
|
||||
[:select.input-select {:on-change handle-change-blend-mode
|
||||
:value (d/name (:blend-mode values) "normal")}
|
||||
|
||||
(when (= :multiple (:blend-mode values))
|
||||
[:option {:value "multiple"} "--"])
|
||||
|
||||
[:option {:value "normal"} (tr "workspace.options.layer-options.blend-mode.normal")]
|
||||
|
||||
[:option {:value "darken"} (tr "workspace.options.layer-options.blend-mode.darken")]
|
||||
[:option {:value "multiply"} (tr "workspace.options.layer-options.blend-mode.multiply")]
|
||||
[:option {:value "color-burn"} (tr "workspace.options.layer-options.blend-mode.color-burn")]
|
||||
|
||||
[:option {:value "lighten"} (tr "workspace.options.layer-options.blend-mode.lighten")]
|
||||
[:option {:value "screen"} (tr "workspace.options.layer-options.blend-mode.screen")]
|
||||
[:option {:value "color-dodge"} (tr "workspace.options.layer-options.blend-mode.color-dodge")]
|
||||
|
||||
[:option {:value "overlay"} (tr "workspace.options.layer-options.blend-mode.overlay")]
|
||||
[:option {:value "soft-light"} (tr "workspace.options.layer-options.blend-mode.soft-light")]
|
||||
[:option {:value "hard-light"} (tr "workspace.options.layer-options.blend-mode.hard-light")]
|
||||
|
||||
[:option {:value "difference"} (tr "workspace.options.layer-options.blend-mode.difference")]
|
||||
[:option {:value "exclusion"} (tr "workspace.options.layer-options.blend-mode.exclusion")]
|
||||
|
||||
[:option {:value "hue"} (tr "workspace.options.layer-options.blend-mode.hue")]
|
||||
[:option {:value "saturation"} (tr "workspace.options.layer-options.blend-mode.saturation")]
|
||||
[:option {:value "color"} (tr "workspace.options.layer-options.blend-mode.color")]
|
||||
[:option {:value "luminosity"} (tr "workspace.options.layer-options.blend-mode.luminosity")]]
|
||||
|
||||
[:div.input-element
|
||||
{:class "percentail"}
|
||||
[:> numeric-input {:value (-> values :opacity opacity->string)
|
||||
:placeholder (tr "settings.multiple")
|
||||
:on-click select-all
|
||||
:on-change handle-opacity-change
|
||||
:min 0
|
||||
:max 100}]]
|
||||
|
||||
|
||||
[:div.element-set-actions.layer-actions
|
||||
(cond
|
||||
(or (= :multiple (:hidden values)) (not (:hidden values)))
|
||||
[:div.element-set-actions-button {:on-click handle-set-hidden} i/eye]
|
||||
|
||||
:else
|
||||
[:div.element-set-actions-button {:on-click handle-set-visible} i/eye-closed])
|
||||
|
||||
(cond
|
||||
(or (= :multiple (:blocked values)) (not (:blocked values)))
|
||||
[:div.element-set-actions-button {:on-click handle-set-blocked} i/lock-open]
|
||||
|
||||
:else
|
||||
[:div.element-set-actions-button {:on-click handle-set-unblocked} i/lock])]]]]))
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.measures
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.measures
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.icons :as i]
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.shadow
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.shadow
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.stroke
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.stroke
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.svg-attrs
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.svg-attrs
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[app.common.data :as d]
|
|
@ -7,31 +7,24 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.text
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.text
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.common.data :as d]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.store :as st]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.typography :refer [typography-entry typography-options]]
|
||||
[app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]]
|
||||
[app.util.dom :as dom]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.fonts :as fonts]
|
||||
[app.util.i18n :as i18n :refer [tr t]]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry typography-options]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.text :as ut]
|
||||
["slate" :refer [Transforms]]))
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(def text-typography-attrs [:typography-ref-id :typography-ref-file])
|
||||
(def text-fill-attrs [:fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient :fill :opacity ])
|
||||
|
@ -56,7 +49,7 @@
|
|||
(def attrs (d/concat #{} shape-attrs root-attrs paragraph-attrs text-attrs))
|
||||
|
||||
(mf/defc text-align-options
|
||||
[{:keys [editor ids values locale on-change] :as props}]
|
||||
[{:keys [editor ids values on-change] :as props}]
|
||||
(let [{:keys [text-align]} values
|
||||
|
||||
text-align (or text-align "left")
|
||||
|
@ -68,29 +61,29 @@
|
|||
;; --- Align
|
||||
[:div.align-icons
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.align-left")
|
||||
{:alt (tr "workspace.options.text-options.align-left")
|
||||
:class (dom/classnames :current (= "left" text-align))
|
||||
:on-click #(handle-change % "left")}
|
||||
i/text-align-left]
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.align-center")
|
||||
{:alt (tr "workspace.options.text-options.align-center")
|
||||
:class (dom/classnames :current (= "center" text-align))
|
||||
:on-click #(handle-change % "center")}
|
||||
i/text-align-center]
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.align-right")
|
||||
{:alt (tr "workspace.options.text-options.align-right")
|
||||
:class (dom/classnames :current (= "right" text-align))
|
||||
:on-click #(handle-change % "right")}
|
||||
i/text-align-right]
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.align-justify")
|
||||
{:alt (tr "workspace.options.text-options.align-justify")
|
||||
:class (dom/classnames :current (= "justify" text-align))
|
||||
:on-click #(handle-change % "justify")}
|
||||
i/text-align-justify]]))
|
||||
|
||||
|
||||
(mf/defc vertical-align
|
||||
[{:keys [shapes editor ids values locale on-change] :as props}]
|
||||
[{:keys [shapes editor ids values on-change] :as props}]
|
||||
(let [{:keys [vertical-align]} values
|
||||
vertical-align (or vertical-align "top")
|
||||
handle-change
|
||||
|
@ -99,23 +92,23 @@
|
|||
|
||||
[:div.align-icons
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.align-top")
|
||||
{:alt (tr "workspace.options.text-options.align-top")
|
||||
:class (dom/classnames :current (= "top" vertical-align))
|
||||
:on-click #(handle-change % "top")}
|
||||
i/align-top]
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.align-middle")
|
||||
{:alt (tr "workspace.options.text-options.align-middle")
|
||||
:class (dom/classnames :current (= "center" vertical-align))
|
||||
:on-click #(handle-change % "center")}
|
||||
i/align-middle]
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.align-bottom")
|
||||
{:alt (tr "workspace.options.text-options.align-bottom")
|
||||
:class (dom/classnames :current (= "bottom" vertical-align))
|
||||
:on-click #(handle-change % "bottom")}
|
||||
i/align-bottom]]))
|
||||
|
||||
(mf/defc grow-options
|
||||
[{:keys [editor ids values locale on-change] :as props}]
|
||||
[{:keys [editor ids values on-change] :as props}]
|
||||
(let [to-single-value (fn [coll] (if (> (count coll) 1) nil (first coll)))
|
||||
grow-type (->> values :grow-type)
|
||||
handle-change-grow
|
||||
|
@ -124,23 +117,23 @@
|
|||
|
||||
[:div.align-icons
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.grow-fixed")
|
||||
{:alt (tr "workspace.options.text-options.grow-fixed")
|
||||
:class (dom/classnames :current (= :fixed grow-type))
|
||||
:on-click #(handle-change-grow % :fixed)}
|
||||
i/auto-fix]
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.grow-auto-width")
|
||||
{:alt (tr "workspace.options.text-options.grow-auto-width")
|
||||
:class (dom/classnames :current (= :auto-width grow-type))
|
||||
:on-click #(handle-change-grow % :auto-width)}
|
||||
i/auto-width]
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.grow-auto-height")
|
||||
{:alt (tr "workspace.options.text-options.grow-auto-height")
|
||||
:class (dom/classnames :current (= :auto-height grow-type))
|
||||
:on-click #(handle-change-grow % :auto-height)}
|
||||
i/auto-height]]))
|
||||
|
||||
(mf/defc text-decoration-options
|
||||
[{:keys [editor ids values locale on-change] :as props}]
|
||||
[{:keys [editor ids values on-change] :as props}]
|
||||
(let [{:keys [text-decoration]} values
|
||||
|
||||
text-decoration (or text-decoration "none")
|
||||
|
@ -150,19 +143,19 @@
|
|||
(on-change {:text-decoration type}))]
|
||||
[:div.align-icons
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.none")
|
||||
{:alt (tr "workspace.options.text-options.none")
|
||||
:class (dom/classnames :current (= "none" text-decoration))
|
||||
:on-click #(handle-change % "none")}
|
||||
i/minus]
|
||||
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.underline")
|
||||
{:alt (tr "workspace.options.text-options.underline")
|
||||
:class (dom/classnames :current (= "underline" text-decoration))
|
||||
:on-click #(handle-change % "underline")}
|
||||
i/underline]
|
||||
|
||||
[:span.tooltip.tooltip-bottom
|
||||
{:alt (t locale "workspace.options.text-options.strikethrough")
|
||||
{:alt (tr "workspace.options.text-options.strikethrough")
|
||||
:class (dom/classnames :current (= "line-through" text-decoration))
|
||||
:on-click #(handle-change % "line-through")}
|
||||
i/strikethrough]]))
|
||||
|
@ -176,14 +169,13 @@
|
|||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [ids type editor values] :as props}]
|
||||
|
||||
(let [locale (mf/deref i18n/locale)
|
||||
current-file-id (mf/use-ctx ctx/current-file-id)
|
||||
(let [current-file-id (mf/use-ctx ctx/current-file-id)
|
||||
typographies (mf/deref refs/workspace-file-typography)
|
||||
shared-libs (mf/deref refs/workspace-libraries)
|
||||
label (case type
|
||||
:multiple (t locale "workspace.options.text-options.title-selection")
|
||||
:group (t locale "workspace.options.text-options.title-group")
|
||||
(t locale "workspace.options.text-options.title"))
|
||||
:multiple (tr "workspace.options.text-options.title-selection")
|
||||
:group (tr "workspace.options.text-options.title-group")
|
||||
(tr "workspace.options.text-options.title"))
|
||||
|
||||
emit-update!
|
||||
(fn [id attrs]
|
||||
|
@ -242,8 +234,7 @@
|
|||
:ids ids
|
||||
:values values
|
||||
:on-change (fn [attrs]
|
||||
(run! #(emit-update! % attrs) ids))
|
||||
:locale locale}]
|
||||
(run! #(emit-update! % attrs) ids))}]
|
||||
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
|
@ -261,9 +252,9 @@
|
|||
|
||||
(= (:typography-ref-id values) :multiple)
|
||||
[:div.multiple-typography
|
||||
[:div.multiple-typography-text (t locale "workspace.libraries.text.multiple-typography")]
|
||||
[:div.multiple-typography-text (tr "workspace.libraries.text.multiple-typography")]
|
||||
[:div.multiple-typography-button {:on-click handle-detach-typography
|
||||
:title (t locale "workspace.libraries.text.multiple-typography-tooltip")} i/unchain]]
|
||||
:title (tr "workspace.libraries.text.multiple-typography-tooltip")} i/unchain]]
|
||||
|
||||
:else
|
||||
[:> typography-options opts])
|
||||
|
@ -276,58 +267,5 @@
|
|||
|
||||
[:div.row-flex
|
||||
[:> grow-options opts]
|
||||
[:> text-decoration-options opts]]
|
||||
[:> text-decoration-options opts]]]]))
|
||||
|
||||
]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
|
||||
editors (mf/deref refs/editors)
|
||||
editor (get editors (:id shape))
|
||||
|
||||
measure-values (select-keys shape measure-attrs)
|
||||
|
||||
fill-values (dwt/current-text-values
|
||||
{:editor editor
|
||||
:shape shape
|
||||
:attrs text-fill-attrs})
|
||||
|
||||
fill-values (d/update-in-when fill-values [:fill-color-gradient :type] keyword)
|
||||
|
||||
fill-values (cond-> fill-values
|
||||
;; Keep for backwards compatibility
|
||||
(:fill fill-values) (assoc :fill-color (:fill fill-values))
|
||||
(:opacity fill-values) (assoc :fill-opacity (:fill fill-values)))
|
||||
|
||||
|
||||
text-values (merge
|
||||
(select-keys shape [:grow-type])
|
||||
(dwt/current-root-values
|
||||
{:editor editor :shape shape
|
||||
:attrs root-attrs})
|
||||
(dwt/current-text-values
|
||||
{:editor editor :shape shape
|
||||
:attrs paragraph-attrs})
|
||||
(dwt/current-text-values
|
||||
{:editor editor :shape shape
|
||||
:attrs text-attrs}))]
|
||||
|
||||
[:*
|
||||
[:& measures-menu {:ids ids
|
||||
:type type
|
||||
:values measure-values}]
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values fill-values
|
||||
:editor editor}]
|
||||
[:& shadow-menu {:ids ids
|
||||
:values (select-keys shape [:shadow])}]
|
||||
[:& blur-menu {:ids ids
|
||||
:values (select-keys shape [:blur])}]
|
||||
[:& text-menu {:ids ids
|
||||
:type type
|
||||
:values text-values
|
||||
:editor editor}]]))
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.typography
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.typography
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[cuerdas.core :as str]
|
|
@ -7,27 +7,32 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.circle
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.circle
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.svg-attrs :refer [svg-attrs-menu]]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
measure-values (select-keys shape measure-attrs)
|
||||
stroke-values (select-keys shape stroke-attrs)]
|
||||
stroke-values (select-keys shape stroke-attrs)
|
||||
layer-values (select-keys shape layer-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:ids ids
|
||||
:type type
|
||||
:values measure-values
|
||||
:options #{:size :position :rotation}}]
|
||||
[:& layer-menu {:ids ids
|
||||
:type type
|
||||
:values layer-values}]
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values (select-keys shape fill-attrs)}]
|
|
@ -8,7 +8,7 @@
|
|||
;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2020 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.frame
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.frame
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
|
@ -21,11 +21,12 @@
|
|||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
[app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.frame-grid :refer [frame-grid]]
|
||||
[app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
|
||||
(declare +size-presets+)
|
||||
|
||||
|
@ -299,9 +300,13 @@
|
|||
[{:keys [shape] :as props}]
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
stroke-values (select-keys shape stroke-attrs)]
|
||||
stroke-values (select-keys shape stroke-attrs)
|
||||
layer-values (select-keys shape layer-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:shape shape}]
|
||||
[:& layer-menu {:ids ids
|
||||
:type type
|
||||
:values layer-values}]
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values (select-keys shape fill-attrs)}]
|
|
@ -8,19 +8,20 @@
|
|||
;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2020 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.group
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.group
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.main.ui.workspace.sidebar.options.multiple :refer [get-attrs]]
|
||||
[app.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.component :refer [component-attrs component-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.text :as ot]
|
||||
[app.main.ui.workspace.sidebar.options.svg-attrs :refer [svg-attrs-menu]]))
|
||||
[app.main.ui.workspace.sidebar.options.shapes.multiple :refer [get-attrs]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-attrs component-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.text :as ot]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
{::mf/wrap [mf/memo]
|
||||
|
@ -32,6 +33,7 @@
|
|||
|
||||
type :group
|
||||
[measure-ids measure-values] (get-attrs [shape] objects :measure)
|
||||
[layer-ids layer-values] (get-attrs [shape] objects :layer)
|
||||
[fill-ids fill-values] (get-attrs [shape] objects :fill)
|
||||
[shadow-ids shadow-values] (get-attrs [shape] objects :shadow)
|
||||
[blur-ids blur-values] (get-attrs [shape] objects :blur)
|
||||
|
@ -42,6 +44,7 @@
|
|||
|
||||
[:div.options
|
||||
[:& measures-menu {:type type :ids measure-ids :values measure-values}]
|
||||
[:& layer-menu {:type type :ids layer-ids :values layer-values}]
|
||||
[:& component-menu {:ids comp-ids :values comp-values}]
|
||||
|
||||
(when-not (empty? fill-ids)
|
|
@ -7,22 +7,27 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.image
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.image
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
measure-values (select-keys shape measure-attrs)]
|
||||
measure-values (select-keys shape measure-attrs)
|
||||
layer-values (select-keys shape layer-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:ids ids
|
||||
:type type
|
||||
:values measure-values}]
|
||||
[:& layer-menu {:ids ids
|
||||
:type type
|
||||
:values layer-values}]
|
||||
[:& shadow-menu {:ids ids
|
||||
:values (select-keys shape [:shadow])}]
|
||||
|
|
@ -7,24 +7,26 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.multiple
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.multiple
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.attrs :as attrs]
|
||||
[app.util.text :as ut]
|
||||
[app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.shadow :refer [shadow-attrs shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.blur :refer [blur-attrs blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.text :as ot]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-attrs shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-attrs blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.text :as ot]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
|
||||
;; We define a map that goes from type to
|
||||
;; attribute and how to handle them
|
||||
(def type->props
|
||||
{:frame
|
||||
{:measure :shape
|
||||
:layer :shape
|
||||
:fill :shape
|
||||
:shadow :children
|
||||
:blur :children
|
||||
|
@ -33,6 +35,7 @@
|
|||
|
||||
:group
|
||||
{:measure :shape
|
||||
:layer :shape
|
||||
:fill :children
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
|
@ -41,6 +44,7 @@
|
|||
|
||||
:path
|
||||
{:measure :shape
|
||||
:layer :shape
|
||||
:fill :shape
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
|
@ -49,6 +53,7 @@
|
|||
|
||||
:text
|
||||
{:measure :shape
|
||||
:layer :shape
|
||||
:fill :text
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
|
@ -57,6 +62,7 @@
|
|||
|
||||
:image
|
||||
{:measure :shape
|
||||
:layer :shape
|
||||
:fill :ignore
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
|
@ -65,6 +71,7 @@
|
|||
|
||||
:rect
|
||||
{:measure :shape
|
||||
:layer :shape
|
||||
:fill :shape
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
|
@ -73,6 +80,7 @@
|
|||
|
||||
:circle
|
||||
{:measure :shape
|
||||
:layer :shape
|
||||
:fill :shape
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
|
@ -81,6 +89,7 @@
|
|||
|
||||
:svg-raw
|
||||
{:measure :shape
|
||||
:layer :shape
|
||||
:fill :shape
|
||||
:shadow :shape
|
||||
:blur :shape
|
||||
|
@ -89,6 +98,7 @@
|
|||
|
||||
(def props->attrs
|
||||
{:measure measure-attrs
|
||||
:layer layer-attrs
|
||||
:fill fill-attrs
|
||||
:shadow shadow-attrs
|
||||
:blur blur-attrs
|
||||
|
@ -169,6 +179,7 @@
|
|||
|
||||
type :multiple
|
||||
[measure-ids measure-values] (get-attrs shapes objects :measure)
|
||||
[layer-ids layer-values] (get-attrs shapes objects :layer)
|
||||
[fill-ids fill-values] (get-attrs shapes objects :fill)
|
||||
[shadow-ids shadow-values] (get-attrs shapes objects :shadow)
|
||||
[blur-ids blur-values] (get-attrs shapes objects :blur)
|
||||
|
@ -179,6 +190,9 @@
|
|||
(when-not (empty? measure-ids)
|
||||
[:& measures-menu {:type type :ids measure-ids :values measure-values}])
|
||||
|
||||
(when-not (empty? layer-ids)
|
||||
[:& layer-menu {:type type :ids layer-ids :values layer-values}])
|
||||
|
||||
(when-not (empty? fill-ids)
|
||||
[:& fill-menu {:type type :ids fill-ids :values fill-values}])
|
||||
|
|
@ -7,27 +7,32 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.path
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.path
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.svg-attrs :refer [svg-attrs-menu]]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
measure-values (select-keys shape measure-attrs)
|
||||
stroke-values (select-keys shape stroke-attrs)]
|
||||
stroke-values (select-keys shape stroke-attrs)
|
||||
layer-values (select-keys shape layer-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:ids ids
|
||||
:type type
|
||||
:values measure-values}]
|
||||
[:& layer-menu {:ids ids
|
||||
:type type
|
||||
:values layer-values}]
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values (select-keys shape fill-attrs)}]
|
|
@ -7,15 +7,16 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.rect
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.rect
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.svg-attrs :refer [svg-attrs-menu]]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
{::mf/wrap [mf/memo]}
|
||||
|
@ -23,6 +24,7 @@
|
|||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
measure-values (select-keys shape measure-attrs)
|
||||
layer-values (select-keys shape layer-attrs)
|
||||
fill-values (select-keys shape fill-attrs)
|
||||
stroke-values (select-keys shape stroke-attrs)]
|
||||
[:*
|
||||
|
@ -30,6 +32,10 @@
|
|||
:type type
|
||||
:values measure-values}]
|
||||
|
||||
[:& layer-menu {:ids ids
|
||||
:type type
|
||||
:values layer-values}]
|
||||
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values fill-values}]
|
|
@ -7,18 +7,18 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.svg-raw
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.svg-raw
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[cuerdas.core :as str]
|
||||
[app.util.data :as d]
|
||||
[app.util.color :as uc]
|
||||
[app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.svg-attrs :refer [svg-attrs-menu]]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]))
|
||||
|
||||
;; This is a list of svg tags that can be grouped in shape-container
|
||||
;; this allows them to have gradients, shadows and masks
|
|
@ -0,0 +1,72 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.text
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu text-fill-attrs root-attrs paragraph-attrs text-attrs]]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
|
||||
editors (mf/deref refs/editors)
|
||||
editor (get editors (:id shape))
|
||||
|
||||
measure-values (select-keys shape measure-attrs)
|
||||
|
||||
fill-values (dwt/current-text-values
|
||||
{:editor editor
|
||||
:shape shape
|
||||
:attrs text-fill-attrs})
|
||||
|
||||
fill-values (d/update-in-when fill-values [:fill-color-gradient :type] keyword)
|
||||
|
||||
fill-values (cond-> fill-values
|
||||
;; Keep for backwards compatibility
|
||||
(:fill fill-values) (assoc :fill-color (:fill fill-values))
|
||||
(:opacity fill-values) (assoc :fill-opacity (:fill fill-values)))
|
||||
|
||||
|
||||
text-values (merge
|
||||
(select-keys shape [:grow-type])
|
||||
(dwt/current-root-values
|
||||
{:editor editor :shape shape
|
||||
:attrs root-attrs})
|
||||
(dwt/current-text-values
|
||||
{:editor editor :shape shape
|
||||
:attrs paragraph-attrs})
|
||||
(dwt/current-text-values
|
||||
{:editor editor :shape shape
|
||||
:attrs text-attrs}))]
|
||||
|
||||
[:*
|
||||
[:& measures-menu {:ids ids
|
||||
:type type
|
||||
:values measure-values}]
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values fill-values
|
||||
:editor editor}]
|
||||
[:& shadow-menu {:ids ids
|
||||
:values (select-keys shape [:shadow])}]
|
||||
[:& blur-menu {:ids ids
|
||||
:values (select-keys shape [:blur])}]
|
||||
[:& text-menu {:ids ids
|
||||
:type type
|
||||
:values text-values
|
||||
:editor editor}]]))
|
Loading…
Add table
Reference in a new issue