mirror of
https://github.com/penpot/penpot.git
synced 2025-01-24 23:49:45 -05:00
✨ Adds flip,proportion and rotation
This commit is contained in:
parent
3aa5fda695
commit
dd15bf7328
3 changed files with 130 additions and 78 deletions
|
@ -156,7 +156,8 @@
|
||||||
|
|
||||||
(mapv #(update % :params transform-params) content)))
|
(mapv #(update % :params transform-params) content)))
|
||||||
|
|
||||||
(defn transform-content [content transform]
|
(defn transform-content
|
||||||
|
[content transform]
|
||||||
(let [set-tr (fn [params px py]
|
(let [set-tr (fn [params px py]
|
||||||
(let [tr-point (-> (gpt/point (get params px) (get params py))
|
(let [tr-point (-> (gpt/point (get params px) (get params py))
|
||||||
(gpt/transform transform))]
|
(gpt/transform transform))]
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.util.json :as json]
|
[app.util.json :as json]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.svg :as usvg]
|
[app.util.svg :as usvg]
|
||||||
|
@ -29,43 +30,58 @@
|
||||||
:else
|
:else
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
|
(defn bool->str [val]
|
||||||
|
(when (some? val) (str val)))
|
||||||
|
|
||||||
(defn add-data
|
(defn add-data
|
||||||
"Adds as metadata properties that we cannot deduce from the exported SVG"
|
"Adds as metadata properties that we cannot deduce from the exported SVG"
|
||||||
[props shape]
|
[props shape]
|
||||||
(let [add!
|
(letfn [(add!
|
||||||
(fn [props attr val]
|
([props attr]
|
||||||
(let [ns-attr (str "penpot:" (-> attr d/name))]
|
(add! props attr str))
|
||||||
(-> props
|
|
||||||
(obj/set! ns-attr val))))
|
|
||||||
frame? (= :frame (:type shape))
|
|
||||||
group? (= :group (:type shape))
|
|
||||||
rect? (= :rect (:type shape))
|
|
||||||
text? (= :text (:type shape))
|
|
||||||
mask? (and group? (:masked-group? shape))]
|
|
||||||
(-> props
|
|
||||||
(add! :name (-> shape :name))
|
|
||||||
(add! :blocked (-> shape (:blocked false) str))
|
|
||||||
(add! :hidden (-> shape (:hidden false) str))
|
|
||||||
(add! :type (-> shape :type d/name))
|
|
||||||
|
|
||||||
(add! :stroke-style (-> shape (:stroke-style :none) d/name))
|
([props attr trfn]
|
||||||
(add! :stroke-alignment (-> shape (:stroke-alignment :center) d/name))
|
(let [val (get shape attr)
|
||||||
|
val (if (keyword? val) (d/name val) val)
|
||||||
|
ns-attr (str "penpot:" (-> attr d/name))]
|
||||||
|
(cond-> props
|
||||||
|
(some? val)
|
||||||
|
(obj/set! ns-attr (trfn val))))))]
|
||||||
|
(let [frame? (= :frame (:type shape))
|
||||||
|
group? (= :group (:type shape))
|
||||||
|
rect? (= :rect (:type shape))
|
||||||
|
text? (= :text (:type shape))
|
||||||
|
mask? (and group? (:masked-group? shape))
|
||||||
|
center (gsh/center-shape shape)]
|
||||||
|
(-> props
|
||||||
|
(add! :name)
|
||||||
|
(add! :blocked)
|
||||||
|
(add! :hidden)
|
||||||
|
(add! :type)
|
||||||
|
(add! :stroke-style)
|
||||||
|
(add! :stroke-alignment)
|
||||||
|
(add! :transform)
|
||||||
|
(add! :transform-inverse)
|
||||||
|
(add! :flip-x)
|
||||||
|
(add! :flip-y)
|
||||||
|
(add! :proportion)
|
||||||
|
(add! :proportion-lock)
|
||||||
|
(add! :rotation)
|
||||||
|
(obj/set! "penpot:center-x" (-> center :x str))
|
||||||
|
(obj/set! "penpot:center-y" (-> center :y str))
|
||||||
|
|
||||||
(add! :transform (-> shape (:transform (gmt/matrix)) str))
|
(cond-> (and rect? (some? (:r1 shape)))
|
||||||
(add! :transform-inverse (-> shape (:transform-inverse (gmt/matrix)) str))
|
(-> (add! :r1)
|
||||||
|
(add! :r2)
|
||||||
|
(add! :r3)
|
||||||
|
(add! :r4)))
|
||||||
|
|
||||||
(cond-> (and rect? (some? (:r1 shape)))
|
(cond-> text?
|
||||||
(-> (add! :r1 (-> shape (:r1 0) str))
|
(-> (add! :grow-type)
|
||||||
(add! :r2 (-> shape (:r2 0) str))
|
(add! :content json/encode)))
|
||||||
(add! :r3 (-> shape (:r3 0) str))
|
|
||||||
(add! :r4 (-> shape (:r4 0) str))))
|
|
||||||
|
|
||||||
(cond-> text?
|
(cond-> mask?
|
||||||
(-> (add! :grow-type (-> shape :grow-type))
|
(obj/set! "penpot:masked-group" "true"))))))
|
||||||
(add! :content (-> shape :content json/encode))))
|
|
||||||
|
|
||||||
(cond-> mask?
|
|
||||||
(add! :masked-group "true")))))
|
|
||||||
|
|
||||||
(mf/defc export-data
|
(mf/defc export-data
|
||||||
[{:keys [shape]}]
|
[{:keys [shape]}]
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.util.color :as uc]
|
[app.util.color :as uc]
|
||||||
[app.util.json :as json]
|
[app.util.json :as json]
|
||||||
|
@ -50,6 +51,10 @@
|
||||||
(or (close? node)
|
(or (close? node)
|
||||||
(some? (get-data node))))
|
(some? (get-data node))))
|
||||||
|
|
||||||
|
(defn str->bool
|
||||||
|
[val]
|
||||||
|
(when (some? val) (= val "true")))
|
||||||
|
|
||||||
(defn get-meta
|
(defn get-meta
|
||||||
([m att]
|
([m att]
|
||||||
(get-meta m att identity))
|
(get-meta m att identity))
|
||||||
|
@ -133,16 +138,32 @@
|
||||||
:height (* (:ry values) 2)}))
|
:height (* (:ry values) 2)}))
|
||||||
|
|
||||||
(defn parse-path
|
(defn parse-path
|
||||||
[props svg-data]
|
[props center svg-data]
|
||||||
(let [content (upp/parse-path (:d svg-data))
|
(let [transform-inverse (:transform-inverse props (gmt/matrix))
|
||||||
selrect (gsh/content->selrect content)
|
transform (:transform props (gmt/matrix))
|
||||||
points (gsh/rect->points selrect)]
|
content (upp/parse-path (:d svg-data))
|
||||||
|
content-tr (gsh/transform-content
|
||||||
|
content
|
||||||
|
(gmt/transform-in center transform-inverse))
|
||||||
|
selrect (gsh/content->selrect content-tr)
|
||||||
|
points (-> (gsh/rect->points selrect)
|
||||||
|
(gsh/transform-points center transform))]
|
||||||
(-> props
|
(-> props
|
||||||
(assoc :content content)
|
(assoc :content content)
|
||||||
(assoc :selrect selrect)
|
(assoc :selrect selrect)
|
||||||
(assoc :points points))))
|
(assoc :points points))))
|
||||||
|
|
||||||
|
(defn setup-selrect [props]
|
||||||
|
(let [data (select-keys props [:x :y :width :height])
|
||||||
|
transform (:transform props (gmt/matrix))
|
||||||
|
selrect (gsh/rect->selrect data)
|
||||||
|
points (gsh/rect->points data)
|
||||||
|
center (gsh/center-rect data)]
|
||||||
|
|
||||||
|
(assoc props
|
||||||
|
:selrect selrect
|
||||||
|
:points (gsh/transform-points points center transform))))
|
||||||
|
|
||||||
(def url-regex #"url\(#([^\)]*)\)")
|
(def url-regex #"url\(#([^\)]*)\)")
|
||||||
|
|
||||||
(defn seek-node
|
(defn seek-node
|
||||||
|
@ -198,23 +219,52 @@
|
||||||
(contains? (:attrs svg-content) :penpot:height)
|
(contains? (:attrs svg-content) :penpot:height)
|
||||||
(assoc :height (-> svg-content :attrs :penpot:height d/parse-double)))))
|
(assoc :height (-> svg-content :attrs :penpot:height d/parse-double)))))
|
||||||
|
|
||||||
|
(defn add-common-data
|
||||||
|
[props node]
|
||||||
|
|
||||||
|
(let [name (get-meta node :name)
|
||||||
|
blocked (get-meta node :blocked str->bool)
|
||||||
|
hidden (get-meta node :hidden str->bool)
|
||||||
|
transform (get-meta node :transform gmt/str->matrix)
|
||||||
|
transform-inverse (get-meta node :transform-inverse gmt/str->matrix)
|
||||||
|
flip-x (get-meta node :flip-x str->bool)
|
||||||
|
flip-y (get-meta node :flip-y str->bool)
|
||||||
|
proportion (get-meta node :proportion d/parse-double)
|
||||||
|
proportion-lock (get-meta node :proportion-lock str->bool)
|
||||||
|
rotation (get-meta node :rotation d/parse-double)]
|
||||||
|
|
||||||
|
(-> props
|
||||||
|
(assoc :name name)
|
||||||
|
(assoc :blocked blocked)
|
||||||
|
(assoc :hidden hidden)
|
||||||
|
(assoc :transform transform)
|
||||||
|
(assoc :transform-inverse transform-inverse)
|
||||||
|
(assoc :flip-x flip-x)
|
||||||
|
(assoc :flip-y flip-y)
|
||||||
|
(assoc :proportion proportion)
|
||||||
|
(assoc :proportion-lock proportion-lock)
|
||||||
|
(assoc :rotation rotation))))
|
||||||
|
|
||||||
(defn add-position
|
(defn add-position
|
||||||
[props type node svg-data]
|
[props type node svg-data]
|
||||||
(cond-> props
|
(let [center-x (get-meta node :center-x d/parse-double)
|
||||||
(has-position? type)
|
center-y (get-meta node :center-y d/parse-double)
|
||||||
(-> (parse-position svg-data)
|
center (gpt/point center-x center-y)]
|
||||||
(gsh/setup-selrect))
|
(cond-> props
|
||||||
|
(has-position? type)
|
||||||
|
(parse-position svg-data)
|
||||||
|
|
||||||
(= type :svg-raw)
|
(= type :svg-raw)
|
||||||
(-> (add-svg-position node)
|
(add-svg-position node)
|
||||||
(gsh/setup-selrect))
|
|
||||||
|
|
||||||
(= type :circle)
|
(= type :circle)
|
||||||
(-> (parse-circle svg-data)
|
(parse-circle svg-data)
|
||||||
(gsh/setup-selrect))
|
|
||||||
|
|
||||||
(= type :path)
|
(= type :path)
|
||||||
(parse-path svg-data)))
|
(parse-path center svg-data)
|
||||||
|
|
||||||
|
(or (has-position? type) (= type :svg-raw) (= type :circle))
|
||||||
|
(setup-selrect))))
|
||||||
|
|
||||||
(defn add-fill
|
(defn add-fill
|
||||||
[props node svg-data]
|
[props node svg-data]
|
||||||
|
@ -293,10 +343,6 @@
|
||||||
(assoc :grow-type (get-meta node :grow-type keyword))
|
(assoc :grow-type (get-meta node :grow-type keyword))
|
||||||
(assoc :content (get-meta node :content json/decode))))
|
(assoc :content (get-meta node :content json/decode))))
|
||||||
|
|
||||||
(defn str->bool
|
|
||||||
[val]
|
|
||||||
(= val "true"))
|
|
||||||
|
|
||||||
(defn add-group-data
|
(defn add-group-data
|
||||||
[props node]
|
[props node]
|
||||||
(let [mask? (get-meta node :masked-group str->bool)]
|
(let [mask? (get-meta node :masked-group str->bool)]
|
||||||
|
@ -462,16 +508,19 @@
|
||||||
(let [svg-content (get-data node :penpot:svg-content)
|
(let [svg-content (get-data node :penpot:svg-content)
|
||||||
attrs (-> (:attrs svg-content) (without-penpot-prefix))
|
attrs (-> (:attrs svg-content) (without-penpot-prefix))
|
||||||
tag (-> svg-content :attrs :penpot:tag keyword)
|
tag (-> svg-content :attrs :penpot:tag keyword)
|
||||||
content {:attrs attrs
|
|
||||||
:tag tag
|
|
||||||
:content (cond
|
|
||||||
(= tag :svg)
|
|
||||||
(->> node :content last :content last :content fix-style-attr)
|
|
||||||
|
|
||||||
(= tag :text)
|
node-content
|
||||||
(-> node :content last :content))}]
|
(cond
|
||||||
(-> props
|
(= tag :svg)
|
||||||
(assoc :content content))))
|
(->> node :content last :content last :content fix-style-attr)
|
||||||
|
|
||||||
|
(= tag :text)
|
||||||
|
(-> node :content last :content))]
|
||||||
|
(assoc
|
||||||
|
props :content
|
||||||
|
{:attrs attrs
|
||||||
|
:tag tag
|
||||||
|
:content node-content})))
|
||||||
|
|
||||||
(defn get-image-name
|
(defn get-image-name
|
||||||
[node]
|
[node]
|
||||||
|
@ -486,17 +535,9 @@
|
||||||
[type node]
|
[type node]
|
||||||
|
|
||||||
(when-not (close? node)
|
(when-not (close? node)
|
||||||
(let [name (get-meta node :name)
|
(let [svg-data (get-svg-data type node)]
|
||||||
blocked (get-meta node :blocked str->bool)
|
|
||||||
hidden (get-meta node :hidden str->bool)
|
|
||||||
transform (get-meta node :transform gmt/str->matrix)
|
|
||||||
transform-inverse (get-meta node :transform-inverse gmt/str->matrix)
|
|
||||||
svg-data (get-svg-data type node)]
|
|
||||||
|
|
||||||
(-> {}
|
(-> {}
|
||||||
(assoc :name name)
|
(add-common-data node)
|
||||||
(assoc :blocked blocked)
|
|
||||||
(assoc :hidden hidden)
|
|
||||||
(add-position type node svg-data)
|
(add-position type node svg-data)
|
||||||
(add-fill node svg-data)
|
(add-fill node svg-data)
|
||||||
(add-stroke node svg-data)
|
(add-stroke node svg-data)
|
||||||
|
@ -519,10 +560,4 @@
|
||||||
(add-image-data node))
|
(add-image-data node))
|
||||||
|
|
||||||
(cond-> (= :text type)
|
(cond-> (= :text type)
|
||||||
(add-text-data node))
|
(add-text-data node))))))
|
||||||
|
|
||||||
(cond-> (some? transform)
|
|
||||||
(assoc :transform transform))
|
|
||||||
|
|
||||||
(cond-> (some? transform-inverse)
|
|
||||||
(assoc :transform-inverse transform-inverse))))))
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue