@grida/hud 0.2.3 → 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-D-Kt_jKx.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-DFo9q3y7.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-D-Kt_jKx.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-DFo9q3y7.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,
@@ -3756,9 +3750,11 @@ var SurfaceState = class {
3756
3750
  const dx = point_doc[0] - g.anchor_doc[0];
3757
3751
  const dy = point_doc[1] - g.anchor_doc[1];
3758
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;
3759
3754
  this.gesture = {
3760
3755
  ...g,
3761
- current_shape: next_shape
3756
+ current_shape: next_shape,
3757
+ preview_shape
3762
3758
  };
3763
3759
  deps.emitIntent({
3764
3760
  kind: "resize",
@@ -4227,7 +4223,8 @@ var SurfaceState = class {
4227
4223
  direction: decision.direction,
4228
4224
  initial_shape: decision.initial_shape,
4229
4225
  anchor_doc: point_doc,
4230
- current_shape: decision.initial_shape
4226
+ current_shape: decision.initial_shape,
4227
+ preview_shape: decision.initial_shape
4231
4228
  };
4232
4229
  response.needsRedraw = true;
4233
4230
  return response;
@@ -5462,7 +5459,7 @@ function buildChrome(input) {
5462
5459
  });
5463
5460
  }
5464
5461
  if (state.gesture.kind === "resize") {
5465
- const shape = state.gesture.current_shape;
5462
+ const shape = state.gesture.preview_shape;
5466
5463
  if (shape.kind === "transformed") {
5467
5464
  const corners = cmath.rect.toCorners(shape.local).map((p) => cmath.vector2.transform(p, shape.matrix));
5468
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,
@@ -3779,9 +3773,11 @@ var SurfaceState = class {
3779
3773
  const dx = point_doc[0] - g.anchor_doc[0];
3780
3774
  const dy = point_doc[1] - g.anchor_doc[1];
3781
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;
3782
3777
  this.gesture = {
3783
3778
  ...g,
3784
- current_shape: next_shape
3779
+ current_shape: next_shape,
3780
+ preview_shape
3785
3781
  };
3786
3782
  deps.emitIntent({
3787
3783
  kind: "resize",
@@ -4250,7 +4246,8 @@ var SurfaceState = class {
4250
4246
  direction: decision.direction,
4251
4247
  initial_shape: decision.initial_shape,
4252
4248
  anchor_doc: point_doc,
4253
- current_shape: decision.initial_shape
4249
+ current_shape: decision.initial_shape,
4250
+ preview_shape: decision.initial_shape
4254
4251
  };
4255
4252
  response.needsRedraw = true;
4256
4253
  return response;
@@ -5485,7 +5482,7 @@ function buildChrome(input) {
5485
5482
  });
5486
5483
  }
5487
5484
  if (state.gesture.kind === "resize") {
5488
- const shape = state.gesture.current_shape;
5485
+ const shape = state.gesture.preview_shape;
5489
5486
  if (shape.kind === "transformed") {
5490
5487
  const corners = _grida_cmath.default.rect.toCorners(shape.local).map((p) => _grida_cmath.default.vector2.transform(p, shape.matrix));
5491
5488
  decoration_polylines.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grida/hud",
3
- "version": "0.2.3",
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": [