mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 19:06:18 +00:00
⚡ Add efficiency improvements to workspace components (refactor part 1) (#8887)
* ♻️ Convert snap-points components to modern rumext format Migrate snap-point, snap-line, snap-feedback, and snap-points from legacy mf/defc format to modern * suffix format. This enables optimized props handling by the rumext macro, eliminating implicit JS object wrapping overhead on each render. All internal and external call sites updated to use [:> component* props] syntax. * ♻️ Convert frame-title to modern rumext format Migrate frame-title from legacy mf/defc format to modern * suffix format. The component was using legacy implicit props wrapping without ::mf/wrap-props false or ::mf/props :obj, causing unnecessary JS object conversion overhead on each render. The parent frame-titles* call site updated to use [:> frame-title* props] syntax. * ♻️ Convert interactions components to modern rumext format Migrate interaction-marker, interaction-path, interaction-handle, overlay-marker, and interactions from legacy mf/defc format to modern * suffix format. These five components had zero props optimization applied, causing implicit JS object wrapping on every render. All internal and external call sites updated to use [:> component* props] syntax. * ♻️ Convert rulers components to modern rumext format Migrate rulers-text, viewport-frame, and selection-area from legacy mf/defc format to modern * suffix format. These three components in the always-visible rulers layer had zero props optimization applied. Internal call sites in the parent rulers component updated to use [:> component* props] syntax. * ♻️ Convert frame-grid components to modern rumext format Migrate square-grid, layout-grid, grid-display-frame, and frame-grid from legacy mf/defc format to modern * suffix format. These four components render grid patterns per-frame with zero props optimization. All internal and external call sites updated to use [:> component* props] syntax. * ♻️ Convert gradient handler components to modern rumext format Migrate shadow, gradient-color-handler, and gradient-handler-transformed from legacy mf/defc format to modern * suffix format. These components are rendered during gradient editing with zero props optimization applied. Internal call sites in gradient-handler-transformed and gradient-handlers-impl updated to use [:> component* props] syntax. * ♻️ Rename ?-ending props in modernized workspace viewport components Apply prop naming rules to all * components migrated in the previous batch: - remove-snap? -> remove-snap in snap-feedback* (and get-snap helper) - selected? -> is-selected in interaction-path* - hover-disabled? -> is-hover-disabled in overlay-marker* and interactions* - show-rulers? -> show-rulers in viewport-frame* Update all internal and external call sites consistently. * 🐛 Fix get-snap call in snap-feedback* using JS props object Modern rumext *-suffix components receive props as JS objects, not Clojure maps. snap-feedback* was pushing the raw props object into the rx/subject and get-snap was destructuring it as a Clojure map, causing all keys to resolve to nil. Fix by: - Changing get-snap to take positional arguments (coord, shapes, page-id, remove-snap, zoom) instead of a map-destructured opts arg - Building an explicit Clojure map from the bound locals before pushing to the subject - Destructuring that map inside the rx/switch-map callback and calling get-snap with positional args Also mark get-snap and add-point-to-snaps as private (defn-), consistent with the other helpers in the namespace — none are referenced externally.
This commit is contained in:
parent
3264bc746f
commit
f07b954b7e
@ -577,7 +577,7 @@
|
|||||||
:tool drawing-tool}])
|
:tool drawing-tool}])
|
||||||
|
|
||||||
(when show-grids?
|
(when show-grids?
|
||||||
[:& frame-grid/frame-grid
|
[:> frame-grid/frame-grid*
|
||||||
{:zoom zoom
|
{:zoom zoom
|
||||||
:selected selected
|
:selected selected
|
||||||
:transform transform
|
:transform transform
|
||||||
@ -588,7 +588,7 @@
|
|||||||
:zoom zoom}])
|
:zoom zoom}])
|
||||||
|
|
||||||
(when show-snap-points?
|
(when show-snap-points?
|
||||||
[:& snap-points/snap-points
|
[:> snap-points/snap-points*
|
||||||
{:layout layout
|
{:layout layout
|
||||||
:transform transform
|
:transform transform
|
||||||
:drawing drawing-obj
|
:drawing drawing-obj
|
||||||
@ -689,13 +689,13 @@
|
|||||||
:disabled (or drawing-tool @space?)}])))
|
:disabled (or drawing-tool @space?)}])))
|
||||||
|
|
||||||
(when show-prototypes?
|
(when show-prototypes?
|
||||||
[:& interactions/interactions
|
[:> interactions/interactions*
|
||||||
{:selected selected
|
{:selected selected
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:objects objects-modified
|
:objects objects-modified
|
||||||
:current-transform transform
|
:current-transform transform
|
||||||
:hover-disabled? hover-disabled?}])])
|
:is-hover-disabled hover-disabled?}])])
|
||||||
|
|
||||||
(when show-gradient-handlers?
|
(when show-gradient-handlers?
|
||||||
[:> gradients/gradient-handlers*
|
[:> gradients/gradient-handlers*
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(mf/defc square-grid [{:keys [frame zoom grid] :as props}]
|
(mf/defc square-grid* [{:keys [frame zoom grid]}]
|
||||||
(let [grid-id (mf/use-memo #(uuid/next))
|
(let [grid-id (mf/use-memo #(uuid/next))
|
||||||
{:keys [size] :as params} (-> grid :params)
|
{:keys [size] :as params} (-> grid :params)
|
||||||
{color-value :color color-opacity :opacity} (-> grid :params :color)
|
{color-value :color color-opacity :opacity} (-> grid :params :color)
|
||||||
@ -45,7 +45,7 @@
|
|||||||
:height (:height frame)
|
:height (:height frame)
|
||||||
:fill (str "url(#" grid-id ")")}]]))
|
:fill (str "url(#" grid-id ")")}]]))
|
||||||
|
|
||||||
(mf/defc layout-grid
|
(mf/defc layout-grid*
|
||||||
[{:keys [key frame grid zoom]}]
|
[{:keys [key frame grid zoom]}]
|
||||||
(let [{color-value :color color-opacity :opacity} (-> grid :params :color)
|
(let [{color-value :color color-opacity :opacity} (-> grid :params :color)
|
||||||
;; Support for old color format
|
;; Support for old color format
|
||||||
@ -124,7 +124,7 @@
|
|||||||
selrect
|
selrect
|
||||||
parents))
|
parents))
|
||||||
|
|
||||||
(mf/defc grid-display-frame
|
(mf/defc grid-display-frame*
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [frame zoom transforming]}]
|
[{:keys [frame zoom transforming]}]
|
||||||
(let [frame-id (:id frame)
|
(let [frame-id (:id frame)
|
||||||
@ -154,16 +154,16 @@
|
|||||||
:zoom zoom
|
:zoom zoom
|
||||||
:grid grid}]
|
:grid grid}]
|
||||||
(case (:type grid)
|
(case (:type grid)
|
||||||
:square [:> square-grid props]
|
:square [:> square-grid* props]
|
||||||
:column [:> layout-grid props]
|
:column [:> layout-grid* props]
|
||||||
:row [:> layout-grid props])))])))
|
:row [:> layout-grid* props])))])))
|
||||||
|
|
||||||
(defn has-grid?
|
(defn has-grid?
|
||||||
[{:keys [grids]}]
|
[{:keys [grids]}]
|
||||||
(and (some? grids)
|
(and (some? grids)
|
||||||
(d/not-empty? (->> grids (filter :display)))))
|
(d/not-empty? (->> grids (filter :display)))))
|
||||||
|
|
||||||
(mf/defc frame-grid
|
(mf/defc frame-grid*
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [zoom transform selected focus]}]
|
[{:keys [zoom transform selected focus]}]
|
||||||
(let [frames (->> (mf/deref refs/workspace-frames)
|
(let [frames (->> (mf/deref refs/workspace-frames)
|
||||||
@ -175,7 +175,7 @@
|
|||||||
(when (and #_(not (is-transform? frame))
|
(when (and #_(not (is-transform? frame))
|
||||||
(not (ctst/rotated-frame? frame))
|
(not (ctst/rotated-frame? frame))
|
||||||
(or (empty? focus) (contains? focus (:id frame))))
|
(or (empty? focus) (contains? focus (:id frame))))
|
||||||
[:& grid-display-frame {:key (str "grid-" (:id frame))
|
[:> grid-display-frame* {:key (str "grid-" (:id frame))
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:frame frame
|
:frame frame
|
||||||
:transforming transforming}]))]))
|
:transforming transforming}]))]))
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
(def gradient-endpoint-radius-selected 6)
|
(def gradient-endpoint-radius-selected 6)
|
||||||
(def gradient-endpoint-radius-handler 20)
|
(def gradient-endpoint-radius-handler 20)
|
||||||
|
|
||||||
(mf/defc shadow [{:keys [id offset]}]
|
(mf/defc shadow* [{:keys [id offset]}]
|
||||||
[:filter {:id id
|
[:filter {:id id
|
||||||
:x "-10%"
|
:x "-10%"
|
||||||
:y "-10%"
|
:y "-10%"
|
||||||
@ -61,7 +61,7 @@
|
|||||||
|
|
||||||
(def checkerboard "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAIAAAC0tAIdAAACvUlEQVQoFQGyAk39AeLi4gAAAAAAAB0dHQAAAAAAAOPj4wAAAAAAAB0dHQAAAAAAAOPj4wAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB////AAAAAAAA4+PjAAAAAAAAHR0dAAAAAAAA4+PjAAAAAAAAHR0dAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATj4+MAAAAAAAAdHR0AAAAAAADj4+MAAAAAAAAdHR0AAAAAAADj4+MAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjScaa0cU7nIAAAAASUVORK5CYII=")
|
(def checkerboard "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAIAAAC0tAIdAAACvUlEQVQoFQGyAk39AeLi4gAAAAAAAB0dHQAAAAAAAOPj4wAAAAAAAB0dHQAAAAAAAOPj4wAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB////AAAAAAAA4+PjAAAAAAAAHR0dAAAAAAAA4+PjAAAAAAAAHR0dAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATj4+MAAAAAAAAdHR0AAAAAAADj4+MAAAAAAAAdHR0AAAAAAADj4+MAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjScaa0cU7nIAAAAASUVORK5CYII=")
|
||||||
|
|
||||||
(mf/defc gradient-color-handler
|
(mf/defc gradient-color-handler*
|
||||||
[{:keys [zoom point color angle selected index
|
[{:keys [zoom point color angle selected index
|
||||||
on-click on-pointer-down on-pointer-up on-pointer-move on-lost-pointer-capture]}]
|
on-click on-pointer-down on-pointer-up on-pointer-move on-lost-pointer-capture]}]
|
||||||
[:g {:filter "url(#gradient-drop-shadow)"
|
[:g {:filter "url(#gradient-drop-shadow)"
|
||||||
@ -118,7 +118,7 @@
|
|||||||
:r (/ 2 zoom)
|
:r (/ 2 zoom)
|
||||||
:fill "var(--app-white)"}]])
|
:fill "var(--app-white)"}]])
|
||||||
|
|
||||||
(mf/defc gradient-handler-transformed
|
(mf/defc gradient-handler-transformed*
|
||||||
[{:keys [from-p
|
[{:keys [from-p
|
||||||
to-p
|
to-p
|
||||||
width-p
|
width-p
|
||||||
@ -270,7 +270,7 @@
|
|||||||
|
|
||||||
[:g.gradient-handlers {:pointer-events "none"}
|
[:g.gradient-handlers {:pointer-events "none"}
|
||||||
[:defs
|
[:defs
|
||||||
[:& shadow {:id "gradient-drop-shadow" :offset (/ 2 zoom)}]]
|
[:> shadow* {:id "gradient-drop-shadow" :offset (/ 2 zoom)}]]
|
||||||
|
|
||||||
(let [lv (-> (gpt/to-vec from-p to-p)
|
(let [lv (-> (gpt/to-vec from-p to-p)
|
||||||
(gpt/unit))
|
(gpt/unit))
|
||||||
@ -425,7 +425,7 @@
|
|||||||
(-> (gpt/to-vec from-p to-p)
|
(-> (gpt/to-vec from-p to-p)
|
||||||
(gpt/scale (:offset stop))))]
|
(gpt/scale (:offset stop))))]
|
||||||
|
|
||||||
[:& gradient-color-handler
|
[:> gradient-color-handler*
|
||||||
{:key index
|
{:key index
|
||||||
:selected (= editing index)
|
:selected (= editing index)
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
@ -505,7 +505,7 @@
|
|||||||
(when (and norm-dist (d/num? norm-dist))
|
(when (and norm-dist (d/num? norm-dist))
|
||||||
(change! {:width norm-dist})))))]
|
(change! {:width norm-dist})))))]
|
||||||
|
|
||||||
[:& gradient-handler-transformed
|
[:> gradient-handler-transformed*
|
||||||
{:editing editing
|
{:editing editing
|
||||||
:from-p from-p
|
:from-p from-p
|
||||||
:to-p to-p
|
:to-p to-p
|
||||||
|
|||||||
@ -96,8 +96,8 @@
|
|||||||
[orig-pos orig-x orig-y dest-pos dest-x dest-y]))
|
[orig-pos orig-x orig-y dest-pos dest-x dest-y]))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc interaction-marker
|
(mf/defc interaction-marker*
|
||||||
[{:keys [x y stroke action-type arrow-dir zoom] :as props}]
|
[{:keys [x y stroke action-type arrow-dir zoom]}]
|
||||||
(let [icon-pdata (case action-type
|
(let [icon-pdata (case action-type
|
||||||
:navigate (case arrow-dir
|
:navigate (case arrow-dir
|
||||||
:right "M -6.5 0 L 5.5 0 M 6.715 0.715 L -0.5 -6.5 M 6.715 -0.715 L -0.365 6.635"
|
:right "M -6.5 0 L 5.5 0 M 6.715 0.715 L -0.5 -6.5 M 6.715 -0.715 L -0.365 6.635"
|
||||||
@ -138,8 +138,8 @@
|
|||||||
"translate(" (* zoom x) ", " (* zoom y) ")")}])]))
|
"translate(" (* zoom x) ", " (* zoom y) ")")}])]))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc interaction-path
|
(mf/defc interaction-path*
|
||||||
[{:keys [index level orig-shape dest-shape dest-point selected? action-type zoom] :as props}]
|
[{:keys [index level orig-shape dest-shape dest-point is-selected action-type zoom]}]
|
||||||
(let [[orig-pos orig-x orig-y dest-pos dest-x dest-y]
|
(let [[orig-pos orig-x orig-y dest-pos dest-x dest-y]
|
||||||
(cond
|
(cond
|
||||||
dest-shape
|
dest-shape
|
||||||
@ -162,7 +162,7 @@
|
|||||||
|
|
||||||
arrow-dir (if (= dest-pos :left) :right :left)]
|
arrow-dir (if (= dest-pos :left) :right :left)]
|
||||||
|
|
||||||
(if-not selected?
|
(if-not is-selected
|
||||||
[:g {:on-pointer-down #(on-pointer-down % index orig-shape)}
|
[:g {:on-pointer-down #(on-pointer-down % index orig-shape)}
|
||||||
[:path {:stroke "var(--df-secondary)"
|
[:path {:stroke "var(--df-secondary)"
|
||||||
:fill "none"
|
:fill "none"
|
||||||
@ -170,13 +170,13 @@
|
|||||||
:stroke-width (/ 2 zoom)
|
:stroke-width (/ 2 zoom)
|
||||||
:d pdata}]
|
:d pdata}]
|
||||||
(when (not dest-shape)
|
(when (not dest-shape)
|
||||||
[:& interaction-marker {:index index
|
[:> interaction-marker* {:index index
|
||||||
:x dest-x
|
:x dest-x
|
||||||
:y dest-y
|
:y dest-y
|
||||||
:stroke "var(--df-secondary)"
|
:stroke "var(--df-secondary)"
|
||||||
:action-type action-type
|
:action-type action-type
|
||||||
:arrow-dir arrow-dir
|
:arrow-dir arrow-dir
|
||||||
:zoom zoom}])]
|
:zoom zoom}])]
|
||||||
|
|
||||||
[:g {:on-pointer-down #(on-pointer-down % index orig-shape)}
|
[:g {:on-pointer-down #(on-pointer-down % index orig-shape)}
|
||||||
[:path {:stroke "var(--color-accent-tertiary)"
|
[:path {:stroke "var(--color-accent-tertiary)"
|
||||||
@ -190,36 +190,36 @@
|
|||||||
:shape dest-shape
|
:shape dest-shape
|
||||||
:color "var(--color-accent-tertiary)"}])
|
:color "var(--color-accent-tertiary)"}])
|
||||||
|
|
||||||
[:& interaction-marker {:index index
|
[:> interaction-marker* {:index index
|
||||||
:x orig-x
|
:x orig-x
|
||||||
:y orig-y
|
:y orig-y
|
||||||
:stroke "var(--color-accent-tertiary)"
|
:stroke "var(--color-accent-tertiary)"
|
||||||
:zoom zoom}]
|
:zoom zoom}]
|
||||||
[:& interaction-marker {:index index
|
[:> interaction-marker* {:index index
|
||||||
:x dest-x
|
:x dest-x
|
||||||
:y dest-y
|
:y dest-y
|
||||||
:stroke "var(--color-accent-tertiary)"
|
:stroke "var(--color-accent-tertiary)"
|
||||||
:action-type action-type
|
:action-type action-type
|
||||||
:arrow-dir arrow-dir
|
:arrow-dir arrow-dir
|
||||||
:zoom zoom}]])))
|
:zoom zoom}]])))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc interaction-handle
|
(mf/defc interaction-handle*
|
||||||
[{:keys [index shape zoom] :as props}]
|
[{:keys [index shape zoom]}]
|
||||||
(let [shape-rect (:selrect shape)
|
(let [shape-rect (:selrect shape)
|
||||||
handle-x (+ (:x shape-rect) (:width shape-rect))
|
handle-x (+ (:x shape-rect) (:width shape-rect))
|
||||||
handle-y (+ (:y shape-rect) (/ (:height shape-rect) 2))]
|
handle-y (+ (:y shape-rect) (/ (:height shape-rect) 2))]
|
||||||
[:g {:on-pointer-down #(on-pointer-down % index shape)}
|
[:g {:on-pointer-down #(on-pointer-down % index shape)}
|
||||||
[:& interaction-marker {:x handle-x
|
[:> interaction-marker* {:x handle-x
|
||||||
:y handle-y
|
:y handle-y
|
||||||
:stroke "var(--color-accent-tertiary)"
|
:stroke "var(--color-accent-tertiary)"
|
||||||
:action-type :navigate
|
:action-type :navigate
|
||||||
:arrow-dir :right
|
:arrow-dir :right
|
||||||
:zoom zoom}]]))
|
:zoom zoom}]]))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc overlay-marker
|
(mf/defc overlay-marker*
|
||||||
[{:keys [page-id index orig-shape dest-shape position objects hover-disabled?] :as props}]
|
[{:keys [page-id index orig-shape dest-shape position objects is-hover-disabled]}]
|
||||||
(let [start-move-position
|
(let [start-move-position
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(st/emit! (dw/start-move-overlay-pos index)))]
|
(st/emit! (dw/start-move-overlay-pos index)))]
|
||||||
@ -250,8 +250,8 @@
|
|||||||
(some? thumbnail-data)
|
(some? thumbnail-data)
|
||||||
(assoc :thumbnail thumbnail-data))]
|
(assoc :thumbnail thumbnail-data))]
|
||||||
[:g {:on-pointer-down start-move-position
|
[:g {:on-pointer-down start-move-position
|
||||||
:on-pointer-enter #(reset! hover-disabled? true)
|
:on-pointer-enter #(reset! is-hover-disabled true)
|
||||||
:on-pointer-leave #(reset! hover-disabled? false)}
|
:on-pointer-leave #(reset! is-hover-disabled false)}
|
||||||
[:g {:transform (gmt/translate-matrix (gpt/point (- marker-x dest-x) (- marker-y dest-y)))}
|
[:g {:transform (gmt/translate-matrix (gpt/point (- marker-x dest-x) (- marker-y dest-y)))}
|
||||||
[:& (mf/provider muc/render-thumbnails) {:value true}
|
[:& (mf/provider muc/render-thumbnails) {:value true}
|
||||||
[:& (mf/provider embed/context) {:value false}
|
[:& (mf/provider embed/context) {:value false}
|
||||||
@ -273,8 +273,8 @@
|
|||||||
:r 8
|
:r 8
|
||||||
:fill "var(--color-accent-tertiary)"}]]))))
|
:fill "var(--color-accent-tertiary)"}]]))))
|
||||||
|
|
||||||
(mf/defc interactions
|
(mf/defc interactions*
|
||||||
[{:keys [current-transform objects zoom selected hover-disabled? page-id] :as props}]
|
[{:keys [current-transform objects zoom selected is-hover-disabled page-id]}]
|
||||||
(let [active-shapes (into []
|
(let [active-shapes (into []
|
||||||
(comp (filter #(seq (:interactions %))))
|
(comp (filter #(seq (:interactions %))))
|
||||||
(vals objects))
|
(vals objects))
|
||||||
@ -305,26 +305,26 @@
|
|||||||
selected? (contains? selected (:id shape))
|
selected? (contains? selected (:id shape))
|
||||||
level (calc-level index (:interactions shape))]
|
level (calc-level index (:interactions shape))]
|
||||||
(when-not selected?
|
(when-not selected?
|
||||||
[:& interaction-path {:key (dm/str "non-selected-" (:id shape) "-" index)
|
[:> interaction-path* {:key (dm/str "non-selected-" (:id shape) "-" index)
|
||||||
:index index
|
:index index
|
||||||
:level level
|
:level level
|
||||||
:orig-shape shape
|
:orig-shape shape
|
||||||
:dest-shape dest-shape
|
:dest-shape dest-shape
|
||||||
:selected selected
|
:selected selected
|
||||||
:selected? false
|
:is-selected false
|
||||||
:action-type (:action-type interaction)
|
:action-type (:action-type interaction)
|
||||||
:zoom zoom}]))))]
|
:zoom zoom}]))))]
|
||||||
|
|
||||||
[:g.selected
|
[:g.selected
|
||||||
(when (and draw-interaction-to first-selected)
|
(when (and draw-interaction-to first-selected)
|
||||||
[:& interaction-path {:key "interactive"
|
[:> interaction-path* {:key "interactive"
|
||||||
:index nil
|
:index nil
|
||||||
:orig-shape first-selected
|
:orig-shape first-selected
|
||||||
:dest-point draw-interaction-to
|
:dest-point draw-interaction-to
|
||||||
:dest-shape draw-interaction-to-frame
|
:dest-shape draw-interaction-to-frame
|
||||||
:selected? true
|
:is-selected true
|
||||||
:action-type :navigate
|
:action-type :navigate
|
||||||
:zoom zoom}])
|
:zoom zoom}])
|
||||||
(for [shape selected-shapes]
|
(for [shape selected-shapes]
|
||||||
(if (seq (:interactions shape))
|
(if (seq (:interactions shape))
|
||||||
(for [[index interaction] (d/enumerate (:interactions shape))]
|
(for [[index interaction] (d/enumerate (:interactions shape))]
|
||||||
@ -333,38 +333,38 @@
|
|||||||
(get objects (:destination interaction)))
|
(get objects (:destination interaction)))
|
||||||
level (calc-level index (:interactions shape))]
|
level (calc-level index (:interactions shape))]
|
||||||
[:g {:key (dm/str "interaction-path-" (:id shape) "-" index)}
|
[:g {:key (dm/str "interaction-path-" (:id shape) "-" index)}
|
||||||
[:& interaction-path {:index index
|
[:> interaction-path* {:index index
|
||||||
:level level
|
:level level
|
||||||
:orig-shape shape
|
:orig-shape shape
|
||||||
:dest-shape dest-shape
|
:dest-shape dest-shape
|
||||||
:selected selected
|
:selected selected
|
||||||
:selected? true
|
:is-selected true
|
||||||
:action-type (:action-type interaction)
|
:action-type (:action-type interaction)
|
||||||
:zoom zoom}]
|
:zoom zoom}]
|
||||||
(when (and (or (= (:action-type interaction) :open-overlay)
|
(when (and (or (= (:action-type interaction) :open-overlay)
|
||||||
(= (:action-type interaction) :toggle-overlay))
|
(= (:action-type interaction) :toggle-overlay))
|
||||||
(= (:overlay-pos-type interaction) :manual))
|
(= (:overlay-pos-type interaction) :manual))
|
||||||
(if (and (some? move-overlay-to)
|
(if (and (some? move-overlay-to)
|
||||||
(= move-overlay-index index))
|
(= move-overlay-index index))
|
||||||
[:& overlay-marker {:page-id page-id
|
[:> overlay-marker* {:page-id page-id
|
||||||
:index index
|
:index index
|
||||||
:orig-shape shape
|
:orig-shape shape
|
||||||
:dest-shape dest-shape
|
:dest-shape dest-shape
|
||||||
:position move-overlay-to
|
:position move-overlay-to
|
||||||
:objects objects
|
:objects objects
|
||||||
:hover-disabled? hover-disabled?}]
|
:is-hover-disabled is-hover-disabled}]
|
||||||
[:& overlay-marker {:page-id page-id
|
[:> overlay-marker* {:page-id page-id
|
||||||
:index index
|
:index index
|
||||||
:orig-shape shape
|
:orig-shape shape
|
||||||
:dest-shape dest-shape
|
:dest-shape dest-shape
|
||||||
:position (:overlay-position interaction)
|
:position (:overlay-position interaction)
|
||||||
:objects objects
|
:objects objects
|
||||||
:hover-disabled? hover-disabled?}]))])))
|
:is-hover-disabled is-hover-disabled}]))])))
|
||||||
(when (and shape
|
(when (and shape
|
||||||
(not (cfh/unframed-shape? shape))
|
(not (cfh/unframed-shape? shape))
|
||||||
(not (#{:move :rotate} current-transform)))
|
(not (#{:move :rotate} current-transform)))
|
||||||
[:& interaction-handle {:key (:id shape)
|
[:> interaction-handle* {:key (:id shape)
|
||||||
:index nil
|
:index nil
|
||||||
:shape shape
|
:shape shape
|
||||||
:selected selected
|
:selected selected
|
||||||
:zoom zoom}])))]]))
|
:zoom zoom}])))]]))
|
||||||
|
|||||||
@ -142,7 +142,7 @@
|
|||||||
|
|
||||||
"Z"))
|
"Z"))
|
||||||
|
|
||||||
(mf/defc rulers-text
|
(mf/defc rulers-text*
|
||||||
"Draws the text for the rulers in a specific axis"
|
"Draws the text for the rulers in a specific axis"
|
||||||
[{:keys [vbox step offset axis zoom-inverse]}]
|
[{:keys [vbox step offset axis zoom-inverse]}]
|
||||||
(let [clip-id (str "clip-ruler-" (d/name axis))
|
(let [clip-id (str "clip-ruler-" (d/name axis))
|
||||||
@ -186,13 +186,13 @@
|
|||||||
:style {:stroke font-color
|
:style {:stroke font-color
|
||||||
:stroke-width rulers-width}}]]))]))
|
:stroke-width rulers-width}}]]))]))
|
||||||
|
|
||||||
(mf/defc viewport-frame
|
(mf/defc viewport-frame*
|
||||||
[{:keys [show-rulers? zoom zoom-inverse vbox offset-x offset-y]}]
|
[{:keys [show-rulers zoom zoom-inverse vbox offset-x offset-y]}]
|
||||||
|
|
||||||
(let [{:keys [width height] x1 :x y1 :y} vbox
|
(let [{:keys [width height] x1 :x y1 :y} vbox
|
||||||
x2 (+ x1 width)
|
x2 (+ x1 width)
|
||||||
y2 (+ y1 height)
|
y2 (+ y1 height)
|
||||||
bw (if show-rulers? (* ruler-area-size zoom-inverse) 0)
|
bw (if show-rulers (* ruler-area-size zoom-inverse) 0)
|
||||||
br (/ canvas-border-radius zoom)
|
br (/ canvas-border-radius zoom)
|
||||||
bs (* 4 zoom-inverse)]
|
bs (* 4 zoom-inverse)]
|
||||||
[:*
|
[:*
|
||||||
@ -214,13 +214,13 @@
|
|||||||
:fill-rule "evenodd"
|
:fill-rule "evenodd"
|
||||||
:fill rulers-background}]]
|
:fill rulers-background}]]
|
||||||
|
|
||||||
(when show-rulers?
|
(when show-rulers
|
||||||
(let [step (calculate-step-size zoom)]
|
(let [step (calculate-step-size zoom)]
|
||||||
[:g.viewport-frame-rulers
|
[:g.viewport-frame-rulers
|
||||||
[:& rulers-text {:vbox vbox :offset offset-x :step step :zoom-inverse zoom-inverse :axis :x}]
|
[:> rulers-text* {:vbox vbox :offset offset-x :step step :zoom-inverse zoom-inverse :axis :x}]
|
||||||
[:& rulers-text {:vbox vbox :offset offset-y :step step :zoom-inverse zoom-inverse :axis :y}]]))]))
|
[:> rulers-text* {:vbox vbox :offset offset-y :step step :zoom-inverse zoom-inverse :axis :y}]]))]))
|
||||||
|
|
||||||
(mf/defc selection-area
|
(mf/defc selection-area*
|
||||||
[{:keys [vbox zoom-inverse selection-rect offset-x offset-y]}]
|
[{:keys [vbox zoom-inverse selection-rect offset-x offset-y]}]
|
||||||
;; When using the format-number callls we consider if the guide is associated to a frame and we show the position relative to it with the offset
|
;; When using the format-number callls we consider if the guide is associated to a frame and we show the position relative to it with the offset
|
||||||
[:g.selection-area
|
[:g.selection-area
|
||||||
@ -332,8 +332,8 @@
|
|||||||
|
|
||||||
(when (some? vbox)
|
(when (some? vbox)
|
||||||
[:g.viewport-frame {:pointer-events "none"}
|
[:g.viewport-frame {:pointer-events "none"}
|
||||||
[:& viewport-frame
|
[:> viewport-frame*
|
||||||
{:show-rulers? show-rulers?
|
{:show-rulers show-rulers?
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:zoom-inverse zoom-inverse
|
:zoom-inverse zoom-inverse
|
||||||
:vbox vbox
|
:vbox vbox
|
||||||
@ -341,7 +341,7 @@
|
|||||||
:offset-y offset-y}]
|
:offset-y offset-y}]
|
||||||
|
|
||||||
(when (and show-rulers? (some? selection-rect))
|
(when (and show-rulers? (some? selection-rect))
|
||||||
[:& selection-area
|
[:> selection-area*
|
||||||
{:zoom zoom
|
{:zoom zoom
|
||||||
:zoom-inverse zoom-inverse
|
:zoom-inverse zoom-inverse
|
||||||
:vbox vbox
|
:vbox vbox
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
;; (def ^:private line-opacity 1 )
|
;; (def ^:private line-opacity 1 )
|
||||||
;; (def ^:private line-width 2)
|
;; (def ^:private line-width 2)
|
||||||
|
|
||||||
(mf/defc snap-point
|
(mf/defc snap-point*
|
||||||
[{:keys [point zoom]}]
|
[{:keys [point zoom]}]
|
||||||
(let [{:keys [x y]} point
|
(let [{:keys [x y]} point
|
||||||
cross-width (/ 3 zoom)]
|
cross-width (/ 3 zoom)]
|
||||||
@ -41,7 +41,7 @@
|
|||||||
:y2 (- y cross-width)
|
:y2 (- y cross-width)
|
||||||
:style {:stroke line-color :stroke-width (str (/ line-width zoom))}}]]))
|
:style {:stroke line-color :stroke-width (str (/ line-width zoom))}}]]))
|
||||||
|
|
||||||
(mf/defc snap-line
|
(mf/defc snap-line*
|
||||||
[{:keys [snap point zoom]}]
|
[{:keys [snap point zoom]}]
|
||||||
[:line {:x1 (:x snap)
|
[:line {:x1 (:x snap)
|
||||||
:y1 (:y snap)
|
:y1 (:y snap)
|
||||||
@ -50,8 +50,8 @@
|
|||||||
:style {:stroke line-color :stroke-width (str (/ line-width zoom))}
|
:style {:stroke line-color :stroke-width (str (/ line-width zoom))}
|
||||||
:opacity line-opacity}])
|
:opacity line-opacity}])
|
||||||
|
|
||||||
(defn get-snap
|
(defn- get-snap
|
||||||
[coord {:keys [shapes page-id remove-snap? zoom]}]
|
[coord shapes page-id remove-snap zoom]
|
||||||
(let [bounds (gsh/shapes->rect shapes)
|
(let [bounds (gsh/shapes->rect shapes)
|
||||||
frame-id (snap/snap-frame-id shapes)]
|
frame-id (snap/snap-frame-id shapes)]
|
||||||
|
|
||||||
@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
(rx/merge-map
|
(rx/merge-map
|
||||||
(fn [[frame-id point]]
|
(fn [[frame-id point]]
|
||||||
(->> (snap/get-snap-points page-id frame-id remove-snap? zoom point coord)
|
(->> (snap/get-snap-points page-id frame-id remove-snap zoom point coord)
|
||||||
(rx/map #(mapcat second %))
|
(rx/map #(mapcat second %))
|
||||||
(rx/map #(map :pt %))
|
(rx/map #(map :pt %))
|
||||||
(rx/map #(vector point % coord)))))
|
(rx/map #(vector point % coord)))))
|
||||||
@ -74,7 +74,7 @@
|
|||||||
[coord]
|
[coord]
|
||||||
(if (= coord :x) :y :x))
|
(if (= coord :x) :y :x))
|
||||||
|
|
||||||
(defn add-point-to-snaps
|
(defn- add-point-to-snaps
|
||||||
[[point snaps coord]]
|
[[point snaps coord]]
|
||||||
(let [normalize-coord #(assoc % coord (get point coord))]
|
(let [normalize-coord #(assoc % coord (get point coord))]
|
||||||
(cons point (map normalize-coord snaps))))
|
(cons point (map normalize-coord snaps))))
|
||||||
@ -100,8 +100,8 @@
|
|||||||
(map (fn [[fixedv [minv maxv]]] [(hash-map coord fixedv (flip coord) minv)
|
(map (fn [[fixedv [minv maxv]]] [(hash-map coord fixedv (flip coord) minv)
|
||||||
(hash-map coord fixedv (flip coord) maxv)]))))
|
(hash-map coord fixedv (flip coord) maxv)]))))
|
||||||
|
|
||||||
(mf/defc snap-feedback
|
(mf/defc snap-feedback*
|
||||||
[{:keys [shapes remove-snap? zoom modifiers] :as props}]
|
[{:keys [shapes remove-snap zoom modifiers page-id]}]
|
||||||
(let [state (mf/use-state [])
|
(let [state (mf/use-state [])
|
||||||
subject (mf/use-memo #(rx/subject))
|
subject (mf/use-memo #(rx/subject))
|
||||||
|
|
||||||
@ -116,9 +116,9 @@
|
|||||||
(fn []
|
(fn []
|
||||||
(let [sub (->> subject
|
(let [sub (->> subject
|
||||||
(rx/switch-map
|
(rx/switch-map
|
||||||
(fn [props]
|
(fn [{:keys [shapes page-id remove-snap zoom]}]
|
||||||
(->> (get-snap :y props)
|
(->> (get-snap :y shapes page-id remove-snap zoom)
|
||||||
(rx/combine-latest (get-snap :x props)))))
|
(rx/combine-latest (get-snap :x shapes page-id remove-snap zoom)))))
|
||||||
|
|
||||||
(rx/map
|
(rx/map
|
||||||
(fn [result]
|
(fn [result]
|
||||||
@ -133,28 +133,31 @@
|
|||||||
#(rx/dispose! sub))))
|
#(rx/dispose! sub))))
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps shapes remove-snap? modifiers)
|
(mf/deps shapes remove-snap modifiers)
|
||||||
(fn []
|
(fn []
|
||||||
(rx/push! subject props)))
|
(rx/push! subject {:shapes shapes
|
||||||
|
:page-id page-id
|
||||||
|
:remove-snap remove-snap
|
||||||
|
:zoom zoom})))
|
||||||
|
|
||||||
[:g.snap-feedback
|
[:g.snap-feedback
|
||||||
(for [[from-point to-point] snap-lines]
|
(for [[from-point to-point] snap-lines]
|
||||||
[:& snap-line {:key (str "line-" (:x from-point)
|
[:> snap-line* {:key (str "line-" (:x from-point)
|
||||||
"-" (:y from-point)
|
"-" (:y from-point)
|
||||||
"-" (:x to-point)
|
"-" (:x to-point)
|
||||||
"-" (:y to-point) "-")
|
"-" (:y to-point) "-")
|
||||||
:snap from-point
|
:snap from-point
|
||||||
:point to-point
|
:point to-point
|
||||||
:zoom zoom}])
|
:zoom zoom}])
|
||||||
(for [point snap-points]
|
(for [point snap-points]
|
||||||
[:& snap-point {:key (str "point-" (:x point)
|
[:> snap-point* {:key (str "point-" (:x point)
|
||||||
"-" (:y point))
|
"-" (:y point))
|
||||||
:point point
|
:point point
|
||||||
:zoom zoom}])]))
|
:zoom zoom}])]))
|
||||||
|
|
||||||
(mf/defc snap-points
|
(mf/defc snap-points*
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [layout zoom objects selected page-id drawing focus] :as props}]
|
[{:keys [layout zoom objects selected page-id drawing focus]}]
|
||||||
(dm/assert! (set? selected))
|
(dm/assert! (set? selected))
|
||||||
(let [shapes (into [] (keep (d/getf objects)) selected)
|
(let [shapes (into [] (keep (d/getf objects)) selected)
|
||||||
|
|
||||||
@ -165,7 +168,7 @@
|
|||||||
(mf/with-memo [layout filter-shapes objects focus]
|
(mf/with-memo [layout filter-shapes objects focus]
|
||||||
(snap/make-remove-snap layout filter-shapes objects focus))
|
(snap/make-remove-snap layout filter-shapes objects focus))
|
||||||
|
|
||||||
remove-snap?
|
remove-snap
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps remove-snap-base?)
|
(mf/deps remove-snap-base?)
|
||||||
(fn [{:keys [type grid] :as snap}]
|
(fn [{:keys [type grid] :as snap}]
|
||||||
@ -176,8 +179,8 @@
|
|||||||
shapes (if drawing [drawing] shapes)
|
shapes (if drawing [drawing] shapes)
|
||||||
frame-id (snap/snap-frame-id shapes)]
|
frame-id (snap/snap-frame-id shapes)]
|
||||||
(when-not (ctl/any-layout? objects frame-id)
|
(when-not (ctl/any-layout? objects frame-id)
|
||||||
[:& snap-feedback {:shapes shapes
|
[:> snap-feedback* {:shapes shapes
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:remove-snap? remove-snap?
|
:remove-snap remove-snap
|
||||||
:zoom zoom}])))
|
:zoom zoom}])))
|
||||||
|
|
||||||
|
|||||||
@ -78,7 +78,7 @@
|
|||||||
:stroke-width (/ 1 zoom)}}]))
|
:stroke-width (/ 1 zoom)}}]))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc frame-title
|
(mf/defc frame-title*
|
||||||
{::mf/wrap [mf/memo
|
{::mf/wrap [mf/memo
|
||||||
#(mf/deferred % ts/raf)]
|
#(mf/deferred % ts/raf)]
|
||||||
::mf/forward-ref true}
|
::mf/forward-ref true}
|
||||||
@ -261,16 +261,16 @@
|
|||||||
(not= id uuid/zero)
|
(not= id uuid/zero)
|
||||||
(or (dbg/enabled? :shape-titles) (= parent-id uuid/zero))
|
(or (dbg/enabled? :shape-titles) (= parent-id uuid/zero))
|
||||||
(or (empty? focus) (contains? focus id)))
|
(or (empty? focus) (contains? focus id)))
|
||||||
[:& frame-title {:key (dm/str "frame-title-" id)
|
[:> frame-title* {:key (dm/str "frame-title-" id)
|
||||||
:frame shape
|
:frame shape
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:is-selected (contains? selected id)
|
:is-selected (contains? selected id)
|
||||||
:is-show-artboard-names is-show-artboard-names
|
:is-show-artboard-names is-show-artboard-names
|
||||||
:is-show-id (dbg/enabled? :shape-titles)
|
:is-show-id (dbg/enabled? :shape-titles)
|
||||||
:is-grid-edition (and (= id edition) grid-edition?)
|
:is-grid-edition (and (= id edition) grid-edition?)
|
||||||
:on-frame-enter on-frame-enter
|
:on-frame-enter on-frame-enter
|
||||||
:on-frame-leave on-frame-leave
|
:on-frame-leave on-frame-leave
|
||||||
:on-frame-select on-frame-select}]))]))
|
:on-frame-select on-frame-select}]))]))
|
||||||
|
|
||||||
(mf/defc frame-flow*
|
(mf/defc frame-flow*
|
||||||
[{:keys [flow frame is-selected zoom on-frame-enter on-frame-leave on-frame-select]}]
|
[{:keys [flow frame is-selected zoom on-frame-enter on-frame-leave on-frame-select]}]
|
||||||
|
|||||||
@ -636,7 +636,7 @@
|
|||||||
:tool drawing-tool}])
|
:tool drawing-tool}])
|
||||||
|
|
||||||
(when show-grids?
|
(when show-grids?
|
||||||
[:& frame-grid/frame-grid
|
[:> frame-grid/frame-grid*
|
||||||
{:zoom zoom
|
{:zoom zoom
|
||||||
:selected selected
|
:selected selected
|
||||||
:transform transform
|
:transform transform
|
||||||
@ -647,7 +647,7 @@
|
|||||||
:zoom zoom}])
|
:zoom zoom}])
|
||||||
|
|
||||||
(when show-snap-points?
|
(when show-snap-points?
|
||||||
[:& snap-points/snap-points
|
[:> snap-points/snap-points*
|
||||||
{:layout layout
|
{:layout layout
|
||||||
:transform transform
|
:transform transform
|
||||||
:drawing drawing-obj
|
:drawing drawing-obj
|
||||||
@ -749,13 +749,13 @@
|
|||||||
:disabled (or drawing-tool @space?)}])))
|
:disabled (or drawing-tool @space?)}])))
|
||||||
|
|
||||||
(when show-prototypes?
|
(when show-prototypes?
|
||||||
[:& interactions/interactions
|
[:> interactions/interactions*
|
||||||
{:selected selected
|
{:selected selected
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:objects objects-modified
|
:objects objects-modified
|
||||||
:current-transform transform
|
:current-transform transform
|
||||||
:hover-disabled? hover-disabled?}])])
|
:is-hover-disabled hover-disabled?}])])
|
||||||
|
|
||||||
(when show-gradient-handlers?
|
(when show-gradient-handlers?
|
||||||
[:> gradients/gradient-handlers*
|
[:> gradients/gradient-handlers*
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user