mirror of
https://github.com/penpot/penpot.git
synced 2025-05-29 15:16:13 +02:00
✨ Change shapes color
This commit is contained in:
parent
9a188fd792
commit
42230f2630
4 changed files with 167 additions and 26 deletions
|
@ -24,6 +24,7 @@
|
|||
[app.util.color :as uc]
|
||||
[app.util.storage :refer [storage]]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; A set of keys that are used for shared state identifiers
|
||||
|
@ -377,7 +378,7 @@
|
|||
|
||||
(defn color-att->text
|
||||
[color]
|
||||
{:fill-color (:color color)
|
||||
{:fill-color (when (:color color) (str/lower (:color color)))
|
||||
:fill-opacity (:opacity color)
|
||||
:fill-color-ref-id (:id color)
|
||||
:fill-color-ref-file (:file-id color)
|
||||
|
|
|
@ -13,12 +13,14 @@
|
|||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.record :as cr]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.changes :as ch]
|
||||
[app.main.data.workspace.bool :as dwb]
|
||||
[app.main.data.workspace.colors :as dwc]
|
||||
[app.main.data.workspace.groups :as dwg]
|
||||
[app.main.data.workspace.media :as dwm]
|
||||
[app.main.store :as st]
|
||||
|
@ -27,6 +29,7 @@
|
|||
[app.plugins.fonts :as fonts]
|
||||
[app.plugins.library :as library]
|
||||
[app.plugins.page :as page]
|
||||
[app.plugins.parser :as parser]
|
||||
[app.plugins.shape :as shape]
|
||||
[app.plugins.user :as user]
|
||||
[app.plugins.utils :as u]
|
||||
|
@ -87,8 +90,13 @@
|
|||
(let [selection (get-in @st/state [:workspace-local :selected])]
|
||||
(apply array (sequence (map (partial shape/shape-proxy $plugin)) selection))))
|
||||
|
||||
(getColors
|
||||
(shapesColors
|
||||
[_ shapes]
|
||||
(cond
|
||||
(or (not (array? shapes)) (not (every? shape/shape-proxy? shapes)))
|
||||
(u/display-not-valid :shapesColors-shapes shapes)
|
||||
|
||||
:else
|
||||
(let [objects (u/locate-objects)
|
||||
shapes (->> shapes
|
||||
(map #(obj/get % "$id"))
|
||||
|
@ -97,25 +105,51 @@
|
|||
file-id (:current-file-id @st/state)
|
||||
shared-libs (:workspace-libraries @st/state)
|
||||
|
||||
colors
|
||||
format-entry
|
||||
(fn [{:keys [prop shape-id index]}]
|
||||
#js {:property (d/name prop)
|
||||
:index index
|
||||
:shapeId (str shape-id)})
|
||||
format-result
|
||||
(fn [[color attrs]]
|
||||
(let [shapes-info (apply array (map format-entry attrs))
|
||||
color (u/to-js color)]
|
||||
(obj/set! color "shapeInfo" shapes-info)
|
||||
color))]
|
||||
(apply
|
||||
array
|
||||
(->> (ctc/extract-all-colors shapes file-id shared-libs)
|
||||
(group-by :attrs)
|
||||
(map (fn [[color attrs]]
|
||||
(let [shapes-info (apply array (map (fn [{:keys [prop shape-id index]}]
|
||||
#js {:property (d/name prop)
|
||||
:index index
|
||||
:shapeId (str shape-id)}) attrs))
|
||||
color (u/to-js color)]
|
||||
(obj/set! color "shapeInfo" shapes-info)
|
||||
color)))))]
|
||||
colors))
|
||||
(map format-result))))))
|
||||
|
||||
(changeColor
|
||||
[_ _shapes _old-color _new-color]
|
||||
;; TODO
|
||||
)
|
||||
(replaceColor
|
||||
[_ shapes old-color new-color]
|
||||
|
||||
(let [old-color (parser/parse-color old-color)
|
||||
new-color (parser/parse-color new-color)]
|
||||
(cond
|
||||
(or (not (array? shapes)) (not (every? shape/shape-proxy? shapes)))
|
||||
(u/display-not-valid :replaceColor-shapes shapes)
|
||||
|
||||
(not (sm/validate ::ctc/color old-color))
|
||||
(u/display-not-valid :replaceColor-oldColor old-color)
|
||||
|
||||
(not (sm/validate ::ctc/color new-color))
|
||||
(u/display-not-valid :replaceColor-newColor new-color)
|
||||
|
||||
:else
|
||||
(let [file-id (:current-file-id @st/state)
|
||||
shared-libs (:workspace-libraries @st/state)
|
||||
objects (u/locate-objects)
|
||||
shapes
|
||||
(->> shapes
|
||||
(map #(obj/get % "$id"))
|
||||
(mapcat #(cfh/get-children-with-self objects %)))
|
||||
|
||||
shapes-by-color
|
||||
(->> (ctc/extract-all-colors shapes file-id shared-libs)
|
||||
(group-by :attrs))]
|
||||
(st/emit! (dwc/change-color-in-selected new-color (get shapes-by-color old-color) old-color))))))
|
||||
|
||||
(getRoot
|
||||
[_]
|
||||
|
|
8
frontend/src/app/plugins/format.cljs
Normal file
8
frontend/src/app/plugins/format.cljs
Normal file
|
@ -0,0 +1,8 @@
|
|||
;; 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
|
||||
|
||||
(ns app.plugins.format)
|
||||
|
98
frontend/src/app/plugins/parser.cljs
Normal file
98
frontend/src/app/plugins/parser.cljs
Normal file
|
@ -0,0 +1,98 @@
|
|||
;; 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
|
||||
|
||||
(ns app.plugins.parser
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.util.object :as obj]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defn parse-id
|
||||
[id]
|
||||
(when id (uuid/uuid id)))
|
||||
|
||||
(defn parse-keyword
|
||||
[kw]
|
||||
(when kw (keyword kw)))
|
||||
|
||||
(defn parse-hex
|
||||
[color]
|
||||
(when color (-> color str/lower)))
|
||||
|
||||
;;export type PenpotImageData = {
|
||||
;; name?: string;
|
||||
;; width: number;
|
||||
;; height: number;
|
||||
;; mtype?: string;
|
||||
;; id: string;
|
||||
;; keepApectRatio?: boolean;
|
||||
;;}
|
||||
(defn parse-image-data
|
||||
[^js image-data]
|
||||
(when image-data
|
||||
(d/without-nils
|
||||
{:id (-> (obj/get image-data "id") parse-id)
|
||||
:name (obj/get image-data "name")
|
||||
:width (obj/get image-data "width")
|
||||
:height (obj/get image-data "height")
|
||||
:mtype (obj/get image-data "mtype")
|
||||
:keep-aspect-ratio (obj/get image-data "keepApectRatio")})))
|
||||
|
||||
;; export type PenpotGradient = {
|
||||
;; type: 'linear' | 'radial';
|
||||
;; startX: number;
|
||||
;; startY: number;
|
||||
;; endX: number;
|
||||
;; endY: number;
|
||||
;; width: number;
|
||||
;; stops: Array<{ color: string; opacity?: number; offset: number }>;
|
||||
;; }
|
||||
(defn parse-gradient-stop
|
||||
[^js stop]
|
||||
(when stop
|
||||
(d/without-nils
|
||||
{:color (-> (obj/get stop "color") parse-hex)
|
||||
:opacity (obj/get stop "opacity")
|
||||
:offset (obj/get stop "offset")})))
|
||||
|
||||
(defn parse-gradient
|
||||
[^js gradient]
|
||||
(when gradient
|
||||
(d/without-nils
|
||||
{:type (-> (obj/get gradient "type") parse-keyword)
|
||||
:start-x (obj/get gradient "startX")
|
||||
:start-y (obj/get gradient "startY")
|
||||
:end-x (obj/get gradient "endX")
|
||||
:end-y (obj/get gradient "endY")
|
||||
:width (obj/get gradient "width")
|
||||
:stops (->> (obj/get gradient "stops")
|
||||
(mapv parse-gradient-stop))})))
|
||||
|
||||
;; export interface PenpotColor {
|
||||
;; id?: string;
|
||||
;; name?: string;
|
||||
;; path?: string;
|
||||
;; color?: string;
|
||||
;; opacity?: number;
|
||||
;; refId?: string;
|
||||
;; refFile?: string;
|
||||
;; gradient?: PenpotGradient;
|
||||
;; image?: PenpotImageData;
|
||||
;; }
|
||||
(defn parse-color
|
||||
[^js color]
|
||||
(when color
|
||||
(d/without-nils
|
||||
{:id (-> (obj/get color "id") parse-id)
|
||||
:name (obj/get color "name")
|
||||
:path (obj/get color "path")
|
||||
:color (-> (obj/get color "color") parse-hex)
|
||||
:opacity (obj/get color "opacity")
|
||||
:ref-id (-> (obj/get color "refId") parse-id)
|
||||
:ref-file (-> (obj/get color "refFile") parse-id)
|
||||
:gradient (-> (obj/get color "gradient") parse-gradient)
|
||||
:image (-> (obj/get color "image") parse-image-data)})))
|
Loading…
Add table
Add a link
Reference in a new issue