mirror of
https://github.com/penpot/penpot.git
synced 2025-05-31 00:46:11 +02:00
✨ Migrates model to the new paths
This commit is contained in:
parent
e2593c2dad
commit
f339f1ee98
13 changed files with 114 additions and 82 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -30,3 +30,4 @@ node_modules
|
||||||
/media
|
/media
|
||||||
/deploy
|
/deploy
|
||||||
/web
|
/web
|
||||||
|
/_dump
|
||||||
|
|
|
@ -233,12 +233,11 @@
|
||||||
|
|
||||||
|
|
||||||
(defn setup-selrect [{:keys [x y width height] :as shape}]
|
(defn setup-selrect [{:keys [x y width height] :as shape}]
|
||||||
(-> shape
|
(let [selrect (gpr/rect->selrect shape)
|
||||||
(assoc :selrect
|
points (gpr/rect->points shape)]
|
||||||
{:x x :y y
|
(-> shape
|
||||||
:width width :height height
|
(assoc :selrect selrect
|
||||||
:x1 x :y1 y
|
:points points))))
|
||||||
:x2 (+ x width) :y2 (+ y height)})))
|
|
||||||
|
|
||||||
|
|
||||||
;; EXPORTS
|
;; EXPORTS
|
||||||
|
|
|
@ -161,3 +161,20 @@
|
||||||
(:c2y params) (update-in [index :params :c2y] + (:c2y params)))
|
(:c2y params) (update-in [index :params :c2y] + (:c2y params)))
|
||||||
content))]
|
content))]
|
||||||
(reduce red-fn content modifiers)))
|
(reduce red-fn content modifiers)))
|
||||||
|
|
||||||
|
(defn segments->content
|
||||||
|
([segments]
|
||||||
|
(segments->content segments false))
|
||||||
|
|
||||||
|
([segments closed?]
|
||||||
|
(let [initial (first segments)
|
||||||
|
lines (rest segments)]
|
||||||
|
|
||||||
|
(d/concat [{:command :move-to
|
||||||
|
:params (select-keys initial [:x :y])}]
|
||||||
|
(->> lines
|
||||||
|
(mapv #(hash-map :command :line-to
|
||||||
|
:params (select-keys % [:x :y]))))
|
||||||
|
|
||||||
|
(when closed?
|
||||||
|
[{:command :close-path}])))))
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
(gpt/point x (+ y height))])
|
(gpt/point x (+ y height))])
|
||||||
|
|
||||||
(defn points->rect [points]
|
(defn points->rect [points]
|
||||||
(let [minx (transduce (map :x) min ##Inf points)
|
(let [minx (transduce (comp (map :x) (remove nil?)) min ##Inf points)
|
||||||
miny (transduce (map :y) min ##Inf points)
|
miny (transduce (comp (map :y) (remove nil?)) min ##Inf points)
|
||||||
maxx (transduce (map :x) max ##-Inf points)
|
maxx (transduce (comp (map :x) (remove nil?)) max ##-Inf points)
|
||||||
maxy (transduce (map :y) max ##-Inf points)]
|
maxy (transduce (comp (map :y) (remove nil?)) max ##-Inf points)]
|
||||||
{:x minx
|
{:x minx
|
||||||
:y miny
|
:y miny
|
||||||
:width (- maxx minx)
|
:width (- maxx minx)
|
||||||
|
@ -45,10 +45,10 @@
|
||||||
(-> rect rect->points points->selrect))
|
(-> rect rect->points points->selrect))
|
||||||
|
|
||||||
(defn join-selrects [selrects]
|
(defn join-selrects [selrects]
|
||||||
(let [minx (transduce (map :x1) min ##Inf selrects)
|
(let [minx (transduce (comp (map :x1) (remove nil?)) min ##Inf selrects)
|
||||||
miny (transduce (map :y1) min ##Inf selrects)
|
miny (transduce (comp (map :y1) (remove nil?)) min ##Inf selrects)
|
||||||
maxx (transduce (map :x2) max ##-Inf selrects)
|
maxx (transduce (comp (map :x2) (remove nil?)) max ##-Inf selrects)
|
||||||
maxy (transduce (map :y2) max ##-Inf selrects)]
|
maxy (transduce (comp (map :y2) (remove nil?)) max ##-Inf selrects)]
|
||||||
{:x minx
|
{:x minx
|
||||||
:y miny
|
:y miny
|
||||||
:x1 minx
|
:x1 minx
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
|
||||||
(def file-version 2)
|
(def file-version 3)
|
||||||
(def max-safe-int 9007199254740991)
|
(def max-safe-int 9007199254740991)
|
||||||
(def min-safe-int -9007199254740991)
|
(def min-safe-int -9007199254740991)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.pages :as cp]
|
[app.common.pages :as cp]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.geom.shapes.path :as gsp]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
|
@ -35,7 +36,6 @@
|
||||||
;; -- MIGRATIONS --
|
;; -- MIGRATIONS --
|
||||||
|
|
||||||
;; Ensure that all :shape attributes on shapes are vectors.
|
;; Ensure that all :shape attributes on shapes are vectors.
|
||||||
|
|
||||||
(defmethod migrate 2
|
(defmethod migrate 2
|
||||||
[data]
|
[data]
|
||||||
(letfn [(update-object [id object]
|
(letfn [(update-object [id object]
|
||||||
|
@ -49,3 +49,63 @@
|
||||||
(update page :objects #(d/mapm update-object %)))]
|
(update page :objects #(d/mapm update-object %)))]
|
||||||
|
|
||||||
(update data :pages-index #(d/mapm update-page %))))
|
(update data :pages-index #(d/mapm update-page %))))
|
||||||
|
|
||||||
|
;; Changes paths formats
|
||||||
|
(defmethod migrate 3
|
||||||
|
[data]
|
||||||
|
(letfn [(migrate-path [shape]
|
||||||
|
(if-not (contains? shape :content)
|
||||||
|
(let [content (gsp/segments->content (:segments shape) (:close? shape))
|
||||||
|
selrect (gsh/content->selrect content)
|
||||||
|
points (gsh/rect->points selrect)]
|
||||||
|
(-> shape
|
||||||
|
(dissoc :segments)
|
||||||
|
(dissoc :close?)
|
||||||
|
(assoc :content content)
|
||||||
|
(assoc :selrect selrect)
|
||||||
|
(assoc :points points)))
|
||||||
|
;; If the shape contains :content is already in the new format
|
||||||
|
shape))
|
||||||
|
|
||||||
|
(fix-frames-selrects [frame]
|
||||||
|
(if (= (:id frame) uuid/zero)
|
||||||
|
frame
|
||||||
|
(let [frame-rect (select-keys frame [:x :y :width :height])]
|
||||||
|
(-> frame
|
||||||
|
(assoc :selrect (gsh/rect->selrect frame-rect))
|
||||||
|
(assoc :points (gsh/rect->points frame-rect))))))
|
||||||
|
|
||||||
|
(fix-empty-points [shape]
|
||||||
|
(let [shape (cond-> shape
|
||||||
|
(empty? (:selrect shape)) (gsh/setup-selrect))]
|
||||||
|
(cond-> shape
|
||||||
|
(empty? (:points shape))
|
||||||
|
(assoc :points (gsh/rect->points (:selrect shape))))))
|
||||||
|
|
||||||
|
(update-object [id object]
|
||||||
|
(cond-> object
|
||||||
|
(= :curve (:type object))
|
||||||
|
(assoc :type :path)
|
||||||
|
|
||||||
|
(or (#{:curve :path} (:type object)))
|
||||||
|
(migrate-path)
|
||||||
|
|
||||||
|
(= :frame (:type object))
|
||||||
|
(fix-frames-selrects)
|
||||||
|
|
||||||
|
(and (empty? (:points object)) (not= (:id object) uuid/zero))
|
||||||
|
(fix-empty-points)
|
||||||
|
|
||||||
|
:always
|
||||||
|
(->
|
||||||
|
;; Setup an empty transformation to re-calculate selrects
|
||||||
|
;; and points data
|
||||||
|
(assoc :modifiers {:displacement (gmt/matrix)})
|
||||||
|
(gsh/transform-shape))
|
||||||
|
|
||||||
|
))
|
||||||
|
|
||||||
|
(update-page [id page]
|
||||||
|
(update page :objects #(d/mapm update-object %)))]
|
||||||
|
|
||||||
|
(update data :pages-index #(d/mapm update-page %))))
|
||||||
|
|
|
@ -206,6 +206,12 @@
|
||||||
|
|
||||||
&.menu {
|
&.menu {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-end;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
fill: $color-gray-60;
|
fill: $color-gray-60;
|
||||||
|
|
|
@ -1046,22 +1046,6 @@
|
||||||
(rx/of (dwt/set-modifiers [id] {:displacement displ})
|
(rx/of (dwt/set-modifiers [id] {:displacement displ})
|
||||||
(dwt/apply-modifiers [id]))))))
|
(dwt/apply-modifiers [id]))))))
|
||||||
|
|
||||||
;; --- Path Modifications
|
|
||||||
|
|
||||||
(defn update-path
|
|
||||||
"Update a concrete point in the path shape."
|
|
||||||
[id index delta]
|
|
||||||
(us/verify ::us/uuid id)
|
|
||||||
(us/verify ::us/integer index)
|
|
||||||
(us/verify gpt/point? delta)
|
|
||||||
#_(ptk/reify ::update-path
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(let [page-id (:current-page-id state)]
|
|
||||||
(-> state
|
|
||||||
(update-in [:workspace-data page-id :objects id :segments index] gpt/add delta)
|
|
||||||
(update-in [:workspace-data page-id :objects id] gsh/update-path-selrect))))))
|
|
||||||
|
|
||||||
;; --- Shape attrs (Layers Sidebar)
|
;; --- Shape attrs (Layers Sidebar)
|
||||||
|
|
||||||
(defn toggle-collapse
|
(defn toggle-collapse
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
[potok.core :as ptk]
|
[potok.core :as ptk]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.geom.shapes.path :as gsp]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.util.geom.path :as path]
|
[app.util.geom.path :as path]
|
||||||
[app.main.data.workspace.drawing.common :as common]))
|
[app.main.data.workspace.drawing.common :as common]))
|
||||||
|
@ -29,7 +30,7 @@
|
||||||
(update-in state [:workspace-drawing :object :segments] (fnil conj []) point))
|
(update-in state [:workspace-drawing :object :segments] (fnil conj []) point))
|
||||||
|
|
||||||
(defn curve-to-path [{:keys [segments] :as shape}]
|
(defn curve-to-path [{:keys [segments] :as shape}]
|
||||||
(let [content (path/segments->content segments)
|
(let [content (gsp/segments->content segments)
|
||||||
selrect (gsh/content->selrect content)
|
selrect (gsh/content->selrect content)
|
||||||
points (gsh/rect->points selrect)]
|
points (gsh/rect->points selrect)]
|
||||||
(-> shape
|
(-> shape
|
||||||
|
|
|
@ -20,28 +20,6 @@
|
||||||
|
|
||||||
;; --- Path Shape
|
;; --- Path Shape
|
||||||
|
|
||||||
;; LEGACY FORMAT
|
|
||||||
(defn- render-path
|
|
||||||
[{:keys [segments close?] :as shape}]
|
|
||||||
(let [numsegs (count segments)]
|
|
||||||
(loop [buffer []
|
|
||||||
index 0]
|
|
||||||
(cond
|
|
||||||
(>= index numsegs)
|
|
||||||
(if close?
|
|
||||||
(str/join " " (conj buffer "Z"))
|
|
||||||
(str/join " " buffer))
|
|
||||||
|
|
||||||
(zero? index)
|
|
||||||
(let [{:keys [x y] :as segment} (nth segments index)
|
|
||||||
buffer (conj buffer (str/istr "M~{x},~{y}"))]
|
|
||||||
(recur buffer (inc index)))
|
|
||||||
|
|
||||||
:else
|
|
||||||
(let [{:keys [x y] :as segment} (nth segments index)
|
|
||||||
buffer (conj buffer (str/istr "L~{x},~{y}"))]
|
|
||||||
(recur buffer (inc index)))))))
|
|
||||||
|
|
||||||
(mf/defc path-shape
|
(mf/defc path-shape
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[props]
|
[props]
|
||||||
|
@ -51,10 +29,7 @@
|
||||||
{:keys [id x y width height]} (:selrect shape)
|
{:keys [id x y width height]} (:selrect shape)
|
||||||
mask-id (mf/use-ctx mask-id-ctx)
|
mask-id (mf/use-ctx mask-id-ctx)
|
||||||
transform (geom/transform-matrix shape)
|
transform (geom/transform-matrix shape)
|
||||||
pdata (if (:content shape)
|
pdata (ugp/content->path (:content shape))
|
||||||
(ugp/content->path (:content shape))
|
|
||||||
(render-path shape))
|
|
||||||
|
|
||||||
props (-> (attrs/extract-style-attrs shape)
|
props (-> (attrs/extract-style-attrs shape)
|
||||||
(obj/merge!
|
(obj/merge!
|
||||||
#js {:transform transform
|
#js {:transform transform
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[rumext.util :refer [map->obj]]
|
[rumext.util :refer [map->obj]]
|
||||||
[app.main.ui.shapes.path :as path]
|
[app.main.refs :as refs]
|
||||||
[app.main.refs :as refs]))
|
[app.util.geom.path :as ugp]))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc outline
|
(mf/defc outline
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
:ry (/ height 2)}
|
:ry (/ height 2)}
|
||||||
|
|
||||||
:path
|
:path
|
||||||
{:d (path/render-path shape)}
|
{:d (ugp/content->path (:content shape))}
|
||||||
|
|
||||||
{:x x
|
{:x x
|
||||||
:y y
|
:y y
|
||||||
|
|
|
@ -43,11 +43,15 @@
|
||||||
|
|
||||||
old-shapes (deref (refs/objects-by-id ids))
|
old-shapes (deref (refs/objects-by-id ids))
|
||||||
frames (map #(deref (refs/object-by-id (:frame-id %))) old-shapes)
|
frames (map #(deref (refs/object-by-id (:frame-id %))) old-shapes)
|
||||||
shapes (map gsh/transform-shape frames old-shapes)
|
|
||||||
|
|
||||||
values (cond-> values
|
shapes (as-> old-shapes $
|
||||||
(not= (:x values) :multiple) (assoc :x (:x (:selrect (first shapes))))
|
(map gsh/transform-shape $)
|
||||||
(not= (:y values) :multiple) (assoc :y (:y (:selrect (first shapes)))))
|
(map gsh/translate-to-frame $ frames))
|
||||||
|
|
||||||
|
values (let [{:keys [x y]} (-> shapes first :points gsh/points->selrect)]
|
||||||
|
(cond-> values
|
||||||
|
(not= (:x values) :multiple) (assoc :x x)
|
||||||
|
(not= (:y values) :multiple) (assoc :y y)))
|
||||||
|
|
||||||
proportion-lock (:proportion-lock values)
|
proportion-lock (:proportion-lock values)
|
||||||
|
|
||||||
|
@ -65,7 +69,7 @@
|
||||||
|
|
||||||
do-position-change
|
do-position-change
|
||||||
(fn [shape' frame' value attr]
|
(fn [shape' frame' value attr]
|
||||||
(let [from (-> shape' :selrect attr)
|
(let [from (-> shape' :points gsh/points->selrect attr)
|
||||||
to (+ value (attr frame'))
|
to (+ value (attr frame'))
|
||||||
target (+ (attr shape') (- to from))]
|
target (+ (attr shape') (- to from))]
|
||||||
(st/emit! (udw/update-position (:id shape') {attr target}))))
|
(st/emit! (udw/update-position (:id shape') {attr target}))))
|
||||||
|
|
|
@ -213,18 +213,3 @@
|
||||||
opposite (gpt/add point (gpt/negate phv))]
|
opposite (gpt/add point (gpt/negate phv))]
|
||||||
opposite))
|
opposite))
|
||||||
|
|
||||||
(defn segments->content [segments]
|
|
||||||
(let [initial (first segments)
|
|
||||||
closed? (= (first segments) (last segments))
|
|
||||||
lines (if closed?
|
|
||||||
(take (- (count segments) 2) (rest segments))
|
|
||||||
(rest segments))]
|
|
||||||
|
|
||||||
(d/concat [{:command :move-to
|
|
||||||
:params (select-keys initial [:x :y])}]
|
|
||||||
(->> lines
|
|
||||||
(mapv #(hash-map :command :line-to
|
|
||||||
:params (select-keys % [:x :y]))))
|
|
||||||
|
|
||||||
(when closed?
|
|
||||||
[{:command :close-path}]))))
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue