0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-09 16:30:37 -05:00

Adds blending mode and opacities to shapes

This commit is contained in:
alonso.torres 2021-03-08 15:40:45 +01:00
parent d39694af59
commit 31fa4a8c8b
4 changed files with 167 additions and 10 deletions

View file

@ -394,13 +394,15 @@
(defn name
"Improved version of name that won't fail if the input is not a keyword"
[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)))
(or default-value
(str maybe-keyword)))))

View file

@ -910,7 +910,6 @@
.element-set-actions {
display: flex;
visibility: hidden;
}
.row-flex-removable:hover .element-set-actions,
@ -918,6 +917,9 @@
visibility: visible;
}
.layer-actions {
visibility: visible;
}
.typography-entry {
margin: 0.5rem 0.3rem;

View file

@ -120,6 +120,17 @@
(obj/merge! attrs (clj->js stroke-attrs)))
attrs)))
(defn add-layer-props [attrs shape]
(let [layer-attrs
(cond-> {}
(:opacity shape)
(assoc :opacity (:opacity shape))
(and (:blend-mode shape) (not= (:blend-mode shape) :normal))
(assoc :mixBlendMode (:blend-mode shape)))]
(obj/merge! attrs (clj->js layer-attrs))))
(defn extract-svg-attrs
[render-id svg-defs svg-attrs]
(let [replace-id (fn [id]
@ -147,7 +158,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)

View file

@ -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])]]]]))