@grida/hud 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -384,8 +384,18 @@ type SurfaceGesture = {
384
384
  * AABB + matrix so resize math runs in the rotated/skewed local frame.
385
385
  */
386
386
  initial_shape: SelectionShape; /** Anchor (pointer-down) in document-space. */
387
- anchor_doc: cmath.Vector2; /** Current shape during the gesture. Same kind as `initial_shape`. */
387
+ anchor_doc: cmath.Vector2;
388
+ /** Current shape during the gesture. Same kind as `initial_shape`.
389
+ * Opposite-anchored — feeds the emitted `resize` intent (move +
390
+ * commit). The host derives its own anchor (e.g. Alt → center)
391
+ * from these dims, so this MUST stay opposite-anchored. */
388
392
  current_shape: SelectionShape;
393
+ /** Shape to DRAW for the dashed preview. Equals `current_shape`
394
+ * except under Alt, where it is symmetric about the initial
395
+ * center so the dashed box matches where a center-anchoring host
396
+ * lands the artwork (otherwise the preview visibly lags the
397
+ * actual result). Visual only — never emitted on an intent. */
398
+ preview_shape: SelectionShape;
389
399
  } | {
390
400
  kind: "rotate";
391
401
  ids: NodeId[];
@@ -384,8 +384,18 @@ type SurfaceGesture = {
384
384
  * AABB + matrix so resize math runs in the rotated/skewed local frame.
385
385
  */
386
386
  initial_shape: SelectionShape; /** Anchor (pointer-down) in document-space. */
387
- anchor_doc: cmath.Vector2; /** Current shape during the gesture. Same kind as `initial_shape`. */
387
+ anchor_doc: cmath.Vector2;
388
+ /** Current shape during the gesture. Same kind as `initial_shape`.
389
+ * Opposite-anchored — feeds the emitted `resize` intent (move +
390
+ * commit). The host derives its own anchor (e.g. Alt → center)
391
+ * from these dims, so this MUST stay opposite-anchored. */
388
392
  current_shape: SelectionShape;
393
+ /** Shape to DRAW for the dashed preview. Equals `current_shape`
394
+ * except under Alt, where it is symmetric about the initial
395
+ * center so the dashed box matches where a center-anchoring host
396
+ * lands the artwork (otherwise the preview visibly lags the
397
+ * actual result). Visual only — never emitted on an intent. */
398
+ preview_shape: SelectionShape;
389
399
  } | {
390
400
  kind: "rotate";
391
401
  ids: NodeId[];
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as HUDPaintStripes, c as HUDRect, d as HUDSemantic, f as HUDSemanticGroup, i as HUDPaintSolid, l as HUDRule, n as HUDLine, o as HUDPoint, r as HUDPaint, s as HUDPolyline, t as HUDDraw, u as HUDScreenRect } from "./types-3wwFisZs.mjs";
2
2
  import { a as cursorEquals, i as RotationCorner, n as CursorRenderer, o as cursorToCss, r as ResizeDirection, t as CursorIcon } from "./cursor-CxS8EMvm.mjs";
3
- import { $ as ResolvedPaint, $t as DEFAULT_RULER_OVERLAP_THRESHOLD, A as TransformBoxHover, At as cornerRadiusLayoutGroups, B as Modifiers, Bt as TransformBoxCorners, C as MIN_CHROME_VISIBLE_SIZE, Ct as DEFAULT_CORNER_RADIUS_HANDLE_SIZE, D as VectorHover, Dt as cornerRadiusAnchorSign, E as RenderShape, Et as computeCornerRadiusLayout, F as TapHandler, Ft as SurfaceGesture, G as lassoToHUDDraw, Gt as getTransformBoxCorners, H as PointerButton, Ht as compose, I as TapOutcome, It as SelectionGroup, J as snapGuideToHUDDraw, Jt as DEFAULT_RULER_ACCENT_COLOR, K as marqueeToHUDDraw, Kt as reduceTransformBox, L as Intent, Lt as SelectionShape, M as PaddingHover, Mt as resolveCenterDragAnchor, N as PaddingOverlayInput, Nt as resolveCornerDragAnchor, O as VectorSubSelection, Ot as cornerRadiusHandlePosLine, P as HUDStyle, Pt as Rect, Q as DEFAULT_STRIPES_THICKNESS_PX, Qt as DEFAULT_RULER_FONT, R as IntentPhase, Rt as AffineTransform, S as HitShape, St as DEFAULT_CORNER_RADIUS_HANDLE_INSET, T as OverlayElement, Tt as DrawCornerRadiusParams, U as SurfaceEvent, Ut as cornersToBoxTransform, V as NO_MODS, Vt as TransformBoxOptions, W as SurfaceResponse, Wt as decompose, X as DEFAULT_STRIPES_ANGLE_DEG, Xt as DEFAULT_RULER_COLOR, Y as filterHUDDrawByGroup, Yt as DEFAULT_RULER_BACKGROUND, Z as DEFAULT_STRIPES_SPACING_PX, Zt as DEFAULT_RULER_DRAG_THRESHOLD, _ as PADDING_HANDLE_PRIORITY, _t as resolveParametricHandleByDirection, a as SurfaceVisibilityPolicy, an as RulerAxis, at as DEFAULT_PARAMETRIC_HANDLE_INSET, b as VectorOverlay, bt as CornerRadiusInput, c as VectorSelectionMode, cn as RulerRange, ct as DrawParametricHandlesParams, d as TRANSFORM_BOX_CORNER_HIT_SIZE, dn as DEFAULT_PIXEL_GRID_STEPS, dt as ParametricHandleInput, en as DEFAULT_RULER_STEPS, et as buildStripesTile, f as TRANSFORM_BOX_CORNER_PRIORITY, fn as DrawPixelGridParams, ft as ParametricHandleLayout, g as PADDING_HANDLE_LENGTH, gt as projectParametricHandleValue, h as buildPaddingOverlay, ht as parametricHandleLayoutGroups, i as SurfaceVisibilityContext, in as DrawRulerParams, it as HUDCanvasOptions, j as TransformBoxInput, jt as drawCornerRadius, k as TransformBoxActiveOp, kt as cornerRadiusHandlePosRect, l as buildTransformBox, ln as drawRuler, lt as ParametricHandle, m as TRANSFORM_BOX_SIDE_PRIORITY, mn as drawPixelGrid, mt as drawParametricHandles, n as SurfaceOptions, nn as DEFAULT_RULER_TEXT_SIDE_OFFSET, nt as resolvePaint, o as VectorBendMode, on as RulerConfig, ot as DEFAULT_PARAMETRIC_HANDLE_SIZE, p as TRANSFORM_BOX_SIDE_HIT_THICKNESS, pn as PixelGridConfig, pt as computeParametricHandleLayout, q as measurementToHUDDraw, qt as DEFAULT_RULER_ACCENT_BACKGROUND, r as SurfaceVisibility, rn as DEFAULT_RULER_TICK_HEIGHT, rt as HUDCanvas, s as VectorInsertionMode, sn as RulerMark, st as DEFAULT_PARAMETRIC_HIT_SIZE, t as Surface, tn as DEFAULT_RULER_STRIP, tt as computeStripesTileGeometry, u as TRANSFORM_BOX_BODY_PRIORITY, un as DEFAULT_PIXEL_GRID_COLOR, ut as ParametricHandleGroup, v as PADDING_HANDLE_THICKNESS, vt as CornerRadiusAnchor, w as MIN_HIT_SIZE, wt as DEFAULT_CORNER_RADIUS_HIT_SIZE, x as SurfaceChromeGroups, xt as CornerRadiusRectangular, y as PADDING_REGION_PRIORITY, yt as CornerRadiusHandleLayout, z as SelectMode, zt as TransformBoxAction } from "./index-BQtDtpHM.mjs";
3
+ import { $ as ResolvedPaint, $t as DEFAULT_RULER_OVERLAP_THRESHOLD, A as TransformBoxHover, At as cornerRadiusLayoutGroups, B as Modifiers, Bt as TransformBoxCorners, C as MIN_CHROME_VISIBLE_SIZE, Ct as DEFAULT_CORNER_RADIUS_HANDLE_SIZE, D as VectorHover, Dt as cornerRadiusAnchorSign, E as RenderShape, Et as computeCornerRadiusLayout, F as TapHandler, Ft as SurfaceGesture, G as lassoToHUDDraw, Gt as getTransformBoxCorners, H as PointerButton, Ht as compose, I as TapOutcome, It as SelectionGroup, J as snapGuideToHUDDraw, Jt as DEFAULT_RULER_ACCENT_COLOR, K as marqueeToHUDDraw, Kt as reduceTransformBox, L as Intent, Lt as SelectionShape, M as PaddingHover, Mt as resolveCenterDragAnchor, N as PaddingOverlayInput, Nt as resolveCornerDragAnchor, O as VectorSubSelection, Ot as cornerRadiusHandlePosLine, P as HUDStyle, Pt as Rect, Q as DEFAULT_STRIPES_THICKNESS_PX, Qt as DEFAULT_RULER_FONT, R as IntentPhase, Rt as AffineTransform, S as HitShape, St as DEFAULT_CORNER_RADIUS_HANDLE_INSET, T as OverlayElement, Tt as DrawCornerRadiusParams, U as SurfaceEvent, Ut as cornersToBoxTransform, V as NO_MODS, Vt as TransformBoxOptions, W as SurfaceResponse, Wt as decompose, X as DEFAULT_STRIPES_ANGLE_DEG, Xt as DEFAULT_RULER_COLOR, Y as filterHUDDrawByGroup, Yt as DEFAULT_RULER_BACKGROUND, Z as DEFAULT_STRIPES_SPACING_PX, Zt as DEFAULT_RULER_DRAG_THRESHOLD, _ as PADDING_HANDLE_PRIORITY, _t as resolveParametricHandleByDirection, a as SurfaceVisibilityPolicy, an as RulerAxis, at as DEFAULT_PARAMETRIC_HANDLE_INSET, b as VectorOverlay, bt as CornerRadiusInput, c as VectorSelectionMode, cn as RulerRange, ct as DrawParametricHandlesParams, d as TRANSFORM_BOX_CORNER_HIT_SIZE, dn as DEFAULT_PIXEL_GRID_STEPS, dt as ParametricHandleInput, en as DEFAULT_RULER_STEPS, et as buildStripesTile, f as TRANSFORM_BOX_CORNER_PRIORITY, fn as DrawPixelGridParams, ft as ParametricHandleLayout, g as PADDING_HANDLE_LENGTH, gt as projectParametricHandleValue, h as buildPaddingOverlay, ht as parametricHandleLayoutGroups, i as SurfaceVisibilityContext, in as DrawRulerParams, it as HUDCanvasOptions, j as TransformBoxInput, jt as drawCornerRadius, k as TransformBoxActiveOp, kt as cornerRadiusHandlePosRect, l as buildTransformBox, ln as drawRuler, lt as ParametricHandle, m as TRANSFORM_BOX_SIDE_PRIORITY, mn as drawPixelGrid, mt as drawParametricHandles, n as SurfaceOptions, nn as DEFAULT_RULER_TEXT_SIDE_OFFSET, nt as resolvePaint, o as VectorBendMode, on as RulerConfig, ot as DEFAULT_PARAMETRIC_HANDLE_SIZE, p as TRANSFORM_BOX_SIDE_HIT_THICKNESS, pn as PixelGridConfig, pt as computeParametricHandleLayout, q as measurementToHUDDraw, qt as DEFAULT_RULER_ACCENT_BACKGROUND, r as SurfaceVisibility, rn as DEFAULT_RULER_TICK_HEIGHT, rt as HUDCanvas, s as VectorInsertionMode, sn as RulerMark, st as DEFAULT_PARAMETRIC_HIT_SIZE, t as Surface, tn as DEFAULT_RULER_STRIP, tt as computeStripesTileGeometry, u as TRANSFORM_BOX_BODY_PRIORITY, un as DEFAULT_PIXEL_GRID_COLOR, ut as ParametricHandleGroup, v as PADDING_HANDLE_THICKNESS, vt as CornerRadiusAnchor, w as MIN_HIT_SIZE, wt as DEFAULT_CORNER_RADIUS_HIT_SIZE, x as SurfaceChromeGroups, xt as CornerRadiusRectangular, y as PADDING_REGION_PRIORITY, yt as CornerRadiusHandleLayout, z as SelectMode, zt as TransformBoxAction } from "./index-DHVvd2ak.mjs";
4
4
 
5
5
  //#region event/selection-controls.d.ts
6
6
  declare const HUDHitPriority: {
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as HUDPaintStripes, c as HUDRect, d as HUDSemantic, f as HUDSemanticGroup, i as HUDPaintSolid, l as HUDRule, n as HUDLine, o as HUDPoint, r as HUDPaint, s as HUDPolyline, t as HUDDraw, u as HUDScreenRect } from "./types-3wwFisZs.js";
2
2
  import { a as cursorEquals, i as RotationCorner, n as CursorRenderer, o as cursorToCss, r as ResizeDirection, t as CursorIcon } from "./cursor-CxS8EMvm.js";
3
- import { $ as ResolvedPaint, $t as DEFAULT_RULER_OVERLAP_THRESHOLD, A as TransformBoxHover, At as cornerRadiusLayoutGroups, B as Modifiers, Bt as TransformBoxCorners, C as MIN_CHROME_VISIBLE_SIZE, Ct as DEFAULT_CORNER_RADIUS_HANDLE_SIZE, D as VectorHover, Dt as cornerRadiusAnchorSign, E as RenderShape, Et as computeCornerRadiusLayout, F as TapHandler, Ft as SurfaceGesture, G as lassoToHUDDraw, Gt as getTransformBoxCorners, H as PointerButton, Ht as compose, I as TapOutcome, It as SelectionGroup, J as snapGuideToHUDDraw, Jt as DEFAULT_RULER_ACCENT_COLOR, K as marqueeToHUDDraw, Kt as reduceTransformBox, L as Intent, Lt as SelectionShape, M as PaddingHover, Mt as resolveCenterDragAnchor, N as PaddingOverlayInput, Nt as resolveCornerDragAnchor, O as VectorSubSelection, Ot as cornerRadiusHandlePosLine, P as HUDStyle, Pt as Rect, Q as DEFAULT_STRIPES_THICKNESS_PX, Qt as DEFAULT_RULER_FONT, R as IntentPhase, Rt as AffineTransform, S as HitShape, St as DEFAULT_CORNER_RADIUS_HANDLE_INSET, T as OverlayElement, Tt as DrawCornerRadiusParams, U as SurfaceEvent, Ut as cornersToBoxTransform, V as NO_MODS, Vt as TransformBoxOptions, W as SurfaceResponse, Wt as decompose, X as DEFAULT_STRIPES_ANGLE_DEG, Xt as DEFAULT_RULER_COLOR, Y as filterHUDDrawByGroup, Yt as DEFAULT_RULER_BACKGROUND, Z as DEFAULT_STRIPES_SPACING_PX, Zt as DEFAULT_RULER_DRAG_THRESHOLD, _ as PADDING_HANDLE_PRIORITY, _t as resolveParametricHandleByDirection, a as SurfaceVisibilityPolicy, an as RulerAxis, at as DEFAULT_PARAMETRIC_HANDLE_INSET, b as VectorOverlay, bt as CornerRadiusInput, c as VectorSelectionMode, cn as RulerRange, ct as DrawParametricHandlesParams, d as TRANSFORM_BOX_CORNER_HIT_SIZE, dn as DEFAULT_PIXEL_GRID_STEPS, dt as ParametricHandleInput, en as DEFAULT_RULER_STEPS, et as buildStripesTile, f as TRANSFORM_BOX_CORNER_PRIORITY, fn as DrawPixelGridParams, ft as ParametricHandleLayout, g as PADDING_HANDLE_LENGTH, gt as projectParametricHandleValue, h as buildPaddingOverlay, ht as parametricHandleLayoutGroups, i as SurfaceVisibilityContext, in as DrawRulerParams, it as HUDCanvasOptions, j as TransformBoxInput, jt as drawCornerRadius, k as TransformBoxActiveOp, kt as cornerRadiusHandlePosRect, l as buildTransformBox, ln as drawRuler, lt as ParametricHandle, m as TRANSFORM_BOX_SIDE_PRIORITY, mn as drawPixelGrid, mt as drawParametricHandles, n as SurfaceOptions, nn as DEFAULT_RULER_TEXT_SIDE_OFFSET, nt as resolvePaint, o as VectorBendMode, on as RulerConfig, ot as DEFAULT_PARAMETRIC_HANDLE_SIZE, p as TRANSFORM_BOX_SIDE_HIT_THICKNESS, pn as PixelGridConfig, pt as computeParametricHandleLayout, q as measurementToHUDDraw, qt as DEFAULT_RULER_ACCENT_BACKGROUND, r as SurfaceVisibility, rn as DEFAULT_RULER_TICK_HEIGHT, rt as HUDCanvas, s as VectorInsertionMode, sn as RulerMark, st as DEFAULT_PARAMETRIC_HIT_SIZE, t as Surface, tn as DEFAULT_RULER_STRIP, tt as computeStripesTileGeometry, u as TRANSFORM_BOX_BODY_PRIORITY, un as DEFAULT_PIXEL_GRID_COLOR, ut as ParametricHandleGroup, v as PADDING_HANDLE_THICKNESS, vt as CornerRadiusAnchor, w as MIN_HIT_SIZE, wt as DEFAULT_CORNER_RADIUS_HIT_SIZE, x as SurfaceChromeGroups, xt as CornerRadiusRectangular, y as PADDING_REGION_PRIORITY, yt as CornerRadiusHandleLayout, z as SelectMode, zt as TransformBoxAction } from "./index-BlfZbeEJ.js";
3
+ import { $ as ResolvedPaint, $t as DEFAULT_RULER_OVERLAP_THRESHOLD, A as TransformBoxHover, At as cornerRadiusLayoutGroups, B as Modifiers, Bt as TransformBoxCorners, C as MIN_CHROME_VISIBLE_SIZE, Ct as DEFAULT_CORNER_RADIUS_HANDLE_SIZE, D as VectorHover, Dt as cornerRadiusAnchorSign, E as RenderShape, Et as computeCornerRadiusLayout, F as TapHandler, Ft as SurfaceGesture, G as lassoToHUDDraw, Gt as getTransformBoxCorners, H as PointerButton, Ht as compose, I as TapOutcome, It as SelectionGroup, J as snapGuideToHUDDraw, Jt as DEFAULT_RULER_ACCENT_COLOR, K as marqueeToHUDDraw, Kt as reduceTransformBox, L as Intent, Lt as SelectionShape, M as PaddingHover, Mt as resolveCenterDragAnchor, N as PaddingOverlayInput, Nt as resolveCornerDragAnchor, O as VectorSubSelection, Ot as cornerRadiusHandlePosLine, P as HUDStyle, Pt as Rect, Q as DEFAULT_STRIPES_THICKNESS_PX, Qt as DEFAULT_RULER_FONT, R as IntentPhase, Rt as AffineTransform, S as HitShape, St as DEFAULT_CORNER_RADIUS_HANDLE_INSET, T as OverlayElement, Tt as DrawCornerRadiusParams, U as SurfaceEvent, Ut as cornersToBoxTransform, V as NO_MODS, Vt as TransformBoxOptions, W as SurfaceResponse, Wt as decompose, X as DEFAULT_STRIPES_ANGLE_DEG, Xt as DEFAULT_RULER_COLOR, Y as filterHUDDrawByGroup, Yt as DEFAULT_RULER_BACKGROUND, Z as DEFAULT_STRIPES_SPACING_PX, Zt as DEFAULT_RULER_DRAG_THRESHOLD, _ as PADDING_HANDLE_PRIORITY, _t as resolveParametricHandleByDirection, a as SurfaceVisibilityPolicy, an as RulerAxis, at as DEFAULT_PARAMETRIC_HANDLE_INSET, b as VectorOverlay, bt as CornerRadiusInput, c as VectorSelectionMode, cn as RulerRange, ct as DrawParametricHandlesParams, d as TRANSFORM_BOX_CORNER_HIT_SIZE, dn as DEFAULT_PIXEL_GRID_STEPS, dt as ParametricHandleInput, en as DEFAULT_RULER_STEPS, et as buildStripesTile, f as TRANSFORM_BOX_CORNER_PRIORITY, fn as DrawPixelGridParams, ft as ParametricHandleLayout, g as PADDING_HANDLE_LENGTH, gt as projectParametricHandleValue, h as buildPaddingOverlay, ht as parametricHandleLayoutGroups, i as SurfaceVisibilityContext, in as DrawRulerParams, it as HUDCanvasOptions, j as TransformBoxInput, jt as drawCornerRadius, k as TransformBoxActiveOp, kt as cornerRadiusHandlePosRect, l as buildTransformBox, ln as drawRuler, lt as ParametricHandle, m as TRANSFORM_BOX_SIDE_PRIORITY, mn as drawPixelGrid, mt as drawParametricHandles, n as SurfaceOptions, nn as DEFAULT_RULER_TEXT_SIDE_OFFSET, nt as resolvePaint, o as VectorBendMode, on as RulerConfig, ot as DEFAULT_PARAMETRIC_HANDLE_SIZE, p as TRANSFORM_BOX_SIDE_HIT_THICKNESS, pn as PixelGridConfig, pt as computeParametricHandleLayout, q as measurementToHUDDraw, qt as DEFAULT_RULER_ACCENT_BACKGROUND, r as SurfaceVisibility, rn as DEFAULT_RULER_TICK_HEIGHT, rt as HUDCanvas, s as VectorInsertionMode, sn as RulerMark, st as DEFAULT_PARAMETRIC_HIT_SIZE, t as Surface, tn as DEFAULT_RULER_STRIP, tt as computeStripesTileGeometry, u as TRANSFORM_BOX_BODY_PRIORITY, un as DEFAULT_PIXEL_GRID_COLOR, ut as ParametricHandleGroup, v as PADDING_HANDLE_THICKNESS, vt as CornerRadiusAnchor, w as MIN_HIT_SIZE, wt as DEFAULT_CORNER_RADIUS_HIT_SIZE, x as SurfaceChromeGroups, xt as CornerRadiusRectangular, y as PADDING_REGION_PRIORITY, yt as CornerRadiusHandleLayout, z as SelectMode, zt as TransformBoxAction } from "./index-KI1k5HJX.js";
4
4
 
5
5
  //#region event/selection-controls.d.ts
6
6
  declare const HUDHitPriority: {
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_surface = require("./surface-BHDH6P6p.js");
2
+ const require_surface = require("./surface-pUdCqwPj.js");
3
3
  const require_cursor = require("./cursor-FGiJBdU-.js");
4
4
  exports.BODY_FLIP_THRESHOLD = require_surface.BODY_FLIP_THRESHOLD;
5
5
  exports.DEFAULT_CORNER_RADIUS_HANDLE_INSET = require_surface.DEFAULT_CORNER_RADIUS_HANDLE_INSET;
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { $ as DEFAULT_RULER_BACKGROUND, A as filterHUDDrawByGroup, B as drawCornerRadius, C as PADDING_REGION_PRIORITY, D as marqueeToHUDDraw, E as lassoToHUDDraw, F as computeCornerRadiusLayout, G as DEFAULT_PARAMETRIC_HIT_SIZE, H as resolveCornerDragAnchor, I as cornerRadiusAnchorSign, J as parametricHandleLayoutGroups, K as computeParametricHandleLayout, L as cornerRadiusHandlePosLine, M as DEFAULT_CORNER_RADIUS_HANDLE_INSET, N as DEFAULT_CORNER_RADIUS_HANDLE_SIZE, O as measurementToHUDDraw, P as DEFAULT_CORNER_RADIUS_HIT_SIZE, Q as DEFAULT_RULER_ACCENT_COLOR, R as cornerRadiusHandlePosRect, S as PADDING_HANDLE_THICKNESS, T as MIN_HIT_SIZE, U as DEFAULT_PARAMETRIC_HANDLE_INSET, V as resolveCenterDragAnchor, W as DEFAULT_PARAMETRIC_HANDLE_SIZE, X as resolveParametricHandleByDirection, Y as projectParametricHandleValue, Z as DEFAULT_RULER_ACCENT_BACKGROUND, _ as getTransformBoxCorners, _t as resolvePaint, a as computeSelectionControlLayout, at as DEFAULT_RULER_STRIP, b as PADDING_HANDLE_LENGTH, c as buildTransformBox, ct as drawRuler, d as TRANSFORM_BOX_CORNER_PRIORITY, dt as drawPixelGrid, et as DEFAULT_RULER_COLOR, f as TRANSFORM_BOX_SIDE_HIT_THICKNESS, ft as DEFAULT_STRIPES_ANGLE_DEG, g as decompose, gt as computeStripesTileGeometry, h as cornersToBoxTransform, ht as buildStripesTile, i as MIN_GUARANTEED_INTERACTIVE_DIM, it as DEFAULT_RULER_STEPS, j as HUDCanvas, k as snapGuideToHUDDraw, l as TRANSFORM_BOX_BODY_PRIORITY, lt as DEFAULT_PIXEL_GRID_COLOR, m as compose, mt as DEFAULT_STRIPES_THICKNESS_PX, n as BODY_FLIP_THRESHOLD, nt as DEFAULT_RULER_FONT, o as negotiateAxis, ot as DEFAULT_RULER_TEXT_SIDE_OFFSET, p as TRANSFORM_BOX_SIDE_PRIORITY, pt as DEFAULT_STRIPES_SPACING_PX, q as drawParametricHandles, r as HUDHitPriority, rt as DEFAULT_RULER_OVERLAP_THRESHOLD, s as NO_MODS, st as DEFAULT_RULER_TICK_HEIGHT, t as Surface, tt as DEFAULT_RULER_DRAG_THRESHOLD, u as TRANSFORM_BOX_CORNER_HIT_SIZE, ut as DEFAULT_PIXEL_GRID_STEPS, v as reduceTransformBox, w as MIN_CHROME_VISIBLE_SIZE, x as PADDING_HANDLE_PRIORITY, y as buildPaddingOverlay, z as cornerRadiusLayoutGroups } from "./surface-B_8w6VWG.mjs";
1
+ import { $ as DEFAULT_RULER_BACKGROUND, A as filterHUDDrawByGroup, B as drawCornerRadius, C as PADDING_REGION_PRIORITY, D as marqueeToHUDDraw, E as lassoToHUDDraw, F as computeCornerRadiusLayout, G as DEFAULT_PARAMETRIC_HIT_SIZE, H as resolveCornerDragAnchor, I as cornerRadiusAnchorSign, J as parametricHandleLayoutGroups, K as computeParametricHandleLayout, L as cornerRadiusHandlePosLine, M as DEFAULT_CORNER_RADIUS_HANDLE_INSET, N as DEFAULT_CORNER_RADIUS_HANDLE_SIZE, O as measurementToHUDDraw, P as DEFAULT_CORNER_RADIUS_HIT_SIZE, Q as DEFAULT_RULER_ACCENT_COLOR, R as cornerRadiusHandlePosRect, S as PADDING_HANDLE_THICKNESS, T as MIN_HIT_SIZE, U as DEFAULT_PARAMETRIC_HANDLE_INSET, V as resolveCenterDragAnchor, W as DEFAULT_PARAMETRIC_HANDLE_SIZE, X as resolveParametricHandleByDirection, Y as projectParametricHandleValue, Z as DEFAULT_RULER_ACCENT_BACKGROUND, _ as getTransformBoxCorners, _t as resolvePaint, a as computeSelectionControlLayout, at as DEFAULT_RULER_STRIP, b as PADDING_HANDLE_LENGTH, c as buildTransformBox, ct as drawRuler, d as TRANSFORM_BOX_CORNER_PRIORITY, dt as drawPixelGrid, et as DEFAULT_RULER_COLOR, f as TRANSFORM_BOX_SIDE_HIT_THICKNESS, ft as DEFAULT_STRIPES_ANGLE_DEG, g as decompose, gt as computeStripesTileGeometry, h as cornersToBoxTransform, ht as buildStripesTile, i as MIN_GUARANTEED_INTERACTIVE_DIM, it as DEFAULT_RULER_STEPS, j as HUDCanvas, k as snapGuideToHUDDraw, l as TRANSFORM_BOX_BODY_PRIORITY, lt as DEFAULT_PIXEL_GRID_COLOR, m as compose, mt as DEFAULT_STRIPES_THICKNESS_PX, n as BODY_FLIP_THRESHOLD, nt as DEFAULT_RULER_FONT, o as negotiateAxis, ot as DEFAULT_RULER_TEXT_SIDE_OFFSET, p as TRANSFORM_BOX_SIDE_PRIORITY, pt as DEFAULT_STRIPES_SPACING_PX, q as drawParametricHandles, r as HUDHitPriority, rt as DEFAULT_RULER_OVERLAP_THRESHOLD, s as NO_MODS, st as DEFAULT_RULER_TICK_HEIGHT, t as Surface, tt as DEFAULT_RULER_DRAG_THRESHOLD, u as TRANSFORM_BOX_CORNER_HIT_SIZE, ut as DEFAULT_PIXEL_GRID_STEPS, v as reduceTransformBox, w as MIN_CHROME_VISIBLE_SIZE, x as PADDING_HANDLE_PRIORITY, y as buildPaddingOverlay, z as cornerRadiusLayoutGroups } from "./surface-Dh43cAhb.mjs";
2
2
  import { i as cursorToCss, r as cursorEquals } from "./cursor-DW-uAPVE.mjs";
3
3
  export { BODY_FLIP_THRESHOLD, DEFAULT_CORNER_RADIUS_HANDLE_INSET, DEFAULT_CORNER_RADIUS_HANDLE_SIZE, DEFAULT_CORNER_RADIUS_HIT_SIZE, DEFAULT_PARAMETRIC_HANDLE_INSET, DEFAULT_PARAMETRIC_HANDLE_SIZE, DEFAULT_PARAMETRIC_HIT_SIZE, DEFAULT_PIXEL_GRID_COLOR, DEFAULT_PIXEL_GRID_STEPS, DEFAULT_RULER_ACCENT_BACKGROUND, DEFAULT_RULER_ACCENT_COLOR, DEFAULT_RULER_BACKGROUND, DEFAULT_RULER_COLOR, DEFAULT_RULER_DRAG_THRESHOLD, DEFAULT_RULER_FONT, DEFAULT_RULER_OVERLAP_THRESHOLD, DEFAULT_RULER_STEPS, DEFAULT_RULER_STRIP, DEFAULT_RULER_TEXT_SIDE_OFFSET, DEFAULT_RULER_TICK_HEIGHT, DEFAULT_STRIPES_ANGLE_DEG, DEFAULT_STRIPES_SPACING_PX, DEFAULT_STRIPES_THICKNESS_PX, HUDCanvas, HUDHitPriority, MIN_CHROME_VISIBLE_SIZE, MIN_GUARANTEED_INTERACTIVE_DIM, MIN_HIT_SIZE, NO_MODS, PADDING_HANDLE_LENGTH, PADDING_HANDLE_PRIORITY, PADDING_HANDLE_THICKNESS, PADDING_REGION_PRIORITY, Surface, TRANSFORM_BOX_BODY_PRIORITY, TRANSFORM_BOX_CORNER_HIT_SIZE, TRANSFORM_BOX_CORNER_PRIORITY, TRANSFORM_BOX_SIDE_HIT_THICKNESS, TRANSFORM_BOX_SIDE_PRIORITY, buildPaddingOverlay, buildStripesTile, buildTransformBox, compose as composeTransformBox, computeCornerRadiusLayout, computeParametricHandleLayout, computeSelectionControlLayout, computeStripesTileGeometry, cornerRadiusAnchorSign, cornerRadiusHandlePosLine, cornerRadiusHandlePosRect, cornerRadiusLayoutGroups, cornersToBoxTransform, cursorEquals, cursorToCss, decompose as decomposeTransformBox, drawCornerRadius, drawParametricHandles, drawPixelGrid, drawRuler, filterHUDDrawByGroup, getTransformBoxCorners, lassoToHUDDraw, marqueeToHUDDraw, measurementToHUDDraw, negotiateAxis, parametricHandleLayoutGroups, projectParametricHandleValue, reduceTransformBox, resolveCenterDragAnchor, resolveCornerDragAnchor, resolvePaint, resolveParametricHandleByDirection, snapGuideToHUDDraw };
package/dist/react.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as HUDDraw } from "./types-3wwFisZs.mjs";
2
- import { n as SurfaceOptions, t as Surface } from "./index-BQtDtpHM.mjs";
2
+ import { n as SurfaceOptions, t as Surface } from "./index-DHVvd2ak.mjs";
3
3
  import cmath from "@grida/cmath";
4
4
  import { Measurement } from "@grida/cmath/_measurement";
5
5
  import * as React from "react";
package/dist/react.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as HUDDraw } from "./types-3wwFisZs.js";
2
- import { n as SurfaceOptions, t as Surface } from "./index-BlfZbeEJ.js";
2
+ import { n as SurfaceOptions, t as Surface } from "./index-KI1k5HJX.js";
3
3
  import cmath from "@grida/cmath";
