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