mirror of
https://github.com/penpot/penpot.git
synced 2025-05-29 00:16:12 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
3cb15df08d
16 changed files with 196 additions and 109 deletions
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
|
- Avoid numeric inputs to change its value without focusing them [Taiga #3140](https://tree.taiga.io/project/penpot/issue/3140)
|
||||||
- Fix comments modal when changing pages [Taiga #2597](https://tree.taiga.io/project/penpot/issue/2508)
|
- Fix comments modal when changing pages [Taiga #2597](https://tree.taiga.io/project/penpot/issue/2508)
|
||||||
- Copy paste inside a text layer leaves pasted text transparent [Taiga #3096](https://tree.taiga.io/project/penpot/issue/3096)
|
- Copy paste inside a text layer leaves pasted text transparent [Taiga #3096](https://tree.taiga.io/project/penpot/issue/3096)
|
||||||
- On dashboard enter on empty search refresh the page [Taiga #2597](https://tree.taiga.io/project/penpot/issue/2597)
|
- On dashboard enter on empty search refresh the page [Taiga #2597](https://tree.taiga.io/project/penpot/issue/2597)
|
||||||
|
@ -68,6 +69,8 @@
|
||||||
- Fix paste ordering for frames not being respected [Taiga #3097](https://tree.taiga.io/project/penpot/issue/3097)
|
- Fix paste ordering for frames not being respected [Taiga #3097](https://tree.taiga.io/project/penpot/issue/3097)
|
||||||
- Improved command support for MacOS [Taiga #2789](https://tree.taiga.io/project/penpot/issue/2789)
|
- Improved command support for MacOS [Taiga #2789](https://tree.taiga.io/project/penpot/issue/2789)
|
||||||
- Fix shift+2 shortcut in MacOS with non-english keyboards [Taiga #3038](https://tree.taiga.io/project/penpot/issue/3038)
|
- Fix shift+2 shortcut in MacOS with non-english keyboards [Taiga #3038](https://tree.taiga.io/project/penpot/issue/3038)
|
||||||
|
- Some fixes to SVG imports [Taiga #3122](https://tree.taiga.io/project/penpot/issue/3122) [#1720](https://github.com/penpot/penpot/issues/1720) [Taiga #2884](https://tree.taiga.io/project/penpot/issue/2884)
|
||||||
|
- Fix drag guides to delete target area [#1679](https://github.com/penpot/penpot/issues/1679)
|
||||||
|
|
||||||
### :arrow_up: Deps updates
|
### :arrow_up: Deps updates
|
||||||
### :heart: Community contributions by (Thank you!)
|
### :heart: Community contributions by (Thank you!)
|
||||||
|
|
|
@ -105,6 +105,7 @@
|
||||||
(dm/export gco/transform-points)
|
(dm/export gco/transform-points)
|
||||||
|
|
||||||
(dm/export gpr/make-rect)
|
(dm/export gpr/make-rect)
|
||||||
|
(dm/export gpr/make-selrect)
|
||||||
(dm/export gpr/rect->selrect)
|
(dm/export gpr/rect->selrect)
|
||||||
(dm/export gpr/rect->points)
|
(dm/export gpr/rect->points)
|
||||||
(dm/export gpr/points->selrect)
|
(dm/export gpr/points->selrect)
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
(def dissoc-attrs
|
(def dissoc-attrs
|
||||||
[:x :y :width :height
|
[:x :y :width :height
|
||||||
:rx :ry :r1 :r2 :r3 :r4
|
:rx :ry :r1 :r2 :r3 :r4
|
||||||
:metadata :shapes])
|
:metadata])
|
||||||
|
|
||||||
(def allowed-transform-types
|
(def allowed-transform-types
|
||||||
#{:rect
|
#{:rect
|
||||||
|
@ -199,7 +199,6 @@
|
||||||
(map #(convert-to-path % objects)))
|
(map #(convert-to-path % objects)))
|
||||||
bool-type (:bool-type shape)
|
bool-type (:bool-type shape)
|
||||||
content (pb/content-bool bool-type (mapv :content children))]
|
content (pb/content-bool bool-type (mapv :content children))]
|
||||||
|
|
||||||
(-> shape
|
(-> shape
|
||||||
(assoc :type :path)
|
(assoc :type :path)
|
||||||
(assoc :content content)
|
(assoc :content content)
|
||||||
|
|
|
@ -1209,8 +1209,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-container {
|
.modal-container {
|
||||||
background-image: url("../images/deco-left.png"),
|
background-image: url("../images/deco-left.png"), url("../images/deco-right.png");
|
||||||
url("../images/deco-right.png");
|
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 10% 50px, 90% 50px;
|
background-position: 10% 50px, 90% 50px;
|
||||||
background-size: 65px;
|
background-size: 65px;
|
||||||
|
@ -1237,18 +1236,8 @@
|
||||||
--checkbox-border-radius: 3px;
|
--checkbox-border-radius: 3px;
|
||||||
--dropdown-option-background-color: rgba(0, 195, 139, 1);
|
--dropdown-option-background-color: rgba(0, 195, 139, 1);
|
||||||
--dropdown-option-active-background-color: rgba(0, 138, 98, 1);
|
--dropdown-option-active-background-color: rgba(0, 138, 98, 1);
|
||||||
--invalid-field-background-color: rgba(
|
--invalid-field-background-color: rgba(238.51780000000002, 205.7178, 204.11780000000002, 1);
|
||||||
238.51780000000002,
|
--message-fail-background-color: rgba(238.51780000000002, 205.7178, 204.11780000000002, 1);
|
||||||
205.7178,
|
|
||||||
204.11780000000002,
|
|
||||||
1
|
|
||||||
);
|
|
||||||
--message-fail-background-color: rgba(
|
|
||||||
238.51780000000002,
|
|
||||||
205.7178,
|
|
||||||
204.11780000000002,
|
|
||||||
1
|
|
||||||
);
|
|
||||||
--message-success-background-color: rgba(171, 232, 197, 1);
|
--message-success-background-color: rgba(171, 232, 197, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1487,7 +1476,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.scale {
|
&.scale {
|
||||||
width: 25%;
|
width: 6.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.scale,
|
&.scale,
|
||||||
|
|
|
@ -104,8 +104,9 @@
|
||||||
|
|
||||||
(update-in state path cp/process-changes redo-changes false)
|
(update-in state path cp/process-changes redo-changes false)
|
||||||
|
|
||||||
(catch :default e
|
(catch :default err
|
||||||
(vreset! error e)
|
(log/error :js/error err)
|
||||||
|
(vreset! error err)
|
||||||
state))))
|
state))))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
|
|
@ -259,10 +259,7 @@
|
||||||
(assoc :stroke-color-gradient (:gradient attrs))
|
(assoc :stroke-color-gradient (:gradient attrs))
|
||||||
|
|
||||||
(contains? attrs :opacity)
|
(contains? attrs :opacity)
|
||||||
(assoc :stroke-opacity (:opacity attrs))
|
(assoc :stroke-opacity (:opacity attrs)))
|
||||||
|
|
||||||
:always
|
|
||||||
(d/without-nils))
|
|
||||||
|
|
||||||
attrs (merge attrs color-attrs)]
|
attrs (merge attrs color-attrs)]
|
||||||
|
|
||||||
|
@ -276,7 +273,10 @@
|
||||||
(assoc :stroke-style :solid)
|
(assoc :stroke-style :solid)
|
||||||
|
|
||||||
(not (contains? new-attrs :stroke-alignment))
|
(not (contains? new-attrs :stroke-alignment))
|
||||||
(assoc :stroke-alignment :center))]
|
(assoc :stroke-alignment :center)
|
||||||
|
|
||||||
|
:always
|
||||||
|
(d/without-nils))]
|
||||||
(assoc-in shape [:strokes index] new-attrs)))))))))
|
(assoc-in shape [:strokes index] new-attrs)))))))))
|
||||||
|
|
||||||
(defn add-stroke
|
(defn add-stroke
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
changes
|
changes
|
||||||
(-> (pcb/empty-changes it page-id)
|
(-> (pcb/empty-changes it page-id)
|
||||||
(pcb/with-objects objects)
|
(pcb/with-objects objects)
|
||||||
(pcb/remove-objects children-ids)
|
(pcb/update-shapes selected #(upsp/convert-to-path % objects))
|
||||||
(pcb/update-shapes selected #(upsp/convert-to-path % objects)))]
|
(pcb/remove-objects children-ids))]
|
||||||
|
|
||||||
(rx/of (dch/commit-changes changes))))))
|
(rx/of (dch/commit-changes changes))))))
|
||||||
|
|
|
@ -70,8 +70,6 @@
|
||||||
:else (str tag))))
|
:else (str tag))))
|
||||||
|
|
||||||
(defn setup-fill [shape]
|
(defn setup-fill [shape]
|
||||||
(if (some? (:fills shape))
|
|
||||||
shape
|
|
||||||
(cond-> shape
|
(cond-> shape
|
||||||
;; Color present as attribute
|
;; Color present as attribute
|
||||||
(uc/color? (str/trim (get-in shape [:svg-attrs :fill])))
|
(uc/color? (str/trim (get-in shape [:svg-attrs :fill])))
|
||||||
|
@ -95,7 +93,7 @@
|
||||||
(get-in shape [:svg-attrs :style :fill-opacity])
|
(get-in shape [:svg-attrs :style :fill-opacity])
|
||||||
(-> (update-in [:svg-attrs :style] dissoc :fill-opacity)
|
(-> (update-in [:svg-attrs :style] dissoc :fill-opacity)
|
||||||
(assoc-in [:fills 0 :fill-opacity] (-> (get-in shape [:svg-attrs :style :fill-opacity])
|
(assoc-in [:fills 0 :fill-opacity] (-> (get-in shape [:svg-attrs :style :fill-opacity])
|
||||||
(d/parse-double)))))))
|
(d/parse-double))))))
|
||||||
|
|
||||||
(defn setup-stroke [shape]
|
(defn setup-stroke [shape]
|
||||||
(let [stroke-linecap (-> (or (get-in shape [:svg-attrs :stroke-linecap])
|
(let [stroke-linecap (-> (or (get-in shape [:svg-attrs :stroke-linecap])
|
||||||
|
|
|
@ -245,4 +245,11 @@
|
||||||
(events/unlistenByKey key)))))
|
(events/unlistenByKey key)))))
|
||||||
|
|
||||||
|
|
||||||
|
(mf/use-layout-effect
|
||||||
|
(mf/deps handle-mouse-wheel)
|
||||||
|
(fn []
|
||||||
|
(let [keys [(events/listen (mf/ref-val ref) EventType.WHEEL handle-mouse-wheel #js {:pasive false})]]
|
||||||
|
#(doseq [key keys]
|
||||||
|
(events/unlistenByKey key)))))
|
||||||
|
|
||||||
[:> :input props]))
|
[:> :input props]))
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
(ns app.main.ui.shapes.svg-defs
|
(ns app.main.ui.shapes.svg-defs
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.geom.point :as gpt]
|
[app.main.ui.shapes.filters :as f]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.svg :as usvg]
|
[app.util.svg :as usvg]
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
@ -21,24 +21,7 @@
|
||||||
(str transform-matrix " " val)
|
(str transform-matrix " " val)
|
||||||
(str transform-matrix)))))
|
(str transform-matrix)))))
|
||||||
|
|
||||||
(defn transform-region [attrs transform]
|
(mf/defc svg-node [{:keys [type node prefix-id transform bounds]}]
|
||||||
(let [{x-str :x y-str :y width-str :width height-str :height} attrs
|
|
||||||
data (map d/parse-double [x-str y-str width-str height-str])]
|
|
||||||
(if (every? (comp not nil?) data)
|
|
||||||
(let [[x y width height] data
|
|
||||||
p1 (-> (gpt/point x y)
|
|
||||||
(gpt/transform transform))
|
|
||||||
p2 (-> (gpt/point (+ x width) (+ y height))
|
|
||||||
(gpt/transform transform))]
|
|
||||||
|
|
||||||
(assoc attrs
|
|
||||||
:x (:x p1)
|
|
||||||
:y (:y p1)
|
|
||||||
:width (- (:x p2) (:x p1))
|
|
||||||
:height (- (:y p2) (:y p1))))
|
|
||||||
attrs)))
|
|
||||||
|
|
||||||
(mf/defc svg-node [{:keys [node prefix-id transform]}]
|
|
||||||
(cond
|
(cond
|
||||||
(string? node) node
|
(string? node) node
|
||||||
|
|
||||||
|
@ -63,23 +46,34 @@
|
||||||
attrs (-> attrs
|
attrs (-> attrs
|
||||||
(usvg/update-attr-ids prefix-id)
|
(usvg/update-attr-ids prefix-id)
|
||||||
(usvg/clean-attrs)
|
(usvg/clean-attrs)
|
||||||
|
;; This clasname will be used to change the transform on the viewport
|
||||||
|
;; only necessary for groups because shapes have their own transform
|
||||||
|
(cond-> (and (or transform-gradient?
|
||||||
|
transform-pattern?
|
||||||
|
transform-clippath?
|
||||||
|
transform-filter?
|
||||||
|
transform-mask?)
|
||||||
|
(= :group type))
|
||||||
|
(update :className #(if % (dm/str % " svg-def") "svg-def")))
|
||||||
(cond->
|
(cond->
|
||||||
transform-gradient? (add-matrix :gradientTransform transform)
|
transform-gradient? (add-matrix :gradientTransform transform)
|
||||||
transform-pattern? (add-matrix :patternTransform transform)
|
transform-pattern? (add-matrix :patternTransform transform)
|
||||||
transform-clippath? (add-matrix :transform transform)
|
transform-clippath? (add-matrix :transform transform)
|
||||||
(or transform-filter?
|
(or transform-filter?
|
||||||
transform-mask?) (transform-region transform)))
|
transform-mask?) (merge attrs bounds)))
|
||||||
|
|
||||||
[wrapper wrapper-props] (if (= tag :mask)
|
[wrapper wrapper-props] (if (= tag :mask)
|
||||||
["g" #js {:transform (str transform)}]
|
["g" #js {:className "svg-mask-wrapper"
|
||||||
|
:transform (str transform)}]
|
||||||
[mf/Fragment (obj/new)])]
|
[mf/Fragment (obj/new)])]
|
||||||
|
|
||||||
[:> (name tag) (clj->js attrs)
|
[:> (name tag) (clj->js attrs)
|
||||||
[:> wrapper wrapper-props
|
[:> wrapper wrapper-props
|
||||||
(for [node content] [:& svg-node {:node node
|
(for [node content] [:& svg-node {:type type
|
||||||
|
:node node
|
||||||
:prefix-id prefix-id
|
:prefix-id prefix-id
|
||||||
:transform transform}])]])))
|
:transform transform
|
||||||
|
:bounds bounds}])]])))
|
||||||
|
|
||||||
(mf/defc svg-defs [{:keys [shape render-id]}]
|
(mf/defc svg-defs [{:keys [shape render-id]}]
|
||||||
(let [svg-defs (:svg-defs shape)
|
(let [svg-defs (:svg-defs shape)
|
||||||
|
@ -91,8 +85,8 @@
|
||||||
(usvg/svg-transform-matrix shape)))
|
(usvg/svg-transform-matrix shape)))
|
||||||
|
|
||||||
;; Paths doesn't have transform so we have to transform its gradients
|
;; Paths doesn't have transform so we have to transform its gradients
|
||||||
transform (if (contains? shape :svg-transform)
|
transform (if (some? (:svg-transform shape))
|
||||||
(gmt/multiply transform (or (:svg-transform shape) (gmt/matrix)))
|
(gmt/multiply transform (:svg-transform shape))
|
||||||
transform)
|
transform)
|
||||||
|
|
||||||
prefix-id
|
prefix-id
|
||||||
|
@ -103,7 +97,9 @@
|
||||||
;; TODO: no key?
|
;; TODO: no key?
|
||||||
(when (seq svg-defs)
|
(when (seq svg-defs)
|
||||||
(for [svg-def (vals svg-defs)]
|
(for [svg-def (vals svg-defs)]
|
||||||
[:& svg-node {:node svg-def
|
[:& svg-node {:type (:type shape)
|
||||||
|
:node svg-def
|
||||||
:prefix-id prefix-id
|
:prefix-id prefix-id
|
||||||
:transform transform}]))))
|
:transform transform
|
||||||
|
:bounds (f/get-filters-bounds shape)}]))))
|
||||||
|
|
||||||
|
|
|
@ -117,8 +117,8 @@
|
||||||
;; Note that the "indeterminate" attribute only may be set by code, not as a static attribute.
|
;; Note that the "indeterminate" attribute only may be set by code, not as a static attribute.
|
||||||
;; See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#attr-indeterminate
|
;; See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#attr-indeterminate
|
||||||
(if (= hide-fill-on-export? :multiple)
|
(if (= hide-fill-on-export? :multiple)
|
||||||
(dom/set-attribute checkbox "indeterminate" true)
|
(dom/set-attribute! checkbox "indeterminate" true)
|
||||||
(dom/remove-attribute checkbox "indeterminate")))))
|
(dom/remove-attribute! checkbox "indeterminate")))))
|
||||||
|
|
||||||
[:div.element-set
|
[:div.element-set
|
||||||
[:div.element-set-title
|
[:div.element-set-title
|
||||||
|
|
|
@ -215,18 +215,19 @@
|
||||||
:text-y pos})))
|
:text-y pos})))
|
||||||
|
|
||||||
(defn guide-inside-vbox?
|
(defn guide-inside-vbox?
|
||||||
([vbox]
|
([zoom vbox]
|
||||||
(partial guide-inside-vbox? vbox))
|
(partial guide-inside-vbox? zoom vbox))
|
||||||
|
|
||||||
([{:keys [x y width height]} {:keys [axis position]}]
|
([zoom {:keys [x y width height]} {:keys [axis position]}]
|
||||||
(let [x1 x
|
(let [rule-area-size (/ rules/rule-area-size zoom)
|
||||||
|
x1 x
|
||||||
x2 (+ x width)
|
x2 (+ x width)
|
||||||
y1 y
|
y1 y
|
||||||
y2 (+ y height)]
|
y2 (+ y height)]
|
||||||
(if (= axis :x)
|
(if (= axis :x)
|
||||||
(and (>= position x1)
|
(and (>= position (+ x1 rule-area-size))
|
||||||
(<= position x2))
|
(<= position x2))
|
||||||
(and (>= position y1)
|
(and (>= position (+ y1 rule-area-size))
|
||||||
(<= position y2))))))
|
(<= position y2))))))
|
||||||
|
|
||||||
(defn guide-creation-area
|
(defn guide-creation-area
|
||||||
|
@ -383,7 +384,7 @@
|
||||||
(let [guide (-> guide
|
(let [guide (-> guide
|
||||||
(assoc :id (uuid/next)
|
(assoc :id (uuid/next)
|
||||||
:axis axis))]
|
:axis axis))]
|
||||||
(when (guide-inside-vbox? vbox guide)
|
(when (guide-inside-vbox? zoom vbox guide)
|
||||||
(st/emit! (dw/update-guides guide))))))
|
(st/emit! (dw/update-guides guide))))))
|
||||||
|
|
||||||
{:keys [on-pointer-enter
|
{:keys [on-pointer-enter
|
||||||
|
@ -431,7 +432,7 @@
|
||||||
(mf/deps page vbox)
|
(mf/deps page vbox)
|
||||||
#(->> (get-in page [:options :guides] {})
|
#(->> (get-in page [:options :guides] {})
|
||||||
(vals)
|
(vals)
|
||||||
(filter (guide-inside-vbox? vbox))))
|
(filter (guide-inside-vbox? zoom vbox))))
|
||||||
|
|
||||||
focus (mf/deref refs/workspace-focus-selected)
|
focus (mf/deref refs/workspace-focus-selected)
|
||||||
|
|
||||||
|
@ -448,7 +449,7 @@
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps vbox)
|
(mf/deps vbox)
|
||||||
(fn [guide]
|
(fn [guide]
|
||||||
(if (guide-inside-vbox? vbox guide)
|
(if (guide-inside-vbox? zoom vbox guide)
|
||||||
(st/emit! (dw/update-guides guide))
|
(st/emit! (dw/update-guides guide))
|
||||||
(st/emit! (dw/remove-guide guide)))))]
|
(st/emit! (dw/remove-guide guide)))))]
|
||||||
|
|
||||||
|
|
|
@ -201,25 +201,43 @@
|
||||||
(mf/use-memo
|
(mf/use-memo
|
||||||
(mf/deps modifiers)
|
(mf/deps modifiers)
|
||||||
(fn []
|
(fn []
|
||||||
|
(when (some? modifiers)
|
||||||
(d/mapm (fn [id {modifiers :modifiers}]
|
(d/mapm (fn [id {modifiers :modifiers}]
|
||||||
(let [center (gsh/center-shape (get objects id))]
|
(let [center (gsh/center-shape (get objects id))]
|
||||||
(gsh/modifiers->transform center modifiers)))
|
(gsh/modifiers->transform center modifiers)))
|
||||||
modifiers)))
|
modifiers))))
|
||||||
|
|
||||||
shapes
|
shapes
|
||||||
(mf/use-memo
|
(mf/use-memo
|
||||||
(mf/deps transforms)
|
(mf/deps transforms)
|
||||||
(fn []
|
(fn []
|
||||||
(->> (keys transforms)
|
(->> (keys transforms)
|
||||||
(mapv (d/getf objects)))))]
|
(mapv (d/getf objects)))))
|
||||||
|
|
||||||
|
prev-shapes (mf/use-var nil)
|
||||||
|
prev-modifiers (mf/use-var nil)
|
||||||
|
prev-transforms (mf/use-var nil)]
|
||||||
|
|
||||||
;; Layout effect is important so the code is executed before the modifiers
|
;; Layout effect is important so the code is executed before the modifiers
|
||||||
;; are applied to the shape
|
;; are applied to the shape
|
||||||
(mf/use-layout-effect
|
(mf/use-layout-effect
|
||||||
(mf/deps transforms)
|
(mf/deps transforms)
|
||||||
(fn []
|
(fn []
|
||||||
(utils/update-transform shapes transforms modifiers)
|
(when (and (nil? @prev-transforms)
|
||||||
#(utils/remove-transform shapes)))))
|
(some? transforms))
|
||||||
|
(utils/start-transform! shapes))
|
||||||
|
|
||||||
|
(when (some? modifiers)
|
||||||
|
(utils/update-transform! shapes transforms modifiers))
|
||||||
|
|
||||||
|
|
||||||
|
(when (and (some? @prev-modifiers)
|
||||||
|
(not (some? modifiers)))
|
||||||
|
(utils/remove-transform! @prev-shapes))
|
||||||
|
|
||||||
|
(reset! prev-modifiers modifiers)
|
||||||
|
(reset! prev-transforms transforms)
|
||||||
|
(reset! prev-shapes shapes)))))
|
||||||
|
|
||||||
(defn inside-vbox [vbox objects frame-id]
|
(defn inside-vbox [vbox objects frame-id]
|
||||||
(let [frame (get objects frame-id)]
|
(let [frame (get objects frame-id)]
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.main.ui.cursors :as cur]
|
[app.main.ui.cursors :as cur]
|
||||||
[app.util.dom :as dom]))
|
[app.util.dom :as dom]))
|
||||||
|
|
||||||
|
@ -100,7 +101,10 @@
|
||||||
(dom/query shape-node ".mask-shape")]
|
(dom/query shape-node ".mask-shape")]
|
||||||
|
|
||||||
group?
|
group?
|
||||||
[]
|
(let [shape-defs (dom/query shape-node "defs")]
|
||||||
|
(d/concat-vec
|
||||||
|
(dom/query-all shape-defs ".svg-def")
|
||||||
|
(dom/query-all shape-defs ".svg-mask-wrapper")))
|
||||||
|
|
||||||
text?
|
text?
|
||||||
[shape-node
|
[shape-node
|
||||||
|
@ -112,7 +116,59 @@
|
||||||
:else
|
:else
|
||||||
[shape-node])))
|
[shape-node])))
|
||||||
|
|
||||||
(defn update-transform [shapes transforms modifiers]
|
(defn transform-region!
|
||||||
|
[node modifiers]
|
||||||
|
|
||||||
|
(let [{:keys [x y width height]}
|
||||||
|
(-> (gsh/make-selrect
|
||||||
|
(-> (dom/get-attribute node "data-old-x") d/parse-double)
|
||||||
|
(-> (dom/get-attribute node "data-old-y") d/parse-double)
|
||||||
|
(-> (dom/get-attribute node "data-old-width") d/parse-double)
|
||||||
|
(-> (dom/get-attribute node "data-old-height") d/parse-double))
|
||||||
|
(gsh/transform-selrect modifiers))]
|
||||||
|
(dom/set-attribute! node "x" x)
|
||||||
|
(dom/set-attribute! node "y" y)
|
||||||
|
(dom/set-attribute! node "width" width)
|
||||||
|
(dom/set-attribute! node "height" height)))
|
||||||
|
|
||||||
|
(defn start-transform!
|
||||||
|
[shapes]
|
||||||
|
(doseq [shape shapes]
|
||||||
|
(when-let [nodes (get-nodes shape)]
|
||||||
|
(doseq [node nodes]
|
||||||
|
(let [old-transform (dom/get-attribute node "transform")]
|
||||||
|
(when (some? old-transform)
|
||||||
|
(dom/set-attribute! node "data-old-transform" old-transform))
|
||||||
|
|
||||||
|
(when (or (= (dom/get-tag-name node) "linearGradient")
|
||||||
|
(= (dom/get-tag-name node) "radialGradient"))
|
||||||
|
(let [gradient-transform (dom/get-attribute node "gradientTransform")]
|
||||||
|
(when (some? gradient-transform)
|
||||||
|
(dom/set-attribute! node "data-old-gradientTransform" gradient-transform))))
|
||||||
|
|
||||||
|
(when (= (dom/get-tag-name node) "pattern")
|
||||||
|
(let [pattern-transform (dom/get-attribute node "patternTransform")]
|
||||||
|
(when (some? pattern-transform)
|
||||||
|
(dom/set-attribute! node "data-old-patternTransform" pattern-transform))))
|
||||||
|
|
||||||
|
(when (or (= (dom/get-tag-name node) "mask")
|
||||||
|
(= (dom/get-tag-name node) "filter"))
|
||||||
|
(dom/set-attribute! node "data-old-x" (dom/get-attribute node "x"))
|
||||||
|
(dom/set-attribute! node "data-old-y" (dom/get-attribute node "y"))
|
||||||
|
(dom/set-attribute! node "data-old-width" (dom/get-attribute node "width"))
|
||||||
|
(dom/set-attribute! node "data-old-height" (dom/get-attribute node "height"))))))))
|
||||||
|
|
||||||
|
(defn set-transform-att!
|
||||||
|
[node att value]
|
||||||
|
|
||||||
|
(let [old-att (dom/get-attribute node (dm/str "data-old-" att))
|
||||||
|
new-value (if (some? old-att)
|
||||||
|
(dm/str value " " old-att)
|
||||||
|
(str value))]
|
||||||
|
(dom/set-attribute! node att (str new-value))))
|
||||||
|
|
||||||
|
(defn update-transform!
|
||||||
|
[shapes transforms modifiers]
|
||||||
(doseq [{:keys [id type] :as shape} shapes]
|
(doseq [{:keys [id type] :as shape} shapes]
|
||||||
(when-let [nodes (get-nodes shape)]
|
(when-let [nodes (get-nodes shape)]
|
||||||
(let [transform (get transforms id)
|
(let [transform (get transforms id)
|
||||||
|
@ -127,24 +183,38 @@
|
||||||
|
|
||||||
(doseq [node nodes]
|
(doseq [node nodes]
|
||||||
(cond
|
(cond
|
||||||
(or (dom/class? node "text-shape") (dom/class? node "text-svg"))
|
;; Text shapes need special treatment because their resize only change
|
||||||
|
;; the text area, not the change size/position
|
||||||
|
(or (dom/class? node "text-shape")
|
||||||
|
(dom/class? node "text-svg"))
|
||||||
(when (some? text-transform)
|
(when (some? text-transform)
|
||||||
(dom/set-attribute node "transform" (str text-transform)))
|
(set-transform-att! node "transform" text-transform))
|
||||||
|
|
||||||
(or (= (dom/get-tag-name node) "foreignObject")
|
(or (= (dom/get-tag-name node) "foreignObject")
|
||||||
(dom/class? node "text-clip"))
|
(dom/class? node "text-clip"))
|
||||||
(let [cur-width (dom/get-attribute node "width")
|
(let [cur-width (dom/get-attribute node "width")
|
||||||
cur-height (dom/get-attribute node "height")]
|
cur-height (dom/get-attribute node "height")]
|
||||||
(when (and (some? text-width) (not= cur-width text-width))
|
(when (and (some? text-width) (not= cur-width text-width))
|
||||||
(dom/set-attribute node "width" text-width))
|
(dom/set-attribute! node "width" text-width))
|
||||||
|
|
||||||
(when (and (some? text-height) (not= cur-height text-height))
|
(when (and (some? text-height) (not= cur-height text-height))
|
||||||
(dom/set-attribute node "height" text-height)))
|
(dom/set-attribute! node "height" text-height)))
|
||||||
|
|
||||||
|
(or (= (dom/get-tag-name node) "mask")
|
||||||
|
(= (dom/get-tag-name node) "filter"))
|
||||||
|
(transform-region! node modifiers)
|
||||||
|
|
||||||
|
(or (= (dom/get-tag-name node) "linearGradient")
|
||||||
|
(= (dom/get-tag-name node) "radialGradient"))
|
||||||
|
(set-transform-att! node "gradientTransform" transform)
|
||||||
|
|
||||||
|
(= (dom/get-tag-name node) "pattern")
|
||||||
|
(set-transform-att! node "patternTransform" transform)
|
||||||
|
|
||||||
(and (some? transform) (some? node))
|
(and (some? transform) (some? node))
|
||||||
(dom/set-attribute node "transform" (str transform))))))))
|
(set-transform-att! node "transform" transform)))))))
|
||||||
|
|
||||||
(defn remove-transform [shapes]
|
(defn remove-transform!
|
||||||
|
[shapes]
|
||||||
(doseq [shape shapes]
|
(doseq [shape shapes]
|
||||||
(when-let [nodes (get-nodes shape)]
|
(when-let [nodes (get-nodes shape)]
|
||||||
(doseq [node nodes]
|
(doseq [node nodes]
|
||||||
|
@ -155,7 +225,10 @@
|
||||||
nil
|
nil
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(dom/remove-attribute node "transform")))))))
|
(let [old-transform (dom/get-attribute node "data-old-transform")]
|
||||||
|
(when-not (some? old-transform)
|
||||||
|
(dom/remove-attribute! node "data-old-transform")
|
||||||
|
(dom/remove-attribute! node "transform")))))))))
|
||||||
|
|
||||||
(defn format-viewbox [vbox]
|
(defn format-viewbox [vbox]
|
||||||
(dm/str (:x vbox 0) " "
|
(dm/str (:x vbox 0) " "
|
||||||
|
|
|
@ -415,11 +415,11 @@
|
||||||
"application/pdf" "pdf"
|
"application/pdf" "pdf"
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
(defn set-attribute [^js node ^string attr value]
|
(defn set-attribute! [^js node ^string attr value]
|
||||||
(when (some? node)
|
(when (some? node)
|
||||||
(.setAttribute node attr value)))
|
(.setAttribute node attr value)))
|
||||||
|
|
||||||
(defn remove-attribute [^js node ^string attr]
|
(defn remove-attribute! [^js node ^string attr]
|
||||||
(when (some? node)
|
(when (some? node)
|
||||||
(.removeAttribute node attr)))
|
(.removeAttribute node attr)))
|
||||||
|
|
||||||
|
|
|
@ -715,7 +715,8 @@
|
||||||
(gmt/matrix)
|
(gmt/matrix)
|
||||||
|
|
||||||
;; Paths doesn't have transform so we have to transform its gradients
|
;; Paths doesn't have transform so we have to transform its gradients
|
||||||
(if (= :path (:type shape))
|
(if (or (= :path (:type shape))
|
||||||
|
(= :group (:type shape)))
|
||||||
(gsh/transform-matrix shape)
|
(gsh/transform-matrix shape)
|
||||||
(gmt/matrix))
|
(gmt/matrix))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue