mirror of
https://github.com/penpot/penpot.git
synced 2025-02-26 08:45:34 -05:00
🎉 Changed the user origin for shapes to their corner
This commit is contained in:
parent
db4e0fc314
commit
7ab3d86bc6
19 changed files with 195 additions and 182 deletions
|
@ -88,7 +88,3 @@
|
|||
(when (= "main" (unchecked-get js/window app-sym))
|
||||
(reinit)))
|
||||
|
||||
(defn ^:export toggle-debug
|
||||
[]
|
||||
(swap! st/*debug* not))
|
||||
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
(let [frame (get objects (:frame-id shape))
|
||||
{:keys [width height rotation]} shape
|
||||
|
||||
center (gpt/center shape)
|
||||
shapev (-> (gpt/point width height))
|
||||
|
||||
;; Vector modifiers depending on the handler
|
||||
|
@ -140,7 +139,7 @@
|
|||
(watch [_ state stream]
|
||||
(let [stoper (rx/filter ms/mouse-up? stream)
|
||||
group (gsh/selection-rect shapes)
|
||||
group-center (gpt/center group)
|
||||
group-center (gsh/center group)
|
||||
initial-angle (gpt/angle (apply-zoom @ms/mouse-position) group-center)
|
||||
calculate-angle (fn [pos ctrl?]
|
||||
(let [angle (- (gpt/angle pos group-center) initial-angle)
|
||||
|
@ -161,7 +160,7 @@
|
|||
(rx/with-latest vector ms/mouse-position-ctrl)
|
||||
(rx/map (fn [[pos ctrl?]]
|
||||
(let [delta-angle (calculate-angle pos ctrl?)]
|
||||
(set-rotation delta-angle shapes))))
|
||||
(set-rotation delta-angle shapes group-center))))
|
||||
(rx/take-until stoper))
|
||||
(rx/of (apply-modifiers (map :id shapes))))))))
|
||||
|
||||
|
@ -275,7 +274,7 @@
|
|||
|
||||
;; Set-rotation is custom because applies different modifiers to each shape adjusting their position
|
||||
(defn set-rotation
|
||||
[delta-rotation shapes]
|
||||
[delta-rotation shapes center]
|
||||
(ptk/reify ::set-rotation
|
||||
IUpdateGroup
|
||||
(get-ids [_] (map :id shapes))
|
||||
|
@ -293,8 +292,7 @@
|
|||
(rotate-around-center [state angle center shapes]
|
||||
(reduce #(rotate-shape %1 angle %2 center) state shapes))]
|
||||
|
||||
(let [center (-> shapes gsh/selection-rect gpt/center)
|
||||
objects (get-in state [:workspace-data page-id :objects])
|
||||
(let [objects (get-in state [:workspace-data page-id :objects])
|
||||
id->obj #(get objects %)
|
||||
get-children (fn [shape] (map id->obj (helpers/get-children (:id shape) objects)))
|
||||
shapes (concat shapes (mapcat get-children shapes))]
|
||||
|
|
|
@ -57,6 +57,14 @@
|
|||
(get-in % [:workspace-data page-id]))
|
||||
(l/derived st/state)))
|
||||
|
||||
(defn object-by-id
|
||||
[id]
|
||||
(letfn [(selector [state]
|
||||
(let [page-id (get-in state [:workspace-page :id])
|
||||
objects (get-in state [:workspace-data page-id :objects])]
|
||||
(->> (get objects id))))]
|
||||
(l/derived selector st/state =)))
|
||||
|
||||
(defn objects-by-id
|
||||
[ids]
|
||||
(letfn [(selector [state]
|
||||
|
|
|
@ -23,11 +23,10 @@
|
|||
(when (debug? :bounding-boxes)
|
||||
(let [shape (unchecked-get props "shape")
|
||||
frame (unchecked-get props "frame")
|
||||
selrect (geom/transform-selrect frame shape)
|
||||
shape-path (-> shape
|
||||
(geom/transform-apply-modifiers)
|
||||
selrect (-> shape
|
||||
(geom/selection-rect-shape)
|
||||
(geom/translate-to-frame frame))
|
||||
shape-center (geom/center shape-path)]
|
||||
shape-center (geom/center selrect)]
|
||||
[:g
|
||||
[:text {:x (:x selrect)
|
||||
:y (- (:y selrect) 5)
|
||||
|
@ -37,10 +36,12 @@
|
|||
:stroke-width 0.1}
|
||||
(str/format "%s - (%s, %s)" (str/slice (str (:id shape)) 0 8) (fix (:x shape)) (fix (:y shape)))]
|
||||
|
||||
[:circle {:cx (:x shape-center) :cy (:y shape-center) :r 5 :fill "yellow"}]
|
||||
|
||||
[:rect {:x (:x selrect)
|
||||
:y (:y selrect)
|
||||
:width (:width selrect)
|
||||
:height (:height selrect)
|
||||
:style {:stroke "red" :fill "transparent" :stroke-width "1px" :stroke-opacity 0.5}}]])))
|
||||
:style {:stroke "red"
|
||||
:fill "transparent"
|
||||
:stroke-width "1px"
|
||||
:stroke-opacity 0.5
|
||||
:pointer-events "none"}}]])))
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
(declare circle-shape)
|
||||
|
||||
(mf/defc circle-wrapper
|
||||
[{:keys [shape frame] :as props}]
|
||||
[{:keys [shape] :as props}]
|
||||
(let [selected (mf/deref refs/selected-shapes)
|
||||
selected? (contains? selected (:id shape))
|
||||
on-mouse-down #(common/on-mouse-down % shape)
|
||||
|
@ -30,8 +30,7 @@
|
|||
[:g.shape {:class (when selected? "selected")
|
||||
:on-mouse-down on-mouse-down
|
||||
:on-context-menu on-context-menu}
|
||||
[:& circle-shape {:shape (geom/transform-shape frame shape)}]
|
||||
[:& bounding-box {:shape shape :frame frame}]]))
|
||||
[:& circle-shape {:shape shape}]]))
|
||||
|
||||
;; --- Circle Shape
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
|
||||
inv-zoom (/ 1 zoom)
|
||||
childs (mapv #(get objects %) (:shapes shape))
|
||||
ds-modifier (:displacement-modifier shape)
|
||||
ds-modifier (get-in shape [:modifiers :displacement])
|
||||
|
||||
label-pos (cond-> (gpt/point x (- y 10))
|
||||
(gmt/matrix? ds-modifier) (gpt/transform ds-modifier))
|
||||
|
|
|
@ -73,11 +73,9 @@
|
|||
|
||||
[:& group-shape
|
||||
{:frame frame
|
||||
:shape (geom/transform-shape frame shape)
|
||||
:shape shape
|
||||
:children children
|
||||
:is-child-selected? is-child-selected?}]
|
||||
(when (not is-child-selected?)
|
||||
[:& bounding-box {:shape shape :frame frame}])]))))
|
||||
:is-child-selected? is-child-selected?}]]))))
|
||||
|
||||
(defn group-shape
|
||||
[shape-wrapper]
|
||||
|
|
|
@ -15,15 +15,14 @@
|
|||
[uxbox.main.ui.shapes.attrs :as attrs]
|
||||
[uxbox.main.ui.shapes.common :as common]
|
||||
[uxbox.util.interop :as itr]
|
||||
[uxbox.util.geom.matrix :as gmt]
|
||||
[uxbox.main.ui.shapes.bounding-box :refer [bounding-box]]))
|
||||
[uxbox.util.geom.matrix :as gmt]))
|
||||
|
||||
;; --- Image Wrapper
|
||||
|
||||
(declare image-shape)
|
||||
|
||||
(mf/defc image-wrapper
|
||||
[{:keys [shape frame] :as props}]
|
||||
[{:keys [shape] :as props}]
|
||||
(let [selected (mf/deref refs/selected-shapes)
|
||||
selected? (contains? selected (:id shape))
|
||||
on-mouse-down (mf/use-callback
|
||||
|
@ -37,8 +36,7 @@
|
|||
[:g.shape {:class (when selected? "selected")
|
||||
:on-mouse-down on-mouse-down
|
||||
:on-context-menu on-context-menu}
|
||||
[:& image-shape {:shape (geom/transform-shape frame shape)}]
|
||||
[:& bounding-box {:shape shape :frame frame}]]))
|
||||
[:& image-shape {:shape shape}]]))
|
||||
|
||||
;; --- Image Shape
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
(declare path-shape)
|
||||
|
||||
(mf/defc path-wrapper
|
||||
[{:keys [shape frame] :as props}]
|
||||
[{:keys [shape] :as props}]
|
||||
(let [selected (mf/deref refs/selected-shapes)
|
||||
selected? (contains? selected (:id shape))
|
||||
on-mouse-down (mf/use-callback
|
||||
|
@ -42,8 +42,7 @@
|
|||
[:g.shape {:on-double-click on-double-click
|
||||
:on-mouse-down on-mouse-down
|
||||
:on-context-menu on-context-menu}
|
||||
[:& path-shape {:shape (geom/transform-shape frame shape) :background? true}]
|
||||
[:& bounding-box {:shape shape :frame frame}]]))
|
||||
[:& path-shape {:shape shape :background? true}]]))
|
||||
|
||||
;; --- Path Shape
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
[uxbox.main.ui.shapes.attrs :as attrs]
|
||||
[uxbox.main.ui.shapes.common :as common]
|
||||
[uxbox.util.interop :as itr]
|
||||
[uxbox.main.ui.shapes.bounding-box :refer [bounding-box]]
|
||||
[uxbox.main.ui.shapes.custom-stroke :refer [shape-custom-stroke]]))
|
||||
|
||||
;; --- Rect Wrapper
|
||||
|
@ -26,7 +25,6 @@
|
|||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [shape (unchecked-get props "shape")
|
||||
frame (unchecked-get props "frame")
|
||||
on-mouse-down (mf/use-callback
|
||||
(mf/deps shape)
|
||||
#(common/on-mouse-down % shape))
|
||||
|
@ -35,8 +33,7 @@
|
|||
#(common/on-context-menu % shape))]
|
||||
[:g.shape {:on-mouse-down on-mouse-down
|
||||
:on-context-menu on-context-menu}
|
||||
[:& rect-shape {:shape (geom/transform-shape frame shape) }]
|
||||
[:& bounding-box {:shape shape :frame frame}]]))
|
||||
[:& rect-shape {:shape shape}]]))
|
||||
|
||||
;; --- Rect Shape
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
[uxbox.main.ui.shapes.text :as text]
|
||||
[uxbox.main.ui.shapes.group :as group]
|
||||
[uxbox.main.ui.shapes.frame :as frame]
|
||||
[uxbox.main.ui.shapes.bounding-box :refer [bounding-box]]
|
||||
[uxbox.util.geom.shapes :as gsh]
|
||||
[uxbox.main.refs :as refs]))
|
||||
|
||||
(defn- shape-wrapper-memo-equals?
|
||||
|
@ -42,8 +44,10 @@
|
|||
[props]
|
||||
(let [shape (unchecked-get props "shape")
|
||||
frame (unchecked-get props "frame")
|
||||
opts #js {:shape shape :frame frame}]
|
||||
opts #js {:shape (->> shape (gsh/transform-shape frame))
|
||||
:frame frame}]
|
||||
(when (and shape (not (:hidden shape)))
|
||||
[:*
|
||||
(case (:type shape)
|
||||
:group [:> group-wrapper opts]
|
||||
:curve [:> path/path-wrapper opts]
|
||||
|
@ -55,8 +59,9 @@
|
|||
:circle [:> circle/circle-wrapper opts]
|
||||
|
||||
;; Only used when drawing a new frame.
|
||||
:frame [:> frame-wrapper opts]
|
||||
nil))))
|
||||
:frame [:> frame-wrapper {:shape shape}]
|
||||
nil)
|
||||
[:& bounding-box {:shape shape :frame frame}]])))
|
||||
|
||||
(def group-wrapper (group/group-wrapper shape-wrapper))
|
||||
(def frame-wrapper (frame/frame-wrapper shape-wrapper))
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
(declare text-shape)
|
||||
|
||||
(mf/defc text-wrapper
|
||||
[{:keys [shape frame] :as props}]
|
||||
[{:keys [shape] :as props}]
|
||||
(let [{:keys [id x1 y1 content group]} shape
|
||||
selected (mf/deref refs/selected-shapes)
|
||||
edition (mf/deref refs/selected-edition)
|
||||
|
@ -67,8 +67,8 @@
|
|||
:on-mouse-down on-mouse-down
|
||||
:on-context-menu on-context-menu}
|
||||
(if edition?
|
||||
[:& text-shape-edit {:shape (geom/transform-shape frame shape)}]
|
||||
[:& text-shape {:shape (geom/transform-shape frame shape)
|
||||
[:& text-shape-edit {:shape shape}]
|
||||
[:& text-shape {:shape shape
|
||||
:selected? selected?}])]))
|
||||
|
||||
;; --- Text Rendering
|
||||
|
@ -284,7 +284,8 @@
|
|||
|
||||
(mf/use-effect on-mount)
|
||||
|
||||
[:foreignObject {:x x :y y :width width :height height :ref self-ref}
|
||||
[:foreignObject {:transform (geom/transform-matrix shape)
|
||||
:x x :y y :width width :height height :ref self-ref}
|
||||
[:> rslate/Slate {:editor editor
|
||||
:value @state
|
||||
:on-change on-change}
|
||||
|
@ -305,13 +306,7 @@
|
|||
|
||||
(mf/defc text-shape
|
||||
[{:keys [shape selected?] :as props}]
|
||||
(let [{:keys [id x y width height rotation content]} shape
|
||||
transform (when (and rotation (pos? rotation))
|
||||
(str/format "rotate(%s %s %s)"
|
||||
rotation
|
||||
(+ x (/ width 2))
|
||||
(+ y (/ height 2))))
|
||||
|
||||
(let [{:keys [id x y width height content]} shape
|
||||
content (parse-content content)
|
||||
editor (mf/use-memo #(rslate/withReact (slate/createEditor)))
|
||||
|
||||
|
@ -334,7 +329,7 @@
|
|||
|
||||
[:foreignObject {:x x
|
||||
:y y
|
||||
:transform transform
|
||||
:transform (geom/transform-matrix shape)
|
||||
:id (str id)
|
||||
:width width
|
||||
:height height}
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
(let [modifier (-> (gpt/point (:x frame) (:y frame))
|
||||
(gpt/negate)
|
||||
(gmt/translate-matrix))
|
||||
frame (assoc frame :displacement-modifier modifier)
|
||||
frame (assoc-in frame [:modifiers :displacement] modifier )
|
||||
|
||||
width (* (:width frame) zoom)
|
||||
height (* (:height frame) zoom)
|
||||
|
|
|
@ -305,7 +305,7 @@
|
|||
|
||||
(mf/defc generic-draw-area
|
||||
[{:keys [shape zoom]}]
|
||||
(let [{:keys [x y width height]} (geom/transform-selrect nil shape)]
|
||||
(let [{:keys [x y width height]} (geom/selection-rect-shape shape)]
|
||||
(when (and x y)
|
||||
[:g
|
||||
[:& shapes/shape-wrapper {:shape shape}]
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
[{:keys [shape zoom on-resize on-rotate] :as props}]
|
||||
(let [{:keys [x y width height rotation] :as shape} (geom/shape->rect-shape shape)
|
||||
radius (if (> (max width height) handler-size-threshold) 4.0 4.0)
|
||||
|
||||
transform (geom/transform-matrix shape)
|
||||
|
||||
resize-handlers {:top [(+ x (/ width 2 )) y]
|
||||
|
@ -85,14 +86,12 @@
|
|||
|
||||
[:g.controls
|
||||
[:rect.main {:transform transform
|
||||
:x x :y y
|
||||
:width width
|
||||
:height height
|
||||
;;:stroke-dasharray (str (/ 8.0 zoom) "," (/ 5 zoom))
|
||||
:vector-effect "non-scaling-stroke"
|
||||
:x (- x 1) :y (- y 1)
|
||||
:width (+ width 2)
|
||||
:height (+ height 2)
|
||||
:style {:stroke "#1FDEA7"
|
||||
:fill "transparent"
|
||||
:stroke-opacity "1"}}]
|
||||
:stroke-width "1"
|
||||
:fill "transparent"}}]
|
||||
|
||||
(for [[position [cx cy]] resize-handlers]
|
||||
(let [tp (gpt/transform (gpt/point cx cy) transform)]
|
||||
|
@ -156,12 +155,12 @@
|
|||
|
||||
(mf/defc text-edition-selection-handlers
|
||||
[{:keys [shape zoom] :as props}]
|
||||
(let [{:keys [x y width height] :as shape} shape]
|
||||
(let [{:keys [x y width height]} shape]
|
||||
[:g.controls
|
||||
[:rect.main {:x x :y y
|
||||
:transform (geom/transform-matrix shape)
|
||||
:width width
|
||||
:height height
|
||||
;; :stroke-dasharray (str (/ 5.0 zoom) "," (/ 5 zoom))
|
||||
:style {:stroke "#1FDEA7"
|
||||
:stroke-width "0.5"
|
||||
:stroke-opacity "1"
|
||||
|
@ -170,16 +169,20 @@
|
|||
(mf/defc multiple-selection-handlers
|
||||
[{:keys [shapes selected zoom objects] :as props}]
|
||||
(let [shape (geom/selection-rect shapes)
|
||||
shape-center (geom/center shape)
|
||||
on-resize #(do (dom/stop-propagation %2)
|
||||
(st/emit! (dw/start-resize %1 selected shape objects)))
|
||||
|
||||
on-rotate #(do (dom/stop-propagation %)
|
||||
(st/emit! (dw/start-rotate shapes)))]
|
||||
|
||||
[:*
|
||||
[:& controls {:shape shape
|
||||
:zoom zoom
|
||||
:on-resize on-resize
|
||||
:on-rotate on-rotate}]))
|
||||
:on-rotate on-rotate}]
|
||||
(when (debug? :selection-center)
|
||||
[:circle {:cx (:x shape-center) :cy (:y shape-center) :r 5 :fill "yellow"}])]))
|
||||
|
||||
(mf/defc single-selection-handlers
|
||||
[{:keys [shape zoom objects] :as props}]
|
||||
|
|
|
@ -15,25 +15,43 @@
|
|||
[uxbox.main.refs :as refs]
|
||||
[uxbox.common.data :as d]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.geom.shapes :as gsh]
|
||||
[uxbox.util.geom.point :as gpt]
|
||||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.util.math :as math]
|
||||
[uxbox.util.i18n :refer [t] :as i18n]))
|
||||
|
||||
|
||||
;; -- User/drawing coords
|
||||
(defn user-coords-vector [shape]
|
||||
(let [{sel-x :x sel-y :y :as selrect}
|
||||
(-> shape
|
||||
gsh/shape->path
|
||||
(gsh/center-transform (:transform shape))
|
||||
gsh/shape->rect-shape)
|
||||
{rec-x :x rec-y :y} (-> shape gsh/shape->rect-shape)
|
||||
|
||||
dx (- rec-x sel-x)
|
||||
dy (- rec-y sel-y)]
|
||||
(gpt/point dx dy)))
|
||||
|
||||
(defn user->draw [{:keys [x y width height] :as shape}]
|
||||
(let [dv (user-coords-vector shape)]
|
||||
(-> shape (gsh/move dv))))
|
||||
|
||||
(defn draw->user [{:keys [x y width height] :as shape}]
|
||||
(let [dv (user-coords-vector shape)]
|
||||
(-> shape (gsh/move (gpt/negate dv)))))
|
||||
|
||||
(mf/defc measures-menu
|
||||
[{:keys [shape options] :as props}]
|
||||
(let [options (or options #{:size :position :rotation :radius})
|
||||
locale (i18n/use-locale)
|
||||
frame (deref (refs/object-by-id (:frame-id shape)))
|
||||
|
||||
data (deref refs/workspace-data)
|
||||
parent (get-in data [:objects (:frame-id shape)])
|
||||
|
||||
x (cond
|
||||
(:x shape) :x
|
||||
(:cx shape) :cx)
|
||||
|
||||
y (cond
|
||||
(:y shape) :y
|
||||
(:cy shape) :cy)
|
||||
shape (->> shape
|
||||
(gsh/transform-shape frame)
|
||||
(draw->user))
|
||||
|
||||
on-size-change
|
||||
(fn [event attr]
|
||||
|
@ -58,9 +76,12 @@
|
|||
(fn [event attr]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(d/parse-integer 0)
|
||||
(+ (attr parent)))] ; Convert back to absolute position before update
|
||||
(st/emit! (udw/update-position (:id shape) {attr value}))))
|
||||
(d/parse-integer 0))
|
||||
new-shape (-> shape
|
||||
(assoc attr value)
|
||||
(gsh/translate-from-frame frame)
|
||||
(user->draw))]
|
||||
(st/emit! (udw/update-position (:id shape) (select-keys new-shape [attr])))))
|
||||
|
||||
on-rotation-change
|
||||
(fn [event]
|
||||
|
@ -148,17 +169,21 @@
|
|||
:type "number"
|
||||
:no-validate true
|
||||
:on-change on-pos-x-change
|
||||
:value (str (-> (- (x shape) (:x parent)) ; Show to user position relative to frame
|
||||
(d/coalesce 0)
|
||||
(math/round)))}]]
|
||||
:value (:x shape)
|
||||
;;:value (str (-> (- (x shape) (:x parent)) ; Show to user position relative to frame
|
||||
;; (d/coalesce 0)
|
||||
;; (math/round)))
|
||||
}]]
|
||||
[:div.input-element.pixels
|
||||
[:input.input-text {:placeholder "y"
|
||||
:type "number"
|
||||
:no-validate true
|
||||
:on-change on-pos-y-change
|
||||
:value (str (-> (- (y shape) (:y parent))
|
||||
(d/coalesce 0)
|
||||
(math/round)))}]]])
|
||||
:value (:y shape)
|
||||
;;:value (str (-> (- (y shape) (:y parent))
|
||||
;; (d/coalesce 0)
|
||||
;; (math/round)))
|
||||
}]]])
|
||||
|
||||
(when (options :rotation)
|
||||
[:div.row-flex
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
(ns uxbox.util.debug
|
||||
"Debugging utils"
|
||||
(:require
|
||||
[uxbox.main.store :as store]))
|
||||
"Debugging utils")
|
||||
|
||||
(def debug-options #{:bounding-boxes :group :events :rotation-handler #_:simple-selection })
|
||||
(def debug-options #{:bounding-boxes :group :events :rotation-handler :selection-center #_:simple-selection })
|
||||
|
||||
(defonce ^:dynamic *debug* (atom #{}))
|
||||
|
||||
|
@ -13,6 +11,13 @@
|
|||
(defn -debug! [option] (swap! *debug* disj option))
|
||||
(defn debug? [option] (@*debug* option))
|
||||
|
||||
|
||||
(defn ^:export toggle-debug [name] (let [option (keyword name)]
|
||||
(if (debug? option)
|
||||
(-debug! option)
|
||||
(debug! option))))
|
||||
(defn ^:export debug-all [name] (debug-all!))
|
||||
|
||||
(defn tap
|
||||
"Transducer function that can execute a side-effect `effect-fn` per input"
|
||||
[effect-fn]
|
||||
|
@ -31,9 +36,4 @@
|
|||
(js/console.log str (clj->js val))
|
||||
val))
|
||||
|
||||
(defn dump-state []
|
||||
(logjs "state" @store/state))
|
||||
|
||||
(defn dump-objects []
|
||||
(let [page-id (get @store/state :current-page-id)]
|
||||
(logjs "state" (get-in @store/state [:workspace-data page-id :objects]))))
|
||||
|
|
|
@ -40,11 +40,6 @@
|
|||
(throw (ex-info "Invalid arguments" {:v v}))))
|
||||
([x y] (Point. x y)))
|
||||
|
||||
(defn center
|
||||
[{:keys [x y width height]}]
|
||||
(point (+ x (/ width 2))
|
||||
(+ y (/ height 2))))
|
||||
|
||||
(defn add
|
||||
"Returns the addition of the supplied value to both
|
||||
coordinates of the point as a new point."
|
||||
|
|
|
@ -376,6 +376,7 @@
|
|||
maxx (transduce (map :x) max segments)
|
||||
maxy (transduce (map :y) max segments)]
|
||||
(assoc shape
|
||||
:type :rect
|
||||
:x1 minx
|
||||
:y1 miny
|
||||
:x2 maxx
|
||||
|
@ -495,7 +496,7 @@
|
|||
|
||||
(defn translate-from-frame
|
||||
[shape {:keys [x y] :as frame}]
|
||||
(move shape (gpt/point (+ x) (+ y))))
|
||||
(move shape (gpt/point x y)))
|
||||
|
||||
;; --- Alignment
|
||||
|
||||
|
@ -736,13 +737,6 @@
|
|||
(gpt/divide (gpt/point (:width shape-path-temp-rec) (:height shape-path-temp-rec))
|
||||
(gpt/point (:width shape-path-temp-dim) (:height shape-path-temp-dim)))))
|
||||
|
||||
(defn transform-selrect
|
||||
[frame shape]
|
||||
(-> shape
|
||||
(transform-apply-modifiers)
|
||||
(translate-to-frame frame)
|
||||
(shape->rect-shape)))
|
||||
|
||||
(defn transform-rect-shape
|
||||
[shape]
|
||||
(let [;; Apply modifiers to the rect as a path so we have the end shape expected
|
||||
|
@ -788,6 +782,8 @@
|
|||
|
||||
new-shape (-> shape
|
||||
(merge rec)
|
||||
(update :x #(mth/precision % 2))
|
||||
(update :y #(mth/precision % 2))
|
||||
(update :transform #(gmt/multiply (or % (gmt/matrix)) stretch-matrix))
|
||||
(update :transform-inverse #(gmt/multiply stretch-matrix-inverse (or % (gmt/matrix)))))]
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue