0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-13 15:31:26 -05:00

Adds path new-point edition

This commit is contained in:
alonso.torres 2021-04-14 17:23:16 +02:00
parent f7712f2b40
commit e2cf3a5a98
6 changed files with 74 additions and 44 deletions

View file

@ -233,7 +233,9 @@
(loop [t1 0
t2 1]
(if (<= (mth/abs (- t1 t2)) path-closest-point-accuracy)
(curve-values start end h1 h2 t1)
(-> (curve-values start end h1 h2 t1)
;; store the segment info
(with-meta {:t t1 :from-p start :to-p end}))
(let [ht (+ t1 (/ (- t2 t1) 2))
ht1 (+ t1 (/ (- t2 t1) 4))
@ -260,21 +262,18 @@
"Point on line"
[position from-p to-p]
(let [{v1x :x v1y :y} from-p
{v2x :x v2y :y} to-p
{px :x py :y} position
e1 (gpt/point (- v2x v1x) (- v2y v1y))
e2 (gpt/point (- px v1x) (- py v1y))
(let [e1 (gpt/to-vec from-p to-p )
e2 (gpt/to-vec from-p position)
len2 (+ (mth/sq (:x e1)) (mth/sq (:y e1)))
val-dp (/ (gpt/dot e1 e2) len2)]
t (/ (gpt/dot e1 e2) len2)]
(if (and (>= t 0) (<= t 1) (not (mth/almost-zero? len2)))
(-> (gpt/add from-p (gpt/scale e1 t))
(with-meta {:t t
:from-p from-p
:to-p to-p}))
(if (and (>= val-dp 0)
(<= val-dp 1)
(not (mth/almost-zero? len2)))
(gpt/point (+ v1x (* val-dp (:x e1)))
(+ v1y (* val-dp (:y e1))))
;; There is no perpendicular projection in the line so the closest
;; point will be one of the extremes
(if (<= (gpt/distance position from-p) (gpt/distance position to-p))
@ -286,20 +285,20 @@
[shape position]
(let [point+distance (fn [[cur-cmd prev-cmd]]
(let [point
(let [from-p (command->point prev-cmd)
to-p (command->point cur-cmd)
h1 (gpt/point (get-in cur-cmd [:params :c1x])
(get-in cur-cmd [:params :c1y]))
h2 (gpt/point (get-in cur-cmd [:params :c2x])
(get-in cur-cmd [:params :c2y]))
point
(case (:command cur-cmd)
:line-to (line-closest-point
position
(command->point prev-cmd)
(command->point cur-cmd))
:curve-to (curve-closest-point
position
(command->point prev-cmd)
(command->point cur-cmd)
(gpt/point (get-in cur-cmd [:params :c1x])
(get-in cur-cmd [:params :c1y]))
(gpt/point (get-in cur-cmd [:params :c2x])
(get-in cur-cmd [:params :c2y])))
:line-to
(line-closest-point position from-p to-p)
:curve-to
(curve-closest-point position from-p to-p h1 h2)
nil)]
(when point
[point (gpt/distance point position)])))

View file

@ -22,6 +22,7 @@
(d/export edition/start-move-handler)
(d/export edition/start-move-path-point)
(d/export edition/start-path-edit)
(d/export edition/create-node-at-position)
;; Selection
(d/export selection/handle-selection)

View file

@ -234,3 +234,15 @@
(update [_ state]
(let [id (get-in state [:workspace-local :edition])]
(update state :workspace-local dissoc :edit-path id)))))
(defn create-node-at-position
[{:keys [from-p to-p t]}]
(ptk/reify ::create-node-at-position
ptk/UpdateEvent
(update [_ state]
(let [id (st/get-path-id state)]
(update-in state (st/get-path state :content) ugp/split-segments #{from-p to-p} t)))
ptk/WatchEvent
(watch [_ state stream]
(rx/of (changes/save-path-content)))))

View file

@ -24,7 +24,7 @@
[rumext.alpha :as mf])
(:import goog.events.EventType))
(mf/defc path-point [{:keys [position zoom edit-mode hover? selected? preview? start-path? last-p?]}]
(mf/defc path-point [{:keys [position zoom edit-mode hover? selected? preview? start-path? last-p? new-point?]}]
(let [{:keys [x y]} position
on-enter
@ -40,6 +40,9 @@
(dom/stop-propagation event)
(dom/prevent-default event)
(when (and new-point? (some? (meta position)))
(st/emit! (drp/create-node-at-position (meta position))))
(let [shift? (kbd/shift? event)]
(cond
(= edit-mode :move)
@ -190,6 +193,8 @@
last-p (->> content last ugp/command->point)
handlers (ugp/content->handlers content)
start-p? (not (some? last-point))
[snap-selected snap-points]
(cond
(some? drag-handler) [#{drag-handler} points]
@ -199,7 +204,9 @@
[(->> selected-points (map base->point) (into #{}))
(->> points (remove selected-points) (into #{}))])
show-snap? (and snap-toggled (or (some? drag-handler) (some? preview) (some? moving-handler) moving-nodes))
show-snap? (and snap-toggled
(empty? hover-points)
(or (some? drag-handler) (some? preview) (some? moving-handler) moving-nodes))
handle-double-click-outside
(fn [event]
@ -213,6 +220,13 @@
#(doseq [key keys]
(events/unlistenByKey key)))))
(hooks/use-stream
ms/mouse-position
(mf/deps shape zoom)
(fn [position]
(when-let [point (gshp/path-closest-point shape position)]
(reset! hover-point (when (< (gpt/distance position point) (/ 10 zoom)) point)))))
[:g.path-editor {:ref editor-ref}
(when (and preview (not drag-handler))
[:& path-preview {:command preview
@ -228,13 +242,15 @@
(when @hover-point
[:g.hover-point
[:& path-point {:position @hover-point
:edit-mode edit-mode
:new-point? true
:start-path? start-p?
:zoom zoom}]])
(for [position points]
(let [point-selected? (contains? selected-points (get point->base position))
point-hover? (contains? hover-points (get point->base position))
last-p? (= last-point (get point->base position))
start-p? (not (some? last-point))]
last-p? (= last-point (get point->base position))]
[:g.path-node
[:g.point-handlers {:pointer-events (when (= edit-mode :draw) "none")}

View file

@ -98,6 +98,7 @@
drawing-path? (or (and edition (= :draw (get-in edit-path [edition :edit-mode])))
(and (some? drawing-obj) (= :path (:type drawing-obj))))
text-editing? (and edition (= :text (get-in objects [edition :type])))
path-editing? (and edition (= :path (get-in objects [edition :type])))
on-click (actions/on-click hover selected edition drawing-path? drawing-tool)
on-context-menu (actions/on-context-menu hover)
@ -132,11 +133,12 @@
show-snap-distance? (and (contains? layout :dynamic-alignment) (= transform :move) (not (empty? selected)))
show-snap-points? (and (contains? layout :dynamic-alignment) (or drawing-obj transform))
show-selrect? (and selrect (empty? drawing))
show-measures? (and (not transform) (not path-editing?) show-distances?)
]
(hooks/setup-dom-events viewport-ref zoom disable-paste in-viewport?)
(hooks/setup-viewport-size viewport-ref)
(hooks/setup-cursor cursor alt? panning drawing-tool drawing-path?)
(hooks/setup-cursor cursor alt? panning drawing-tool drawing-path? path-editing?)
(hooks/setup-resize layout viewport-ref)
(hooks/setup-keyboard alt? ctrl?)
(hooks/setup-hover-shapes page-id move-stream selected objects transform selected ctrl? hover hover-ids)
@ -224,7 +226,7 @@
:disable-handlers (or drawing-tool edition)
:on-move-selected on-move-selected}])
(when (and (not transform) show-distances?)
(when show-measures?
[:& msr/measurement
{:bounds vbox
:selected-shapes selected-shapes

View file

@ -58,23 +58,23 @@
;; We schedule the event so it fires after `initialize-page` event
(timers/schedule #(st/emit! (dw/initialize-viewport size)))))))
(defn setup-cursor [cursor alt? panning drawing-tool drawing-path?]
(defn setup-cursor [cursor alt? panning drawing-tool drawing-path? path-editing?]
(mf/use-effect
(mf/deps @cursor @alt? panning drawing-tool drawing-path?)
(mf/deps @cursor @alt? panning drawing-tool drawing-path? path-editing?)
(fn []
(let [new-cursor
(cond
panning (utils/get-cursor :hand)
(= drawing-tool :comments) (utils/get-cursor :comments)
(= drawing-tool :frame) (utils/get-cursor :create-artboard)
(= drawing-tool :rect) (utils/get-cursor :create-rectangle)
(= drawing-tool :circle) (utils/get-cursor :create-ellipse)
panning (utils/get-cursor :hand)
(= drawing-tool :comments) (utils/get-cursor :comments)
(= drawing-tool :frame) (utils/get-cursor :create-artboard)
(= drawing-tool :rect) (utils/get-cursor :create-rectangle)
(= drawing-tool :circle) (utils/get-cursor :create-ellipse)
(or (= drawing-tool :path)
drawing-path?) (utils/get-cursor :pen)
(= drawing-tool :curve) (utils/get-cursor :pencil)
drawing-tool (utils/get-cursor :create-shape)
@alt? (utils/get-cursor :duplicate)
:else (utils/get-cursor :pointer-inner))]
drawing-path?) (utils/get-cursor :pen)
(= drawing-tool :curve) (utils/get-cursor :pencil)
drawing-tool (utils/get-cursor :create-shape)
(and @alt? (not path-editing?)) (utils/get-cursor :duplicate)
:else (utils/get-cursor :pointer-inner))]
(when (not= @cursor new-cursor)
(reset! cursor new-cursor))))))