🐛 Fix problems with empty paths and shortcuts

This commit is contained in:
alonso.torres 2021-05-07 13:05:45 +02:00 committed by Andrey Antukh
parent 5e0101e424
commit 3bb3fcfbda
3 changed files with 64 additions and 62 deletions

View file

@ -14,6 +14,7 @@
- Fix problem with `close-path` command [#917](https://github.com/penpot/penpot/issues/917) - Fix problem with `close-path` command [#917](https://github.com/penpot/penpot/issues/917)
- Fix wrong query for obtain the profile default project-id - Fix wrong query for obtain the profile default project-id
- Fix problems with empty paths and shortcuts [#923](https://github.com/penpot/penpot/issues/923)
## 1.5.1-alpha ## 1.5.1-alpha

View file

@ -30,14 +30,16 @@
id (st/get-path-id state) id (st/get-path-id state)
page-id (:current-page-id state) page-id (:current-page-id state)
shape (get-in state (st/get-path state)) shape (get-in state (st/get-path state))
selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{}) selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{})
points (or points selected-points) points (or points selected-points)]
new-content (-> (tool-fn (:content shape) points) (when-not (empty? points)
(ups/close-subpaths)) (let [new-content (-> (tool-fn (:content shape) points)
[rch uch] (changes/generate-path-changes objects page-id shape (:content shape) new-content)] (ups/close-subpaths))
(rx/of (dch/commit-changes rch uch {:commit-local? true}) [rch uch] (changes/generate-path-changes objects page-id shape (:content shape) new-content)]
(when (empty? new-content) (rx/of (dch/commit-changes rch uch {:commit-local? true})
dwc/clear-edition-mode))))))) (when (empty? new-content)
dwc/clear-edition-mode)))))))))
(defn make-corner (defn make-corner
([] ([]

View file

@ -8,14 +8,10 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes.path :as gshp]
[app.util.svg :as usvg]
[cuerdas.core :as str]
[clojure.set :as set]
[app.common.math :as mth] [app.common.math :as mth]
[app.util.path.commands :as upc] [app.util.path.commands :as upc]
[app.util.path.geom :as upg] [app.util.path.geom :as upg]
)) [clojure.set :as set]))
(defn remove-line-curves (defn remove-line-curves
"Remove all curves that have both handlers in the same position that the "Remove all curves that have both handlers in the same position that the
@ -235,70 +231,73 @@
to keep everything consistent" to keep everything consistent"
[content points] [content points]
(let [content (d/with-prev content)] (if (empty? points)
content
(loop [result [] (let [content (d/with-prev content)]
last-handler nil
[cur-cmd prev-cmd] (first content)
content (rest content)]
(if (nil? cur-cmd) (loop [result []
;; The result with be an array of arrays were every entry is a subpath last-handler nil
(->> result [cur-cmd prev-cmd] (first content)
;; remove empty and only 1 node subpaths content (rest content)]
(filter #(> (count %) 1))
;; flatten array-of-arrays plain array
(flatten)
(into []))
(let [move? (= :move-to (:command cur-cmd)) (if (nil? cur-cmd)
curve? (= :curve-to (:command cur-cmd)) ;; The result with be an array of arrays were every entry is a subpath
(->> result
;; remove empty and only 1 node subpaths
(filter #(> (count %) 1))
;; flatten array-of-arrays plain array
(flatten)
(into []))
;; When the old command was a move we start a subpath (let [move? (= :move-to (:command cur-cmd))
result (if move? (conj result []) result) curve? (= :curve-to (:command cur-cmd))
subpath (peek result) ;; When the old command was a move we start a subpath
result (if move? (conj result []) result)
point (upc/command->point cur-cmd) subpath (peek result)
old-prev-point (upc/command->point prev-cmd) point (upc/command->point cur-cmd)
new-prev-point (upc/command->point (peek subpath))
remove? (contains? points point) old-prev-point (upc/command->point prev-cmd)
new-prev-point (upc/command->point (peek subpath))
remove? (contains? points point)
;; We store the first handler for the first curve to be removed to ;; We store the first handler for the first curve to be removed to
;; use it for the first handler of the regenerated path ;; use it for the first handler of the regenerated path
cur-handler (cond cur-handler (cond
(and (not last-handler) remove? curve?) (and (not last-handler) remove? curve?)
(select-keys (:params cur-cmd) [:c1x :c1y]) (select-keys (:params cur-cmd) [:c1x :c1y])
(not remove?) (not remove?)
nil nil
:else :else
last-handler) last-handler)
cur-cmd (cond-> cur-cmd cur-cmd (cond-> cur-cmd
;; If we're starting a subpath and it's not a move make it a move ;; If we're starting a subpath and it's not a move make it a move
(and (not move?) (empty? subpath)) (and (not move?) (empty? subpath))
(assoc :command :move-to (assoc :command :move-to
:params (select-keys (:params cur-cmd) [:x :y])) :params (select-keys (:params cur-cmd) [:x :y]))
;; If have a curve the first handler will be relative to the previous ;; If have a curve the first handler will be relative to the previous
;; point. We change the handler to the new previous point ;; point. We change the handler to the new previous point
(and curve? (not (empty? subpath)) (not= old-prev-point new-prev-point)) (and curve? (not (empty? subpath)) (not= old-prev-point new-prev-point))
(update :params merge last-handler)) (update :params merge last-handler))
head-idx (dec (count result)) head-idx (dec (count result))
result (cond-> result result (cond-> result
(not remove?) (not remove?)
(update head-idx conj cur-cmd))] (update head-idx conj cur-cmd))]
(recur result (recur result
cur-handler cur-handler
(first content) (first content)
(rest content))))))) (rest content))))))))
(defn join-nodes (defn join-nodes
"Creates new segments between points that weren't previously" "Creates new segments between points that weren't previously"