mirror of
https://github.com/penpot/penpot.git
synced 2025-02-13 18:48:37 -05:00
🐛 Fixed issues with masks when coloring
This commit is contained in:
parent
07d77c1320
commit
4b22615f97
7 changed files with 304 additions and 282 deletions
|
@ -144,38 +144,36 @@
|
|||
}
|
||||
}
|
||||
|
||||
.element-list li.masked {
|
||||
.element-children {
|
||||
li:first-child {
|
||||
position: relative;
|
||||
.element-list li.masked > .element-children > li {
|
||||
&:first-child {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: " ";
|
||||
border-right: 1px solid $color-gray-40;
|
||||
border-top: 1px solid $color-gray-40;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
transform: rotate(-45deg);
|
||||
top: -1px;
|
||||
left: -4px;
|
||||
}
|
||||
&::before {
|
||||
content: " ";
|
||||
border-right: 1px solid $color-gray-40;
|
||||
border-top: 1px solid $color-gray-40;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
transform: rotate(-45deg);
|
||||
top: -1px;
|
||||
left: -4px;
|
||||
}
|
||||
}
|
||||
|
||||
li:last-child {
|
||||
border-left: none;
|
||||
position: relative;
|
||||
&:last-child {
|
||||
border-left: none;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: " ";
|
||||
border-left: 1px solid $color-gray-40;
|
||||
border-bottom: 1px solid $color-gray-40;
|
||||
height: 1rem;
|
||||
width: 0.3rem;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
&::after {
|
||||
content: " ";
|
||||
border-left: 1px solid $color-gray-40;
|
||||
border-bottom: 1px solid $color-gray-40;
|
||||
height: 1rem;
|
||||
width: 0.3rem;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.data.workspace.texts :as dwtxt]
|
||||
[app.main.data.workspace.transforms :as dwt]
|
||||
[app.main.data.workspace.groups :as dwg]
|
||||
[app.main.data.workspace.drawing :as dwd]
|
||||
[app.main.data.workspace.drawing.path :as dwdp]
|
||||
[app.main.repo :as rp]
|
||||
|
@ -1011,11 +1012,12 @@
|
|||
(ptk/reify ::set-shape-proportion-lock
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(rx/of (dwc/update-shapes [id] (fn [shape]
|
||||
(if-not lock
|
||||
(assoc shape :proportion-lock false)
|
||||
(-> (assoc shape :proportion-lock true)
|
||||
(gpr/assign-proportions)))))))))
|
||||
(letfn [(assign-proportions [shape]
|
||||
(if-not lock
|
||||
(assoc shape :proportion-lock false)
|
||||
(-> (assoc shape :proportion-lock true)
|
||||
(gpr/assign-proportions))))]
|
||||
(rx/of (dwc/update-shapes [id] assign-proportions))))))
|
||||
|
||||
;; --- Update Shape Position
|
||||
|
||||
|
@ -1371,135 +1373,6 @@
|
|||
(with-meta params
|
||||
{:on-success image-uploaded})))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; GROUPS
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def group-selected
|
||||
(ptk/reify ::group-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
shapes (dws/shapes-for-grouping objects selected)]
|
||||
(when-not (empty? shapes)
|
||||
(let [[group rchanges uchanges] (dws/prepare-create-group page-id shapes "Group-" false)]
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dwc/select-shapes (d/ordered-set (:id group))))))))))
|
||||
|
||||
(def ungroup-selected
|
||||
(ptk/reify ::ungroup-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
group-id (first selected)
|
||||
group (get objects group-id)]
|
||||
(when (and (= 1 (count selected))
|
||||
(= (:type group) :group))
|
||||
(let [[rchanges uchanges]
|
||||
(dws/prepare-remove-group page-id group objects)]
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))))
|
||||
|
||||
(def mask-group
|
||||
(ptk/reify ::mask-group
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
shapes (dws/shapes-for-grouping objects selected)]
|
||||
(when-not (empty? shapes)
|
||||
(let [;; If the selected shape is a group, we can use it. If not,
|
||||
;; create a new group and set it as masked.
|
||||
[group rchanges uchanges]
|
||||
(if (and (= (count shapes) 1)
|
||||
(= (:type (first shapes)) :group))
|
||||
[(first shapes) [] []]
|
||||
(dws/prepare-create-group page-id shapes "Group-" true))
|
||||
|
||||
rchanges (d/concat rchanges
|
||||
[{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:operations [{:type :set
|
||||
:attr :masked-group?
|
||||
:val true}]}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [(:id group)]}])
|
||||
|
||||
uchanges (conj uchanges
|
||||
{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:operations [{:type :set
|
||||
:attr :masked-group?
|
||||
:val nil}]})
|
||||
|
||||
;; If the mask has the default color, change it automatically
|
||||
;; to white, to have an opaque mask by default (user may change
|
||||
;; it later to have different degrees of transparency).
|
||||
mask (first shapes)
|
||||
rchanges (if (not= (:fill-color mask) cp/default-color)
|
||||
rchanges
|
||||
(conj rchanges
|
||||
{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id mask)
|
||||
:operations [{:type :set
|
||||
:attr :fill-color
|
||||
:val "#ffffff"}]}))
|
||||
|
||||
uchanges (if (not= (:fill-color mask) cp/default-color)
|
||||
uchanges
|
||||
(conj uchanges
|
||||
{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id mask)
|
||||
:operations [{:type :set
|
||||
:attr :fill-color
|
||||
:val (:fill-color mask)}]}))]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dwc/select-shapes (d/ordered-set (:id group))))))))))
|
||||
|
||||
(def unmask-group
|
||||
(ptk/reify ::unmask-group
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])]
|
||||
(when (= (count selected) 1)
|
||||
(let [group (get objects (first selected))
|
||||
|
||||
rchanges [{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:operations [{:type :set
|
||||
:attr :masked-group?
|
||||
:val nil}]}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [(:id group)]}]
|
||||
|
||||
uchanges [{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:operations [{:type :set
|
||||
:attr :masked-group?
|
||||
:val (:masked-group? group)}]}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [(:id group)]}]]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dwc/select-shapes (d/ordered-set (:id group))))))))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Interactions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -1631,6 +1504,13 @@
|
|||
(d/export dwc/start-edition-mode)
|
||||
(d/export dwdp/start-path-edit)
|
||||
|
||||
;; Groups
|
||||
|
||||
(d/export dwg/mask-group)
|
||||
(d/export dwg/unmask-group)
|
||||
(d/export dwg/group-selected)
|
||||
(d/export dwg/ungroup-selected)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Shortcuts
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
199
frontend/src/app/main/data/workspace/groups.cljs
Normal file
199
frontend/src/app/main/data/workspace/groups.cljs
Normal file
|
@ -0,0 +1,199 @@
|
|||
(ns app.main.data.workspace.groups
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.pages-helpers :as cph]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
(defn shapes-for-grouping
|
||||
[objects selected]
|
||||
(->> selected
|
||||
(map #(get objects %))
|
||||
(filter #(not= :frame (:type %)))
|
||||
(map #(assoc % ::index (cph/position-on-parent (:id %) objects)))
|
||||
(sort-by ::index)))
|
||||
|
||||
(defn- make-group
|
||||
[shapes prefix keep-name]
|
||||
(let [selrect (gsh/selection-rect shapes)
|
||||
frame-id (-> shapes first :frame-id)
|
||||
parent-id (-> shapes first :parent-id)
|
||||
group-name (if (and keep-name
|
||||
(= (count shapes) 1)
|
||||
(= (:type (first shapes)) :group))
|
||||
(:name (first shapes))
|
||||
(name (gensym prefix)))]
|
||||
(-> (cp/make-minimal-group frame-id selrect group-name)
|
||||
(gsh/setup selrect)
|
||||
(assoc :shapes (mapv :id shapes)))))
|
||||
|
||||
(defn prepare-create-group
|
||||
[page-id shapes prefix keep-name]
|
||||
(let [group (make-group shapes prefix keep-name)
|
||||
rchanges [{:type :add-obj
|
||||
:id (:id group)
|
||||
:page-id page-id
|
||||
:frame-id (:frame-id (first shapes))
|
||||
:parent-id (:parent-id (first shapes))
|
||||
:obj group
|
||||
:index (::index (first shapes))}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:id group)
|
||||
:shapes (mapv :id shapes)}]
|
||||
|
||||
uchanges (conj
|
||||
(mapv (fn [obj] {:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:parent-id obj)
|
||||
:index (::index obj)
|
||||
:shapes [(:id obj)]})
|
||||
shapes)
|
||||
{:type :del-obj
|
||||
:id (:id group)
|
||||
:page-id page-id})]
|
||||
[group rchanges uchanges]))
|
||||
|
||||
(defn prepare-remove-group
|
||||
[page-id group objects]
|
||||
(let [shapes (:shapes group)
|
||||
parent-id (cph/get-parent (:id group) objects)
|
||||
parent (get objects parent-id)
|
||||
index-in-parent (->> (:shapes parent)
|
||||
(map-indexed vector)
|
||||
(filter #(#{(:id group)} (second %)))
|
||||
(ffirst))
|
||||
rchanges [{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id parent-id
|
||||
:shapes shapes
|
||||
:index index-in-parent}
|
||||
{:type :del-obj
|
||||
:page-id page-id
|
||||
:id (:id group)}]
|
||||
uchanges [{:type :add-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:frame-id (:frame-id group)
|
||||
:obj (assoc group :shapes [])}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:id group)
|
||||
:shapes shapes}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id parent-id
|
||||
:shapes [(:id group)]
|
||||
:index index-in-parent}]]
|
||||
[rchanges uchanges]))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; GROUPS
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def group-selected
|
||||
(ptk/reify ::group-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
shapes (shapes-for-grouping objects selected)]
|
||||
(when-not (empty? shapes)
|
||||
(let [[group rchanges uchanges] (prepare-create-group page-id shapes "Group-" false)]
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dwc/select-shapes (d/ordered-set (:id group))))))))))
|
||||
|
||||
(def ungroup-selected
|
||||
(ptk/reify ::ungroup-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
group-id (first selected)
|
||||
group (get objects group-id)]
|
||||
(when (and (= 1 (count selected))
|
||||
(= (:type group) :group))
|
||||
(let [[rchanges uchanges]
|
||||
(prepare-remove-group page-id group objects)]
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))))
|
||||
|
||||
(def mask-group
|
||||
(ptk/reify ::mask-group
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
shapes (shapes-for-grouping objects selected)]
|
||||
(when-not (empty? shapes)
|
||||
(let [;; If the selected shape is a group, we can use it. If not,
|
||||
;; create a new group and set it as masked.
|
||||
[group rchanges uchanges]
|
||||
(if (and (= (count shapes) 1)
|
||||
(= (:type (first shapes)) :group))
|
||||
[(first shapes) [] []]
|
||||
(prepare-create-group page-id shapes "Group-" true))
|
||||
|
||||
rchanges (d/concat rchanges
|
||||
[{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:operations [{:type :set
|
||||
:attr :masked-group?
|
||||
:val true}]}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [(:id group)]}])
|
||||
|
||||
uchanges (conj uchanges
|
||||
{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:operations [{:type :set
|
||||
:attr :masked-group?
|
||||
:val nil}]})]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dwc/select-shapes (d/ordered-set (:id group))))))))))
|
||||
|
||||
(def unmask-group
|
||||
(ptk/reify ::unmask-group
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])]
|
||||
(when (= (count selected) 1)
|
||||
(let [group (get objects (first selected))
|
||||
|
||||
rchanges [{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:operations [{:type :set
|
||||
:attr :masked-group?
|
||||
:val nil}]}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [(:id group)]}]
|
||||
|
||||
uchanges [{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:operations [{:type :set
|
||||
:attr :masked-group?
|
||||
:val (:masked-group? group)}]}
|
||||
{:type :reg-objects
|
||||
:page-id page-id
|
||||
:shapes [(:id group)]}]]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dwc/select-shapes (d/ordered-set (:id group))))))))))
|
||||
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
[app.common.geom.shapes :as geom]
|
||||
[app.main.data.messages :as dm]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.data.workspace.groups :as dwg]
|
||||
[app.main.data.workspace.libraries-helpers :as dwlh]
|
||||
[app.common.pages :as cp]
|
||||
[app.main.repo :as rp]
|
||||
|
@ -182,7 +182,7 @@
|
|||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
shapes (dws/shapes-for-grouping objects selected)]
|
||||
shapes (dwg/shapes-for-grouping objects selected)]
|
||||
(when-not (empty? shapes)
|
||||
(let [;; If the selected shape is a group, we can use it. If not,
|
||||
;; we need to create a group before creating the component.
|
||||
|
@ -190,7 +190,7 @@
|
|||
(if (and (= (count shapes) 1)
|
||||
(= (:type (first shapes)) :group))
|
||||
[(first shapes) [] []]
|
||||
(dws/prepare-create-group page-id shapes "Component-" true))
|
||||
(dwg/prepare-create-group page-id shapes "Component-" true))
|
||||
|
||||
[new-shape new-shapes updated-shapes]
|
||||
(dwlh/make-component-shape group objects)
|
||||
|
|
|
@ -197,91 +197,6 @@
|
|||
(rx/of (deselect-all) (select-shape (:id selected))))))))
|
||||
|
||||
|
||||
;; --- Group shapes
|
||||
|
||||
(defn shapes-for-grouping
|
||||
[objects selected]
|
||||
(->> selected
|
||||
(map #(get objects %))
|
||||
(filter #(not= :frame (:type %)))
|
||||
(map #(assoc % ::index (cph/position-on-parent (:id %) objects)))
|
||||
(sort-by ::index)))
|
||||
|
||||
(defn- make-group
|
||||
[shapes prefix keep-name]
|
||||
(let [selrect (geom/selection-rect shapes)
|
||||
frame-id (-> shapes first :frame-id)
|
||||
parent-id (-> shapes first :parent-id)
|
||||
group-name (if (and keep-name
|
||||
(= (count shapes) 1)
|
||||
(= (:type (first shapes)) :group))
|
||||
(:name (first shapes))
|
||||
(name (gensym prefix)))]
|
||||
(-> (cp/make-minimal-group frame-id selrect group-name)
|
||||
(geom/setup selrect)
|
||||
(assoc :shapes (mapv :id shapes)))))
|
||||
|
||||
(defn prepare-create-group
|
||||
[page-id shapes prefix keep-name]
|
||||
(let [group (make-group shapes prefix keep-name)
|
||||
rchanges [{:type :add-obj
|
||||
:id (:id group)
|
||||
:page-id page-id
|
||||
:frame-id (:frame-id (first shapes))
|
||||
:parent-id (:parent-id (first shapes))
|
||||
:obj group
|
||||
:index (::index (first shapes))}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:id group)
|
||||
:shapes (mapv :id shapes)}]
|
||||
|
||||
uchanges (conj
|
||||
(mapv (fn [obj] {:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:parent-id obj)
|
||||
:index (::index obj)
|
||||
:shapes [(:id obj)]})
|
||||
shapes)
|
||||
{:type :del-obj
|
||||
:id (:id group)
|
||||
:page-id page-id})]
|
||||
[group rchanges uchanges]))
|
||||
|
||||
(defn prepare-remove-group
|
||||
[page-id group objects]
|
||||
(let [shapes (:shapes group)
|
||||
parent-id (cph/get-parent (:id group) objects)
|
||||
parent (get objects parent-id)
|
||||
index-in-parent (->> (:shapes parent)
|
||||
(map-indexed vector)
|
||||
(filter #(#{(:id group)} (second %)))
|
||||
(ffirst))
|
||||
rchanges [{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id parent-id
|
||||
:shapes shapes
|
||||
:index index-in-parent}
|
||||
{:type :del-obj
|
||||
:page-id page-id
|
||||
:id (:id group)}]
|
||||
uchanges [{:type :add-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:frame-id (:frame-id group)
|
||||
:obj (assoc group :shapes [])}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:id group)
|
||||
:shapes shapes}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id parent-id
|
||||
:shapes [(:id group)]
|
||||
:index index-in-parent}]]
|
||||
[rchanges uchanges]))
|
||||
|
||||
|
||||
;; --- Duplicate Shapes
|
||||
(declare prepare-duplicate-change)
|
||||
(declare prepare-duplicate-frame-change)
|
||||
|
|
|
@ -10,42 +10,37 @@
|
|||
(ns app.main.ui.shapes.group
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[cuerdas.core :as str]
|
||||
[app.main.ui.shapes.attrs :as attrs]
|
||||
[app.common.geom.shapes :as geom]))
|
||||
[app.main.ui.shapes.mask :refer [mask-str mask-factory]]))
|
||||
|
||||
(defn group-shape
|
||||
[shape-wrapper]
|
||||
(mf/fnc group-shape
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [frame (unchecked-get props "frame")
|
||||
shape (unchecked-get props "shape")
|
||||
childs (unchecked-get props "childs")
|
||||
expand-mask (unchecked-get props "expand-mask")
|
||||
pointer-events (unchecked-get props "pointer-events")
|
||||
mask (if (and (:masked-group? shape) (not expand-mask))
|
||||
(first childs)
|
||||
nil)
|
||||
childs (if (and (:masked-group? shape) (not expand-mask))
|
||||
(rest childs)
|
||||
childs)
|
||||
{:keys [id x y width height]} shape
|
||||
transform (geom/transform-matrix shape)]
|
||||
[:g.group {:pointer-events pointer-events
|
||||
:mask (when (and mask (not expand-mask))
|
||||
(str/fmt "url(#%s)" (:id mask)))}
|
||||
(when mask
|
||||
[:defs
|
||||
[:mask {:id (:id mask)
|
||||
:width width
|
||||
:height height}
|
||||
(let [render-mask (mask-factory shape-wrapper)]
|
||||
(mf/fnc group-shape
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [frame (unchecked-get props "frame")
|
||||
shape (unchecked-get props "shape")
|
||||
childs (unchecked-get props "childs")
|
||||
expand-mask (unchecked-get props "expand-mask")
|
||||
pointer-events (unchecked-get props "pointer-events")
|
||||
|
||||
{:keys [id x y width height]} shape
|
||||
|
||||
show-mask? (and (:masked-group? shape) (not expand-mask))
|
||||
mask (when show-mask? (first childs))
|
||||
childs (if show-mask? (rest childs) childs)]
|
||||
|
||||
[:g.group
|
||||
{:pointer-events pointer-events
|
||||
:mask (when (and mask (not expand-mask)) (mask-str mask))}
|
||||
|
||||
(when mask
|
||||
[:> render-mask #js {:frame frame :mask mask}])
|
||||
|
||||
(for [item childs]
|
||||
[:& shape-wrapper {:frame frame
|
||||
:shape mask}]]])
|
||||
(for [item childs]
|
||||
[:& shape-wrapper {:frame frame
|
||||
:shape item
|
||||
:key (:id item)}])])))
|
||||
:shape item
|
||||
:key (:id item)}])]))))
|
||||
|
||||
|
||||
|
||||
|
|
35
frontend/src/app/main/ui/shapes/mask.cljs
Normal file
35
frontend/src/app/main/ui/shapes/mask.cljs
Normal file
|
@ -0,0 +1,35 @@
|
|||
;; 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.shapes.mask
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defn mask-str [mask]
|
||||
(str/fmt "url(#%s)" (str (:id mask) "-mask")))
|
||||
|
||||
(defn mask-factory
|
||||
[shape-wrapper]
|
||||
(mf/fnc mask-shape
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [frame (unchecked-get props "frame")
|
||||
mask (unchecked-get props "mask")]
|
||||
[:defs
|
||||
[:filter {:id (str (:id mask) "-filter")}
|
||||
[:feFlood {:flood-color "white"}]
|
||||
[:feComposite {:in "BackgroundImage"
|
||||
:in2 "SourceGraphic"
|
||||
:operator "in"
|
||||
:result "comp"}]]
|
||||
[:mask {:id (str (:id mask) "-mask")}
|
||||
[:g {:filter (str/fmt "url(#%s)" (str (:id mask) "-filter"))}
|
||||
[:& shape-wrapper {:frame frame :shape mask}]]]])))
|
||||
|
Loading…
Add table
Reference in a new issue