4
4
  import { SnapResult } from "@grida/cmath/_snap";
5
5
  import { Measurement } from "@grida/cmath/_measurement";
package/dist/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const require_surface = require("./surface-BHDH6P6p.js");
3
+ const require_surface = require("./surface-pUdCqwPj.js");
4
4
  let react = require("react");
5
5
  react = require_surface.__toESM(react);
6
6
  let _grida_cmath__snap = require("@grida/cmath/_snap");
package/dist/react.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { D as marqueeToHUDDraw, E as lassoToHUDDraw, O as measurementToHUDDraw, j as HUDCanvas, k as snapGuideToHUDDraw, t as Surface } from "./surface-B_8w6VWG.mjs";
2
+ import { D as marqueeToHUDDraw, E as lassoToHUDDraw, O as measurementToHUDDraw, j as HUDCanvas, k as snapGuideToHUDDraw, t as Surface } from "./surface-Dh43cAhb.mjs";
3
3
  import * as React from "react";
4
4
  import { guide } from "@grida/cmath/_snap";
5
5
  import { jsx } from "react/jsx-runtime";
@@ -2695,10 +2695,11 @@ function rectFromPoints(a, b) {
2695
2695
  * No constraints: width/height can go negative — host is responsible for
2696
2696
  * normalizing if it cares (most callers clamp to a min-size).
2697
2697
  */
2698
- function applyResize(initial, direction, dx, dy) {
2698
+ function applyResize(initial, direction, dx, dy, opts) {
2699
+ const fromCenter = opts?.fromCenter ?? false;
2699
2700
  if (initial.kind === "rect") return {
2700
2701
  kind: "rect",
2701
- rect: applyResizeRect(initial.rect, direction, dx, dy)
2702
+ rect: applyResizeRect(initial.rect, direction, dx, dy, fromCenter)
2702
2703
  };
2703
2704
  if (initial.kind === "transformed") {
2704
2705
  const m = initial.matrix;
@@ -2715,49 +2716,42 @@ function applyResize(initial, direction, dx, dy) {
2715
2716
  const [ldx, ldy] = cmath.vector2.transform([dx, dy], inv_linear);
2716
2717
  return {
2717
2718
  kind: "transformed",
2718
- local: applyResizeRect(initial.local, direction, ldx, ldy),
2719
+ local: applyResizeRect(initial.local, direction, ldx, ldy, fromCenter),
2719
2720
  matrix: m
2720
2721
  };
2721
2722
  }
2722
2723
  return initial;
2723
2724
  }
2724
- function applyResizeRect(initial, direction, dx, dy) {
2725
+ /**
2726
+ * Resize a rect by dragging `direction`'s edge/corner by `(dx, dy)`.
2727
+ *
2728
+ * Default anchors the OPPOSITE edge/corner (far side pinned). With
2729
+ * `fromCenter` (Alt), the resize is symmetric about the rect's center:
2730
+ * the dragged edge moves by the delta and the opposite edge mirrors it,
2731
+ * so the size delta doubles and the center stays put.
2732
+ */
2733
+ function applyResizeRect(initial, direction, dx, dy, fromCenter = false) {
2725
2734
  let { x, y, width, height } = initial;
2726
- switch (direction) {
2727
- case "n":
2728
- y += dy;
2729
- height -= dy;
2730
- break;
2731
- case "s":
2732
- height += dy;
2733
- break;
2734
- case "e":
2735
- width += dx;
2736
- break;
2737
- case "w":
2738
- x += dx;
2739
- width -= dx;
2740
- break;
2741
- case "ne":
2742
- y += dy;
2743
- height -= dy;
2744
- width += dx;
2745
- break;
2746
- case "nw":
2747
- y += dy;
2748
- height -= dy;
2749
- x += dx;
2750
- width -= dx;
2751
- break;
2752
- case "se":
2753
- width += dx;
2754
- height += dy;
2755
- break;
2756
- case "sw":
2757
- x += dx;
2758
- width -= dx;
2759
- height += dy;
2760
- break;
2735
+ const k = fromCenter ? 2 : 1;
2736
+ const hasN = direction === "n" || direction === "ne" || direction === "nw";
2737
+ const hasS = direction === "s" || direction === "se" || direction === "sw";
2738
+ const hasE = direction === "e" || direction === "ne" || direction === "se";
2739
+ const hasW = direction === "w" || direction === "nw" || direction === "sw";
2740
+ if (hasE) {
2741
+ width += k * dx;
2742
+ if (fromCenter) x -= dx;
2743
+ }
2744
+ if (hasW) {
2745
+ x += dx;
2746
+ width -= k * dx;
2747
+ }
2748
+ if (hasS) {
2749
+ height += k * dy;
2750
+ if (fromCenter) y -= dy;
2751
+ }
2752
+ if (hasN) {
2753
+ y += dy;
2754
+ height -= k * dy;
2761
2755
  }
2762
2756
  return {
2763
2757
  x,
@@ -2908,6 +2902,7 @@ var HitRegions = class {
2908
2902
  */
2909
2903
  function classifyScenario(input) {
2910
2904
  const { ui_action, hovered_id, selection_ids, modifiers, click_count, readonly, in_content_edit, sub_selection } = input;
2905
+ const meta_marquee = modifiers.meta && !in_content_edit && click_count < 2;
2911
2906
  if (in_content_edit && click_count >= 2) {
2912
2907
  if (!(ui_action && (ui_action.kind === "vertex_handle" || ui_action.kind === "tangent_handle" || ui_action.kind === "segment_strip" || ui_action.kind === "ghost_handle" || ui_action.kind === "region"))) return "ExitEdit";
2913
2908
  }
@@ -2936,10 +2931,14 @@ function classifyScenario(input) {
2936
2931
  case "select_node": {
2937
2932
  const id = ui_action.id;
2938
2933
  if (click_count >= 2) return "EnterEdit";
2934
+ if (meta_marquee) return "MetaSelectOrMarquee";
2939
2935
  return classifyContent(id, selection_ids, modifiers);
2940
2936
  }
2941
- case "translate_handle": return classifyBodyRegion(hovered_id, selection_ids, modifiers, click_count);
2937
+ case "translate_handle":
2938
+ if (meta_marquee) return contentId(ui_action, hovered_id) ? "MetaSelectOrMarquee" : "MetaMarquee";
2939
+ return classifyBodyRegion(hovered_id, selection_ids, modifiers, click_count);
2942
2940
  }
2941
+ if (meta_marquee) return hovered_id ? "MetaSelectOrMarquee" : "MetaMarquee";
2943
2942
  if (hovered_id) {
2944
2943
  if (click_count >= 2) return "EnterEdit";
2945
2944
  return classifyContent(hovered_id, selection_ids, modifiers);
@@ -3284,10 +3283,22 @@ function dispatch(scenario, input) {
3284
3283
  emit_on_down: "clear_vector_selection"
3285
3284
  };
3286
3285
  case "EmptyMarquee":
3287
- case "EmptyAdditiveMarquee": return {
3286
+ case "EmptyAdditiveMarquee":
3287
+ case "MetaMarquee": return {
3288
3288
  kind: "start_marquee_pend",
3289
3289
  emit_on_down: "none"
3290
3290
  };
3291
+ case "MetaSelectOrMarquee": return {
3292
+ kind: "pend",
3293
+ pending: {
3294
+ ids_at_down: [],
3295
+ deferred: {
3296
+ kind: "select",
3297
+ node_id: contentId(ui_action, hovered_id),
3298
+ shift: modifiers.shift
3299
+ }
3300
+ }
3301
+ };
3291
3302
  }
3292
3303
  }
3293
3304
  /** Resolve the id that the user clicked on for content-class scenarios. */
@@ -3739,9 +3750,11 @@ var SurfaceState = class {
3739
3750
  const dx = point_doc[0] - g.anchor_doc[0];
3740
3751
  const dy = point_doc[1] - g.anchor_doc[1];
3741
3752
  const next_shape = applyResize(g.initial_shape, g.direction, dx, dy);
3753
+ const preview_shape = this.modifiers.alt ? applyResize(g.initial_shape, g.direction, dx, dy, { fromCenter: true }) : next_shape;
3742
3754
  this.gesture = {
3743
3755
  ...g,
3744
- current_shape: next_shape
3756
+ current_shape: next_shape,
3757
+ preview_shape
3745
3758
  };
3746
3759
  deps.emitIntent({
3747
3760
  kind: "resize",
@@ -4210,7 +4223,8 @@ var SurfaceState = class {
4210
4223
  direction: decision.direction,
4211
4224
  initial_shape: decision.initial_shape,
4212
4225
  anchor_doc: point_doc,
4213
- current_shape: decision.initial_shape
4226
+ current_shape: decision.initial_shape,
4227
+ preview_shape: decision.initial_shape
4214
4228
  };
4215
4229
  response.needsRedraw = true;
4216
4230
  return response;
@@ -5445,7 +5459,7 @@ function buildChrome(input) {
5445
5459
  });
5446
5460
  }
5447
5461
  if (state.gesture.kind === "resize") {
5448
- const shape = state.gesture.current_shape;
5462
+ const shape = state.gesture.preview_shape;
5449
5463
  if (shape.kind === "transformed") {
5450
5464
  const corners = cmath.rect.toCorners(shape.local).map((p) => cmath.vector2.transform(p, shape.matrix));
5451
5465
  decoration_polylines.push({
@@ -2718,10 +2718,11 @@ function rectFromPoints(a, b) {
2718
2718
  * No constraints: width/height can go negative — host is responsible for
2719
2719
  * normalizing if it cares (most callers clamp to a min-size).
2720
2720
  */
2721
- function applyResize(initial, direction, dx, dy) {
2721
+ function applyResize(initial, direction, dx, dy, opts) {
2722
+ const fromCenter = opts?.fromCenter ?? false;
2722
2723
  if (initial.kind === "rect") return {
2723
2724
  kind: "rect",
2724
- rect: applyResizeRect(initial.rect, direction, dx, dy)
2725
+ rect: applyResizeRect(initial.rect, direction, dx, dy, fromCenter)
2725
2726
  };
2726
2727
  if (initial.kind === "transformed") {
2727
2728
  const m = initial.matrix;
@@ -2738,49 +2739,42 @@ function applyResize(initial, direction, dx, dy) {
2738
2739
  const [ldx, ldy] = _grida_cmath.default.vector2.transform([dx, dy], inv_linear);
2739
2740
  return {
2740
2741
  kind: "transformed",
2741
- local: applyResizeRect(initial.local, direction, ldx, ldy),
2742
+ local: applyResizeRect(initial.local, direction, ldx, ldy, fromCenter),
2742
2743
  matrix: m
2743
2744
  };
2744
2745
  }
2745
2746
  return initial;
2746
2747
  }
2747
- function applyResizeRect(initial, direction, dx, dy) {
2748
+ /**
2749
+ * Resize a rect by dragging `direction`'s edge/corner by `(dx, dy)`.
2750
+ *
2751
+ * Default anchors the OPPOSITE edge/corner (far side pinned). With
2752
+ * `fromCenter` (Alt), the resize is symmetric about the rect's center:
2753
+ * the dragged edge moves by the delta and the opposite edge mirrors it,
2754
+ * so the size delta doubles and the center stays put.
2755
+ */
2756
+ function applyResizeRect(initial, direction, dx, dy, fromCenter = false) {
2748
2757
  let { x, y, width, height } = initial;
2749
- switch (direction) {
2750
- case "n":
2751
- y += dy;
2752
- height -= dy;
2753
- break;
2754
- case "s":
2755
- height += dy;
2756
- break;
2757
- case "e":
2758
- width += dx;
2759
- break;
2760
- case "w":
2761
- x += dx;
2762
- width -= dx;
2763
- break;
2764
- case "ne":
2765
- y += dy;
2766
- height -= dy;
2767
- width += dx;
2768
- break;
2769
- case "nw":
2770
- y += dy;
2771
- height -= dy;
2772
- x += dx;
2773
- width -= dx;
2774
- break;
2775
- case "se":
2776
- width += dx;
2777
- height += dy;
2778
- break;
2779
- case "sw":
2780
- x += dx;
2781
- width -= dx;
2782
- height += dy;
2783
- break;
2758
+ const k = fromCenter ? 2 : 1;
2759
+ const hasN = direction === "n" || direction === "ne" || direction === "nw";
2760
+ const hasS = direction === "s" || direction === "se" || direction === "sw";
2761
+ const hasE = direction === "e" || direction === "ne" || direction === "se";
2762
+ const hasW = direction === "w" || direction === "nw" || direction === "sw";
2763
+ if (hasE) {
2764
+ width += k * dx;
2765
+ if (fromCenter) x -= dx;
2766
+ }
2767
+ if (hasW) {
2768
+ x += dx;
2769
+ width -= k * dx;
2770
+ }
2771
+ if (hasS) {
2772
+ height += k * dy;
2773
+ if (fromCenter) y -= dy;
2774
+ }
2775
+ if (hasN) {
2776
+ y += dy;
2777
+ height -= k * dy;
2784
2778
  }
2785
2779
  return {
2786
2780
  x,
@@ -2931,6 +2925,7 @@ var HitRegions = class {
2931
2925
  */
2932
2926
  function classifyScenario(input) {
2933
2927
  const { ui_action, hovered_id, selection_ids, modifiers, click_count, readonly, in_content_edit, sub_selection } = input;
2928
+ const meta_marquee = modifiers.meta && !in_content_edit && click_count < 2;
2934
2929
  if (in_content_edit && click_count >= 2) {
2935
2930
  if (!(ui_action && (ui_action.kind === "vertex_handle" || ui_action.kind === "tangent_handle" || ui_action.kind === "segment_strip" || ui_action.kind === "ghost_handle" || ui_action.kind === "region"))) return "ExitEdit";
2936
2931
  }
@@ -2959,10 +2954,14 @@ function classifyScenario(input) {
2959
2954
  case "select_node": {
2960
2955
  const id = ui_action.id;
2961
2956
  if (click_count >= 2) return "EnterEdit";
2957
+ if (meta_marquee) return "MetaSelectOrMarquee";
2962
2958
  return classifyContent(id, selection_ids, modifiers);
2963
2959
  }
2964
- case "translate_handle": return classifyBodyRegion(hovered_id, selection_ids, modifiers, click_count);
2960
+ case "translate_handle":
2961
+ if (meta_marquee) return contentId(ui_action, hovered_id) ? "MetaSelectOrMarquee" : "MetaMarquee";
2962
+ return classifyBodyRegion(hovered_id, selection_ids, modifiers, click_count);
2965
2963
  }
2964
+ if (meta_marquee) return hovered_id ? "MetaSelectOrMarquee" : "MetaMarquee";
2966
2965
  if (hovered_id) {
2967
2966
  if (click_count >= 2) return "EnterEdit";
2968
2967
  return classifyContent(hovered_id, selection_ids, modifiers);
@@ -3307,10 +3306,22 @@ function dispatch(scenario, input) {
3307
3306
  emit_on_down: "clear_vector_selection"
3308
3307
  };
3309
3308
  case "EmptyMarquee":
3310
- case "EmptyAdditiveMarquee": return {
3309
+ case "EmptyAdditiveMarquee":
3310
+ case "MetaMarquee": return {
3311
3311
  kind: "start_marquee_pend",
3312
3312
  emit_on_down: "none"
3313
3313
  };
3314
+ case "MetaSelectOrMarquee": return {
3315
+ kind: "pend",
3316
+ pending: {
3317
+ ids_at_down: [],
3318
+ deferred: {
3319
+ kind: "select",
3320
+ node_id: contentId(ui_action, hovered_id),
3321
+ shift: modifiers.shift
3322
+ }
3323
+ }
3324
+ };
3314
3325
  }
3315
3326
  }
3316
3327
  /** Resolve the id that the user clicked on for content-class scenarios. */
@@ -3762,9 +3773,11 @@ var SurfaceState = class {
3762
3773
  const dx = point_doc[0] - g.anchor_doc[0];
3763
3774
  const dy = point_doc[1] - g.anchor_doc[1];
3764
3775
  const next_shape = applyResize(g.initial_shape, g.direction, dx, dy);
3776
+ const preview_shape = this.modifiers.alt ? applyResize(g.initial_shape, g.direction, dx, dy, { fromCenter: true }) : next_shape;
3765
3777
  this.gesture = {
3766
3778
  ...g,
3767
- current_shape: next_shape
3779
+ current_shape: next_shape,
3780
+ preview_shape
3768
3781
  };
3769
3782
  deps.emitIntent({
3770
3783
  kind: "resize",
@@ -4233,7 +4246,8 @@ var SurfaceState = class {
4233
4246
  direction: decision.direction,
4234
4247
  initial_shape: decision.initial_shape,
4235
4248
  anchor_doc: point_doc,
4236
- current_shape: decision.initial_shape
4249
+ current_shape: decision.initial_shape,
4250
+ preview_shape: decision.initial_shape
4237
4251
  };
4238
4252
  response.needsRedraw = true;
4239
4253
  return response;
@@ -5468,7 +5482,7 @@ function buildChrome(input) {
5468
5482
  });
5469
5483
  }
5470
5484
  if (state.gesture.kind === "resize") {
5471
- const shape = state.gesture.current_shape;
5485
+ const shape = state.gesture.preview_shape;
5472
5486
  if (shape.kind === "transformed") {
5473
5487
  const corners = _grida_cmath.default.rect.toCorners(shape.local).map((p) => _grida_cmath.default.vector2.transform(p, shape.matrix));
5474
5488
  decoration_polylines.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grida/hud",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "private": false,
5
5
  "description": "Canvas-based heads-up display for the Grida editor viewport",
6
6
  "keywords": [