From f339f1ee984fc133c1eae2b17c246ca8232f25a5 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 20 Nov 2020 09:38:33 +0100 Subject: [PATCH] :sparkles: Migrates model to the new paths --- .gitignore | 1 + common/app/common/geom/shapes.cljc | 11 ++-- common/app/common/geom/shapes/path.cljc | 17 +++++ common/app/common/geom/shapes/rect.cljc | 16 ++--- common/app/common/pages.cljc | 2 +- common/app/common/pages_migrations.cljc | 62 ++++++++++++++++++- .../styles/main/partials/dashboard-grid.scss | 6 ++ frontend/src/app/main/data/workspace.cljs | 16 ----- .../main/data/workspace/drawing/curve.cljs | 3 +- frontend/src/app/main/ui/shapes/path.cljs | 27 +------- .../app/main/ui/workspace/shapes/outline.cljs | 6 +- .../workspace/sidebar/options/measures.cljs | 14 +++-- frontend/src/app/util/geom/path.cljs | 15 ----- 13 files changed, 114 insertions(+), 82 deletions(-) diff --git a/.gitignore b/.gitignore index a7cb67059..0e01a6685 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ node_modules /media /deploy /web +/_dump diff --git a/common/app/common/geom/shapes.cljc b/common/app/common/geom/shapes.cljc index 325f9e634..56fe8ccb6 100644 --- a/common/app/common/geom/shapes.cljc +++ b/common/app/common/geom/shapes.cljc @@ -233,12 +233,11 @@ (defn setup-selrect [{:keys [x y width height] :as shape}] - (-> shape - (assoc :selrect - {:x x :y y - :width width :height height - :x1 x :y1 y - :x2 (+ x width) :y2 (+ y height)}))) + (let [selrect (gpr/rect->selrect shape) + points (gpr/rect->points shape)] + (-> shape + (assoc :selrect selrect + :points points)))) ;; EXPORTS diff --git a/common/app/common/geom/shapes/path.cljc b/common/app/common/geom/shapes/path.cljc index 1c9f26466..538b9b13d 100644 --- a/common/app/common/geom/shapes/path.cljc +++ b/common/app/common/geom/shapes/path.cljc @@ -161,3 +161,20 @@ (:c2y params) (update-in [index :params :c2y] + (:c2y params))) content))] (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}]))))) diff --git a/common/app/common/geom/shapes/rect.cljc b/common/app/common/geom/shapes/rect.cljc index 9cd097996..bca71f3ad 100644 --- a/common/app/common/geom/shapes/rect.cljc +++ b/common/app/common/geom/shapes/rect.cljc @@ -24,10 +24,10 @@ (gpt/point x (+ y height))]) (defn points->rect [points] - (let [minx (transduce (map :x) min ##Inf points) - miny (transduce (map :y) min ##Inf points) - maxx (transduce (map :x) max ##-Inf points) - maxy (transduce (map :y) max ##-Inf points)] + (let [minx (transduce (comp (map :x) (remove nil?)) min ##Inf points) + miny (transduce (comp (map :y) (remove nil?)) min ##Inf points) + maxx (transduce (comp (map :x) (remove nil?)) max ##-Inf points) + maxy (transduce (comp (map :y) (remove nil?)) max ##-Inf points)] {:x minx :y miny :width (- maxx minx) @@ -45,10 +45,10 @@ (-> rect rect->points points->selrect)) (defn join-selrects [selrects] - (let [minx (transduce (map :x1) min ##Inf selrects) - miny (transduce (map :y1) min ##Inf selrects) - maxx (transduce (map :x2) max ##-Inf selrects) - maxy (transduce (map :y2) max ##-Inf selrects)] + (let [minx (transduce (comp (map :x1) (remove nil?)) min ##Inf selrects) + miny (transduce (comp (map :y1) (remove nil?)) min ##Inf selrects) + maxx (transduce (comp (map :x2) (remove nil?)) max ##-Inf selrects) + maxy (transduce (comp (map :y2) (remove nil?)) max ##-Inf selrects)] {:x minx :y miny :x1 minx diff --git a/common/app/common/pages.cljc b/common/app/common/pages.cljc index 2212d77df..52accc13e 100644 --- a/common/app/common/pages.cljc +++ b/common/app/common/pages.cljc @@ -20,7 +20,7 @@ [app.common.spec :as us] [app.common.uuid :as uuid])) -(def file-version 2) +(def file-version 3) (def max-safe-int 9007199254740991) (def min-safe-int -9007199254740991) diff --git a/common/app/common/pages_migrations.cljc b/common/app/common/pages_migrations.cljc index 7d9b89bc0..75697f5e3 100644 --- a/common/app/common/pages_migrations.cljc +++ b/common/app/common/pages_migrations.cljc @@ -2,6 +2,7 @@ (:require [app.common.pages :as cp] [app.common.geom.shapes :as gsh] + [app.common.geom.shapes.path :as gsp] [app.common.geom.point :as gpt] [app.common.geom.matrix :as gmt] [app.common.spec :as us] @@ -35,7 +36,6 @@ ;; -- MIGRATIONS -- ;; Ensure that all :shape attributes on shapes are vectors. - (defmethod migrate 2 [data] (letfn [(update-object [id object] @@ -49,3 +49,63 @@ (update page :objects #(d/mapm update-object %)))] (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 %)))) diff --git a/frontend/resources/styles/main/partials/dashboard-grid.scss b/frontend/resources/styles/main/partials/dashboard-grid.scss index 7f0364275..79b5da8ad 100644 --- a/frontend/resources/styles/main/partials/dashboard-grid.scss +++ b/frontend/resources/styles/main/partials/dashboard-grid.scss @@ -206,6 +206,12 @@ &.menu { margin-right: 0; + width: 2rem; + height: 2rem; + display: flex; + justify-content: flex-end; + align-items: flex-end; + flex-direction: column; svg { fill: $color-gray-60; diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index a8fc65d4d..c760d812c 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -1046,22 +1046,6 @@ (rx/of (dwt/set-modifiers [id] {:displacement displ}) (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) (defn toggle-collapse diff --git a/frontend/src/app/main/data/workspace/drawing/curve.cljs b/frontend/src/app/main/data/workspace/drawing/curve.cljs index 387525fa4..e06e7240d 100644 --- a/frontend/src/app/main/data/workspace/drawing/curve.cljs +++ b/frontend/src/app/main/data/workspace/drawing/curve.cljs @@ -13,6 +13,7 @@ [potok.core :as ptk] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] + [app.common.geom.shapes.path :as gsp] [app.main.streams :as ms] [app.util.geom.path :as path] [app.main.data.workspace.drawing.common :as common])) @@ -29,7 +30,7 @@ (update-in state [:workspace-drawing :object :segments] (fnil conj []) point)) (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) points (gsh/rect->points selrect)] (-> shape diff --git a/frontend/src/app/main/ui/shapes/path.cljs b/frontend/src/app/main/ui/shapes/path.cljs index ff1a0bce3..85a0e0cd2 100644 --- a/frontend/src/app/main/ui/shapes/path.cljs +++ b/frontend/src/app/main/ui/shapes/path.cljs @@ -20,28 +20,6 @@ ;; --- 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/wrap-props false} [props] @@ -51,10 +29,7 @@ {:keys [id x y width height]} (:selrect shape) mask-id (mf/use-ctx mask-id-ctx) transform (geom/transform-matrix shape) - pdata (if (:content shape) - (ugp/content->path (:content shape)) - (render-path shape)) - + pdata (ugp/content->path (:content shape)) props (-> (attrs/extract-style-attrs shape) (obj/merge! #js {:transform transform diff --git a/frontend/src/app/main/ui/workspace/shapes/outline.cljs b/frontend/src/app/main/ui/workspace/shapes/outline.cljs index f41f371ec..309bdc5ff 100644 --- a/frontend/src/app/main/ui/workspace/shapes/outline.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/outline.cljs @@ -13,8 +13,8 @@ [app.common.geom.shapes :as gsh] [app.util.object :as 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 @@ -45,7 +45,7 @@ :ry (/ height 2)} :path - {:d (path/render-path shape)} + {:d (ugp/content->path (:content shape))} {:x x :y y diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/measures.cljs index f76fa2ee0..6d67412d8 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/measures.cljs @@ -43,11 +43,15 @@ old-shapes (deref (refs/objects-by-id ids)) frames (map #(deref (refs/object-by-id (:frame-id %))) old-shapes) - shapes (map gsh/transform-shape frames old-shapes) - values (cond-> values - (not= (:x values) :multiple) (assoc :x (:x (:selrect (first shapes)))) - (not= (:y values) :multiple) (assoc :y (:y (:selrect (first shapes))))) + shapes (as-> old-shapes $ + (map gsh/transform-shape $) + (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) @@ -65,7 +69,7 @@ do-position-change (fn [shape' frame' value attr] - (let [from (-> shape' :selrect attr) + (let [from (-> shape' :points gsh/points->selrect attr) to (+ value (attr frame')) target (+ (attr shape') (- to from))] (st/emit! (udw/update-position (:id shape') {attr target})))) diff --git a/frontend/src/app/util/geom/path.cljs b/frontend/src/app/util/geom/path.cljs index eb64b84b3..e8d40fff9 100644 --- a/frontend/src/app/util/geom/path.cljs +++ b/frontend/src/app/util/geom/path.cljs @@ -213,18 +213,3 @@ opposite (gpt/add point (gpt/negate phv))] 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}]))))