@weasel-js/core 1.4.4 → 1.5.0
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.
- package/CHANGELOG.md +937 -2202
- package/README.md +118 -75
- package/dist/{autoPoseDescriptor-DF1SnnSx.d.ts → autoPoseDescriptor-CvjflWJK.d.ts} +29 -26
- package/dist/{chunk-2VXGHUVL.js → chunk-BDWAA634.js} +4 -22
- package/dist/chunk-BDWAA634.js.map +1 -0
- package/dist/{chunk-R3AWPTLZ.js → chunk-MG7OXCAI.js} +2760 -4491
- package/dist/chunk-MG7OXCAI.js.map +1 -0
- package/dist/{chunk-PRGBGMH3.js → chunk-MQI4PIX3.js} +3 -3
- package/dist/chunk-MQI4PIX3.js.map +1 -0
- package/dist/{chunk-WPM42WJP.js → chunk-UCPV7JXC.js} +201 -256
- package/dist/chunk-UCPV7JXC.js.map +1 -0
- package/dist/clipboard.d.ts +2 -3
- package/dist/clone.d.ts +3 -2
- package/dist/depSchema-nMqj_qTM.d.ts +3490 -0
- package/dist/{grid-0Pbn5B2C.d.ts → grid-BrIa38gG.d.ts} +7 -10
- package/dist/index.d.ts +1996 -1229
- package/dist/index.js +4 -5
- package/dist/insert.d.ts +4 -4
- package/dist/insert.js +1 -1
- package/dist/move.d.ts +5 -6
- package/dist/move.js +3 -6
- package/dist/move.js.map +1 -1
- package/dist/{options-DbYLImvq.d.ts → options-BDyCnrp8.d.ts} +3 -2
- package/dist/poseDescriptor-CGOgIgf8.d.ts +134 -0
- package/dist/renderer.d.ts +10 -4
- package/dist/renderer.js +4 -5
- package/dist/resize.d.ts +10 -12
- package/dist/resize.js +2 -2
- package/dist/routing.d.ts +1 -142
- package/dist/routing.js +1 -1
- package/dist/routing.js.map +1 -1
- package/dist/{types-ei3UMl9R.d.ts → types-DMyo7dnM.d.ts} +12 -41
- package/dist/{types-DEALFt5F.d.ts → types-DtjCJA5r.d.ts} +9 -3
- package/package.json +13 -10
- package/dist/DrawCommand-CD-ug3d9.d.ts +0 -332
- package/dist/builtins-BXFBXegF.d.ts +0 -840
- package/dist/chunk-2VXGHUVL.js.map +0 -1
- package/dist/chunk-BL65SHCX.js +0 -573
- package/dist/chunk-BL65SHCX.js.map +0 -1
- package/dist/chunk-PRGBGMH3.js.map +0 -1
- package/dist/chunk-R3AWPTLZ.js.map +0 -1
- package/dist/chunk-WPM42WJP.js.map +0 -1
- package/dist/geometry-6fCNhAux.d.ts +0 -114
- package/dist/path-JEV2c5If.d.ts +0 -48
- package/dist/registry-BY-wI9gm.d.ts +0 -4003
- package/dist/types-BHK2dkMu.d.ts +0 -172
- package/dist/types-bcc7jcUy.d.ts +0 -594
- package/dist/view-DSQgxBJB.d.ts +0 -63
package/dist/index.d.ts
CHANGED
|
@@ -1,48 +1,40 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
2
|
import React__default, { RefObject, ReactNode, Ref, MouseEvent, ComponentType, MutableRefObject } from 'react';
|
|
3
|
-
import { a as
|
|
4
|
-
export {
|
|
5
|
-
import {
|
|
6
|
-
export {
|
|
7
|
-
import {
|
|
8
|
-
export { a1 as ALWAYS, a2 as ActionDeps, a3 as ActionDisabledReason, a4 as ActionEnabledResult, a5 as ActionEntry, a6 as ActionsProvider, a7 as ActionsScope, a8 as ActiveToolContextProvider, a9 as ActiveToolContextProviderIfRoot, aa as ActiveToolContextProviderProps, ab as ActiveToolContextValue, ac as AnimateToBoundsOptions, ad as AreaSelectDep, ae as BezierEasing, af as BindingOpts, ag as BooleanOp, ah as BooleanOpResult, ai as BoundGesture, aj as BuildRuleCtxArgs, ak as ClaimableGesture, al as ClipboardDep, am as ClipboardIngestCtx, an as ColorOverride, ao as ColorOverrideFn, ap as CustomPaintContext, aq as DecayLoopConfig, ar as DecayOptions, as as DepName, at as DepRegistry, au as DepRegistryProvider, av as DispatcherContext, aw as DragSample, ax as EASINGS, ay as EasingFn, az as EasingName, aA as EditAnchorsDep, aB as EventTrack, aC as GestureBinding, aD as IDENTITY_POSE_COMPOSITION, aE as ImmediateInvoker, aF as IngestCtx, aG as IngestionDep, aH as InsertDep, aI as Interpolate, aJ as InterpolatorFactory, aK as InvocationCtx, aL as Invoker, aM as KIT_SHAPE_KINDS, aN as Keyframe, aO as LassoSelectDep, aP as LayerCommandCache, aQ as LayerDrawFailure, aR as LayoutDep, aS as LoopFactory, aT as LoopOptions, aU as MatchResult, aV as NEVER, aW as NestedTimeline, aX as NodeAtPointDep, aY as OngoingHandle, aZ as OngoingInvoker, a_ as PhysicsHandle, a$ as PhysicsOptions, b0 as Point2, b1 as PointerContextProvider, b2 as PointerContextValue, b3 as PointerWorldPos, b4 as PoseAdapter, b5 as PoseComposition, b6 as ResizePolicy, b7 as ResolveAllOptions, b8 as ResolveOnlyResult, b9 as ResolvedCandidate, ba as SPRING_PRESETS, bb as SelectionExtendKey, bc as SelectionMode, bd as Selector, be as SnapDep, bf as SpringOptions, bg as SpringPreset, bh as StaggerBuilder, bi as StaggerDelay, bj as StaggerFactory, bk as StaggerOptions, bl as StaggerPerItem, bm as StaggerSpringPoseOptions, bn as StaggerTweenOptions, bo as SvgUnpacker, bp as TextEditDep, bq as TimelineHandle, br as TimelineOptions, bs as TimelineTrack, bt as ToolCtx, bu as ToolModifiers, bv as ToolPresentation, bw as ToolSlot, bx as Track, by as TweenLoopOptions, bz as TweenOptions, bA as UiOngoingControl, bB as VIEW_ANIMATION_KEY, bC as ViewAnimationApi, bD as ViewApi, bE as ViewChannel, bF as actionBindings, bG as applyBooleanOp, bH as buildRuleCtx, bI as clipboardCopyAction, bJ as clipboardCutAction, bK as composeRectPose, bL as composeWorldPose, bM as createDispatcher, bN as cubicBezierEasing, bO as decomposeRectPose, bP as describeRule, bQ as drawLayers, bR as drawOneLayer, bS as easeIn, bT as easeInBack, bU as easeInBounce, bV as easeInCirc, bW as easeInCubic, bX as easeInElastic, bY as easeInExpo, bZ as easeInOut, b_ as easeInOutBack, b$ as easeInOutBounce, c0 as easeInOutCirc, c1 as easeInOutCubic, c2 as easeInOutElastic, c3 as easeInOutExpo, c4 as easeInOutQuad, c5 as easeInOutQuart, c6 as easeInOutQuint, c7 as easeInOutSine, c8 as easeInQuad, c9 as easeInQuart, ca as easeInQuint, cb as easeInSine, cc as easeOut, cd as easeOutBack, ce as easeOutBounce, cf as easeOutCirc, cg as easeOutCubic, ch as easeOutElastic, ci as easeOutExpo, cj as easeOutQuad, ck as easeOutQuart, cl as easeOutQuint, cm as easeOutSine, cn as enterTextEditAction, co as evaluate, cp as evaluateEnabled, cq as isLayerPainted, cr as isLayerVisible, cs as linear, ct as rebaseLocalPose, cu as registerContentHandler, cv as resolveEasing, cw as resolveParams, cx as sliceAction, cy as specificity, cz as translateRectPose, cA as useAction, cB as useActionsRegistry, cC as useActiveToolContext, cD as useDecayLoop, cE as useDepRegistry, cF as useDepSource, cG as useOptionalActiveToolContext, cH as useOptionalDepRegistry, cI as usePointerContext, cJ as useSelection, cK as useViewAnimation, cL as worldPoseLookup } from './registry-BY-wI9gm.js';
|
|
9
|
-
import { Stroke, FillStyle, TextureHandle, TilePatternSpec, GradientKind, GradStop, GradientFill, GradientUnits, MarkerKey, MarkerRef } from '@weasel-js/paint';
|
|
3
|
+
import { a as UnitValue, b as UnitSystem, c as Unit, U as UseMoveOptions, O as OriginProjection } from './grid-BrIa38gG.js';
|
|
4
|
+
export { A as ANGLE_RADIANS, I as IMPERIAL_INCHES, M as METRIC_MM, P as PIXELS, R as RECT_ORIGIN_PROJECTION, f as formatUnit, g as gridSnapStrategy, p as pointToGridCell, r as resolveUnit } from './grid-BrIa38gG.js';
|
|
5
|
+
import { View, NodeId, Bounds, ModifierState, PointerSessionCancelReason, DeviceProfile, Action, SelectionMode, SelectionExtendKey, SelectionApi, DepSchema, AnyToolOf, Contribution as Contribution$1, ContributionChrome as ContributionChrome$1, Tool as Tool$1, ToolDef as ToolDef$1, ViewportToolDef as ViewportToolDef$1, HitShape, HandleKind, DebugSink, ToolKeybinding, HotkeyTrigger, RuleCtx, Rule, IngestItem, OngoingOverlay, ActionsProp, OverlayRole, ResizeAnchor } from '@weasel-js/routing';
|
|
6
|
+
export { ALWAYS, Action, ActionDeps, ActionDisabledReason, ActionDispatch, ActionEnabledResult, ActionEntry, ActionPresentation, ActionsProp, ActionsRegistry, AffordanceHit, BindingOpts, BindingScope, BindingSource, BoundGesture, Bounds, BuildRuleCtxArgs, COARSE_TARGET_SCALE, ContributionRouting, DEFAULT_ALLOWED_CAPABILITIES, DEFAULT_DEVICE_PROFILE, DebugSink, DepName, DepSchema, DetectedDeviceFacts, DeviceProfile, Dispatcher, DispatcherContext, DragSample, Eligibility, EligibilityState, GestureBinding, HandleKind, HitShape, HotkeyTrigger, ImmediateInvoker, IngestItem, InputEvent, InvocationCtx, Invoker, MatchResult, ModifierState, NEVER, NodeId, OngoingHandle, OngoingInvoker, OngoingOverlay, OverlayPosition, OverlayRole, Point2, PointerSession, PointerSessionCallbacks, PointerSessionCancelReason, PointerSessionOptions, ResizeAnchor, ResolveAllOptions, ResolveOnlyResult, ResolvedCandidate, Rule, RuleCtx, ScopedBinding, ScratchKey, ScratchStore, SelectionApi, SelectionExtendKey, SelectionMode, Selector, ToolCtx, ToolKeybinding, ToolModifiers, ToolPresentation, ToolSlot, UiOngoingControl, View, actionBindings, buildRuleCtx, clientToCanvas, createDispatcher, deleteScratch, describeRule, evaluate, evaluateEnabled, getScratch, isEditableTarget, liveScope, matchesKeyBinding, mergeContributions, openPointerSession, resolveDeviceProfile, resolveParams, scopeBindings, scratchKey, setScratch, specificity } from '@weasel-js/routing';
|
|
7
|
+
import { FillStyle, Stroke, TextureHandle, TilePatternSpec, GradientKind, GradStop, GradientFill, GradientUnits, MarkerKey, MarkerRef } from '@weasel-js/paint';
|
|
10
8
|
export { FillStyle, GradStop, GradientFill, GradientKind, GradientUnits, KitMarkerKey, MarkerKey, MarkerRef, Region, STROKE_DASH_RATIOS, Stroke, StrokeAlign, StrokeDashStyle, TextureHandle, TilePatternSpec, alignedStrokeRect, dashForStrokeStyle, strokeDashStyleOf } from '@weasel-js/paint';
|
|
11
|
-
import {
|
|
12
|
-
export {
|
|
13
|
-
import {
|
|
14
|
-
export {
|
|
15
|
-
import {
|
|
16
|
-
export { ClickSpec, DragSpec, DropSpec, GestureSpec,
|
|
17
|
-
import {
|
|
18
|
-
export {
|
|
19
|
-
import {
|
|
20
|
-
export { A as
|
|
21
|
-
import {
|
|
22
|
-
export {
|
|
23
|
-
import {
|
|
24
|
-
export { g as
|
|
25
|
-
import {
|
|
26
|
-
export {
|
|
27
|
-
import { a as PolygonPath, P as Path, b as PathFillRule, R as RectPath } from './path-JEV2c5If.js';
|
|
9
|
+
import { D as DrawCommand, E as Effect, u as Scene, w as RectPose, x as InertiaConfig, y as ViewAnimationOptions, N as Node$1, z as PoseComposition, A as SliceDep, B as VertexColorChannel, f as ShaderProgramHandle, C as InsertExtras, F as SerializedScene, H as GeometryProjection, J as ContentHandlerEntry, K as SvgIngestOptions, L as PanBounds, O as Animator, Q as ColorOverrideRegistry, U as UseSceneOptions, X as SceneRegistry, Y as RegisteredOp, Z as PoseOverrides, _ as DerivedDep, $ as ViewportDims, P as PathDrawCommand, T as TextDrawCommand, a0 as ShaderProgram, c as Mat3$1, a1 as BooleansAdapter, a2 as UseAnimatorOptions, a3 as SpringPresetName, a4 as EasingSpec, a5 as AnimationHandle, a6 as SampledTrack } from './depSchema-nMqj_qTM.js';
|
|
10
|
+
export { a7 as AddLayerSpec, a8 as AddNodeSpec, a9 as AnimateToBoundsOptions, aa as AreaSelectDep, ab as BezierEasing, ac as BooleanOp, ad as BooleanOpResult, ae as ClipboardDep, af as ClipboardIngestCtx, ag as ColorOverride, ah as ColorOverrideFn, ai as ContainerNode, aj as DecayLoopConfig, ak as DecayOptions, al as EASINGS, am as EasingFn, an as EasingName, ao as EditAnchorsDep, ap as EventBooking, aq as EventBookingHandle, ar as EventTrack, as as FitViewToBoundsOptions, G as GroupDrawCommand, at as IDENTITY_POSE_COMPOSITION, a as ImageDrawCommand, b as ImageMinification, au as IngestCtx, av as IngestionDep, aw as InsertDep, ax as Interpolate, ay as InterpolatorFactory, az as Keyframe, aA as LassoSelectDep, aB as LayerRecord, aC as LayoutDep, aD as LeafNode, aE as LoopFactory, aF as LoopOptions, aG as NestedTimeline, aH as NodeAtPointDep, aI as PhysicsHandle, aJ as PhysicsOptions, aK as PointerContextProvider, aL as PointerContextValue, aM as PointerWorldPos, aN as PoseAdapter, aO as PoseClosure, aP as PoseOverride, aQ as RECT_POSE_COMPOSITION, aR as RIGID_POSE_COMPOSITION, R as RenderTarget, aS as ResizePolicy, aT as SPRING_PRESETS, S as SPRITE_STRIDE, aU as SerializedNode, e as ShaderDrawCommand, g as ShaderUniform, aV as SnapDep, aW as SpringOptions, aX as SpringPreset, i as SpriteSheet, j as SpritesDrawCommand, aY as StaggerBuilder, aZ as StaggerDelay, a_ as StaggerFactory, a$ as StaggerOptions, b0 as StaggerPerItem, b1 as StaggerSpringPoseOptions, b2 as StaggerTweenOptions, b3 as SvgUnpacker, b4 as SystemLayerRecord, b5 as SystemLayerSpec, b6 as TextEditDep, b7 as TimelineClock, b8 as TimelineEvent, b9 as TimelineHandle, ba as TimelineOptions, bb as TimelineTrack, bc as Track, bd as TweenLoopOptions, be as TweenOptions, bf as UserLayerRecord, bg as VIEW_ANIMATION_KEY, bh as ViewAnimationApi, bi as ViewApi, bj as ViewChannel, bk as applyBooleanOp, bl as asNodeId, m as blur, bm as composeRectPose, bn as composeRigidPose, bo as composeWorldPose, bp as cubicBezierEasing, bq as decomposeRectPose, br as decomposeRigidPose, bs as easeIn, bt as easeInBack, bu as easeInBounce, bv as easeInCirc, bw as easeInCubic, bx as easeInElastic, by as easeInExpo, bz as easeInOut, bA as easeInOutBack, bB as easeInOutBounce, bC as easeInOutCirc, bD as easeInOutCubic, bE as easeInOutElastic, bF as easeInOutExpo, bG as easeInOutQuad, bH as easeInOutQuart, bI as easeInOutQuint, bJ as easeInOutSine, bK as easeInQuad, bL as easeInQuart, bM as easeInQuint, bN as easeInSine, bO as easeOut, bP as easeOutBack, bQ as easeOutBounce, bR as easeOutCirc, bS as easeOutCubic, bT as easeOutElastic, bU as easeOutExpo, bV as easeOutQuad, bW as easeOutQuart, bX as easeOutQuint, bY as easeOutSine, bZ as fitViewToBounds, o as frameRect, b_ as linear, p as mat3, b$ as rebaseLocalPose, c0 as registerContentHandler, r as registerEffect, c1 as resolveEasing, c2 as resolveStrokeWidth, c3 as translateRectPose, c4 as useDecayLoop, c5 as usePointerContext, c6 as useViewAnimation, v as viewToMat3, s as vignette, c7 as worldPoseLookup } from './depSchema-nMqj_qTM.js';
|
|
11
|
+
import { CursorSpec, PaintedCursorState } from '@weasel-js/cursor';
|
|
12
|
+
export { BakeOptions, CursorGlyph, CursorGlyphName, CursorGlyphSpec, CursorSpec, PaintedCursor, PaintedCursorFrame, PaintedCursorState, ResolvedCursor, bakeCursor, createPaintedCursorState, cursorFor, resolveCursor, resolveCursorTier } from '@weasel-js/cursor';
|
|
13
|
+
import { ClaimableGesture, GestureSpec } from '@weasel-js/gestures';
|
|
14
|
+
export { ClaimableGesture, ClickSpec, DragSpec, DropSpec, GestureSpec, KeyHeldSpec, KeySpec, ModSpec, MultiTouchSpec, PasteSpec, TargetSpec, WheelSpec } from '@weasel-js/gestures';
|
|
15
|
+
import { ToolsApi as ToolsApi$1, UseToolsOptions as UseToolsOptions$1 } from '@weasel-js/routing/react';
|
|
16
|
+
export { ActionsProvider, ActionsScope, ActiveToolContextProvider, ActiveToolContextProviderIfRoot, ActiveToolContextProviderProps, ActiveToolContextValue, DepRegistry, DepRegistryProvider, UseGestureDispatcherOptions, useAction, useActionsRegistry, useActiveToolContext, useDepRegistry, useDepSource, useGestureDispatcher, useOptionalActiveToolContext, useOptionalDepRegistry } from '@weasel-js/routing/react';
|
|
17
|
+
import { B as BoundsConstraint, P as PointSnapBehavior, L as LassoSelectBehavior, R as RotateBehavior, S as SnapStrategy, M as MoveBehavior, I as InsertBehavior } from './types-DMyo7dnM.js';
|
|
18
|
+
export { A as ActionBehavior, b as AreaSelectOverlay, c as BehaviorMoveResult, d as BehaviorResult, C as CloneBehavior, e as CloneLayer, f as ClonePose, G as GestureContext, g as GroupTransform, h as InsertMoveResult, i as InsertOverlay, j as InsertPoint, k as InsertProposed, l as LassoSelectMoveResult, m as LassoSelectOverlay, n as LassoSelectPose, o as LassoSelectProposed, p as PointSnapContext, a as PointSnapFrame, q as PointSnapResult, r as PointerState, s as ResizeMoveResult, t as ResizeOverlay, u as ResizeProposed, v as RotateMoveResult, w as RotateOverlay, x as RotateProposed } from './types-DMyo7dnM.js';
|
|
19
|
+
import { P as PoseDescriptor, c as PolygonPath, a as Path, d as RotatedPose, e as PathFillRule, f as RectPath } from './poseDescriptor-CGOgIgf8.js';
|
|
20
|
+
export { R as RECT_POSE_DESCRIPTOR, b as ROTATED_POSE_DESCRIPTOR, p as poseDescriptorForNode, t as translatePoseViaDescriptor, v as visualBoundsViaDescriptor } from './poseDescriptor-CGOgIgf8.js';
|
|
21
|
+
import { U as UseResizeOptions } from './autoPoseDescriptor-CvjflWJK.js';
|
|
22
|
+
export { A as AUTO_POSE_DESCRIPTOR, C as CORNER_ANCHORS, a as CornerAnchor, g as CornerEdge, b as CornerHandle, c as cornerPoint, d as cornerResizeHandles, h as hitCornerHandle, i as isPathLike, e as isRectPose, p as pointSnapToGrid } from './autoPoseDescriptor-CvjflWJK.js';
|
|
23
|
+
import { M as MoveAdapter, A as AreaSelectAdapter, R as RotateAdapter, b as LassoHitMode, c as LassoSelectAdapter, d as ResizeAdapter, L as LayoutStrategy, e as LayerEnumerableAdapter, I as InsertAdapter, C as ClipboardSnapshot, O as OrderedAdapter, a as SceneAdapter, f as LayoutSnap } from './types-DtjCJA5r.js';
|
|
24
|
+
export { g as ContainerBounds, D as DropTarget, h as LayoutChild, i as LayoutContainer, j as LayoutDragged, S as SnapTarget } from './types-DtjCJA5r.js';
|
|
28
25
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
29
|
-
import { D as DrawCommand, b as ShaderProgramHandle, P as PathDrawCommand, M as Mat3$1 } from './DrawCommand-CD-ug3d9.js';
|
|
30
|
-
export { E as Effect, G as GroupDrawCommand, I as ImageDrawCommand, S as SPRITE_STRIDE, a as ShaderDrawCommand, c as ShaderUniform, e as SpritesDrawCommand, T as TextDrawCommand, m as mat3, r as registerEffect } from './DrawCommand-CD-ug3d9.js';
|
|
31
26
|
import { Op, HistorySelection, CreateHistoryOptions, History } from '@weasel-js/history';
|
|
32
27
|
export * from '@weasel-js/history';
|
|
33
28
|
export { Op } from '@weasel-js/history';
|
|
34
29
|
import { PlacementAlign, Rect, Mat3 } from '@weasel-js/geom';
|
|
35
|
-
export { PATH_C, PATH_CMD_LENGTHS, PATH_L, PATH_M, PATH_Q, PATH_Z, Rect, pathCommandCoordCount } from '@weasel-js/geom';
|
|
30
|
+
export { DEFAULT_FLATTEN_TOLERANCE, PATH_C, PATH_CMD_LENGTHS, PATH_L, PATH_M, PATH_Q, PATH_Z, Rect, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, pathCommandCoordCount } from '@weasel-js/geom';
|
|
36
31
|
import { TextRenderer, TextPose, StyledRun, TextStyle, TextPaint, TextVerticalAlign } from '@weasel-js/text';
|
|
37
|
-
export { DEFAULT_TEXT_STYLE, LaidOutDecoration, LaidOutGroup, LaidOutLineBox, LaidOutOutlineGlyph, LaidOutQuad, LaidOutRuns, LayoutLine, LayoutResult, LayoutRunsOpts, MARKDOWN_RUN_GRAMMAR, MarkdownFontOptions, MeasureFn, MeasureTextBoundsOpts, MeasuredText, PositionedRun, ResolvedRun, ResolvedTextStyle, RunFlag, RunGrammar, RunMarker, SCRIPT_METRICS, StyledRun, TextAlign, TextDirection, TextLineBoxesOpts, TextPaint, TextPose, TextRenderer, TextStyle, TextVerticalAlign, cachedLayoutRuns, createMarkdownRenderer, fontString, layoutMarkdown, layoutRuns, markdownToRuns, measureText, measureTextBounds, measuredWidth, resolveAlign, resolveRuns, resolveTextStyle, runsToMarkdown, runsToPlainText, textLineBoxes, toRuns, verticalAlignOffset } from '@weasel-js/text';
|
|
38
|
-
import { i as ShaderProgram } from './builtins-BXFBXegF.js';
|
|
39
|
-
export { a as ImageMinification, R as RenderTarget, b as SpriteSheet, e as blur, g as frameRect, r as resolveStrokeWidth, v as viewToMat3, h as vignette } from './builtins-BXFBXegF.js';
|
|
32
|
+
export { DEFAULT_TEXT_STYLE, LaidOutDecoration, LaidOutGroup, LaidOutLineBox, LaidOutOutlineGlyph, LaidOutQuad, LaidOutRuns, LayoutLine, LayoutResult, LayoutRunsOpts, MARKDOWN_RUN_GRAMMAR, MarkdownFontOptions, MeasureFn, MeasureTextBoundsOpts, MeasuredText, PositionedRun, ResolvedRun, ResolvedTextStyle, RunFlag, RunGrammar, RunMarker, SCRIPT_METRICS, StyledRun, TextAlign, TextDirection, TextLineBoxesOpts, TextPaint, TextPose, TextPoseLayout, TextPoseLayoutInput, TextRenderer, TextStyle, TextVerticalAlign, cachedLayoutRuns, createMarkdownRenderer, fontString, layoutMarkdown, layoutRuns, layoutTextPose, markdownToRuns, measureText, measureTextBounds, measuredWidth, resolveAlign, resolveRuns, resolveTextStyle, runsToMarkdown, runsToPlainText, textLineBoxes, textPoseLayoutInput, toRuns, verticalAlignOffset } from '@weasel-js/text';
|
|
40
33
|
import { G as Guide } from './types-D2tTKEU0.js';
|
|
41
|
-
export { U as UseInsertOptions } from './options-
|
|
34
|
+
export { U as UseInsertOptions } from './options-BDyCnrp8.js';
|
|
42
35
|
export { UseClipboardOpsOptions, UseClipboardOpsReturn, WEASEL_CLIPBOARD_MIME, WEASEL_CLIPBOARD_MIME_WEB, buildWeaselClipboardText, embedWeaselMetadataInSvg, extractWeaselClipboardFromSvg, parseWeaselClipboardText, sniffWeaselClipboardText, useClipboardOps } from './clipboard.js';
|
|
43
36
|
export { cloneByAltDrag } from './clone.js';
|
|
44
37
|
export { FontVariant, LocalFontOutlinesResult, OutlineFontStyle, OutlineSource, OutlineStatus, OutlineVariant, canQueryLocalFonts, enableLocalFontOutlines, hasFontOutlines, isCanvasFont, listFontOutlines, outlineStatus, registerCanvasFont, registerFont, registerFontOutlines, subscribeGlyphReady, unregisterCanvasFont, unregisterFontOutlines } from '@weasel-js/font';
|
|
45
|
-
import { CapabilityTag } from '@weasel-js/modes';
|
|
46
38
|
|
|
47
39
|
/**
|
|
48
40
|
* The kit version a build was compiled from, so an app can report what it is
|
|
@@ -67,6 +59,20 @@ declare const VERSION: string;
|
|
|
67
59
|
/** Round `value` to the nearest multiple of `cellSize`. Returns 0 when the result would be -0. */
|
|
68
60
|
declare function roundToCell(value: number, cellSize: number): number;
|
|
69
61
|
|
|
62
|
+
/** Pan offset (in pixels) plus per-axis zoom (pixels per content unit). */
|
|
63
|
+
interface ViewTransform {
|
|
64
|
+
panX: number;
|
|
65
|
+
panY: number;
|
|
66
|
+
zoom: {
|
|
67
|
+
x: number;
|
|
68
|
+
y: number;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Project a world-space point to screen-space pixels through a `ViewTransform`. */
|
|
72
|
+
declare function worldToScreen(worldX: number, worldY: number, view: ViewTransform): [number, number];
|
|
73
|
+
/** Inverse of `worldToScreen` — recover the world-space point under a screen-space pixel. */
|
|
74
|
+
declare function screenToWorld(screenX: number, screenY: number, view: ViewTransform): [number, number];
|
|
75
|
+
|
|
70
76
|
/**
|
|
71
77
|
* Pointer-tracking glue that turns hover position into a grid cell, suitable
|
|
72
78
|
* for dropping straight into `createCellHighlightLayer({ getCell })`. Pairs
|
|
@@ -125,6 +131,524 @@ interface UseGridCellHoverReturn {
|
|
|
125
131
|
/** Track which grid cell the pointer is over; pairs with `createCellHighlightLayer`. */
|
|
126
132
|
declare function useGridCellHover(opts: UseGridCellHoverOptions): UseGridCellHoverReturn;
|
|
127
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Input convenience for zoom primitives. A `number` is treated as a
|
|
136
|
+
* uniform factor applied to both axes; a `{x, y}` vector applies
|
|
137
|
+
* per-axis factors.
|
|
138
|
+
*/
|
|
139
|
+
type ZoomFactor = number | {
|
|
140
|
+
x: number;
|
|
141
|
+
y: number;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Input convenience for zoom-clamp ranges. A `number` is applied as the
|
|
145
|
+
* same bound on both axes; a `{x, y}` vector applies per-axis bounds.
|
|
146
|
+
*/
|
|
147
|
+
type ZoomBound = number | {
|
|
148
|
+
x: number;
|
|
149
|
+
y: number;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Bridge `View` into the legacy `ViewTransform` shape so chrome can keep
|
|
153
|
+
* calling `worldToScreen` / `screenToWorld`. `View` and `ViewTransform`
|
|
154
|
+
* use opposite sign conventions for the translation half (`view.x` is
|
|
155
|
+
* camera position; `panX` is canvas translation), so the adapter flips
|
|
156
|
+
* the sign and multiplies by per-axis scale.
|
|
157
|
+
*/
|
|
158
|
+
declare function viewToTransform(view: View): ViewTransform;
|
|
159
|
+
/**
|
|
160
|
+
* How far `view` is zoomed in, as one number — the geometric mean of its two
|
|
161
|
+
* axes, so a uniform view reports its own scale and a stretched one reports
|
|
162
|
+
* the scale that covers the same area.
|
|
163
|
+
*
|
|
164
|
+
* What a `RuleCtx` carries, because the only rule that asks about the
|
|
165
|
+
* viewport asks for a threshold rather than a camera.
|
|
166
|
+
*/
|
|
167
|
+
declare function viewZoom(view: View): number;
|
|
168
|
+
/**
|
|
169
|
+
* `view` inside the invariant {@link View} documents: a zero or non-finite
|
|
170
|
+
* scale axis becomes `ZOOM_FLOOR`, a negative one keeps its sign, and a
|
|
171
|
+
* non-finite translation becomes 0. Returns `view` itself when it already
|
|
172
|
+
* holds, so a valid view keeps its identity.
|
|
173
|
+
*/
|
|
174
|
+
declare function normalizeView(view: View): View;
|
|
175
|
+
|
|
176
|
+
interface ChromeState {
|
|
177
|
+
/** Currently selected ids. Live; reflects useSelection's React state. */
|
|
178
|
+
readonly selection: readonly NodeId[];
|
|
179
|
+
/** True when the canvas is in multi-mode AND >= 2 ids are selected. */
|
|
180
|
+
readonly multiActive: boolean;
|
|
181
|
+
/** Bounds for any selection member id. Honors active-tool overlay state
|
|
182
|
+
* (move/resize/rotate ghosts → ghost bounds; otherwise → committed
|
|
183
|
+
* pose bounds). Returns null for unknown ids or ids whose bounds aren't
|
|
184
|
+
* computable. */
|
|
185
|
+
boundsOf(id: string): Bounds | null;
|
|
186
|
+
/** Multi-union AABB when `multiActive`. Computed lazily from `boundsOf`
|
|
187
|
+
* over every selected id, expanding rotated members to the extent of
|
|
188
|
+
* their ink; null otherwise. */
|
|
189
|
+
readonly unionBounds: Bounds | null;
|
|
190
|
+
/** Active modifier state at the moment of the call. */
|
|
191
|
+
readonly modifiers: ModifierState;
|
|
192
|
+
/** True iff the node's pose-descriptor declares it can carry a rotation.
|
|
193
|
+
* Affordances consult this to decide whether to expose rotate cursors /
|
|
194
|
+
* drag-bands. Defaults to `true` when the descriptor doesn't declare
|
|
195
|
+
* (back-compat) or when the id is unknown — the rotation gesture will
|
|
196
|
+
* no-op visually for poses without AABB fields, but the affordance
|
|
197
|
+
* doesn't lie about the cursor. Optional on the interface so unit-test
|
|
198
|
+
* call sites that construct `ChromeState` by hand keep compiling;
|
|
199
|
+
* affordances should treat an absent predicate as "true". */
|
|
200
|
+
canRotate?(id: string): boolean;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @experimental
|
|
205
|
+
* A single interactive piece of chrome. Pure functions; the kit composes
|
|
206
|
+
* multiple affordances into a single RenderLayer per tool via
|
|
207
|
+
* `composeAffordanceLayer`.
|
|
208
|
+
*
|
|
209
|
+
* Affordances declare interactive regions in a target's *local* frame.
|
|
210
|
+
* The framework (`composeAffordanceLayer`) composes the target's bounds
|
|
211
|
+
* transform (rotation around the AABB center, when present) for both paint
|
|
212
|
+
* and hit-test, so the affordance never touches rotation, view.scale, or
|
|
213
|
+
* world↔screen math.
|
|
214
|
+
*/
|
|
215
|
+
interface Affordance {
|
|
216
|
+
/** Stable id for debug overlays + visibility maps. */
|
|
217
|
+
id: string;
|
|
218
|
+
/** Enumerate this affordance's interactive regions. Each region lives in
|
|
219
|
+
* some target id's local frame (or in the world frame when `targetId`
|
|
220
|
+
* is `null`). Returning `[]` means "no chrome for this state" (no
|
|
221
|
+
* selection, multi-mode disabled, etc.). */
|
|
222
|
+
regions(state: ChromeState): readonly AffordanceRegion[];
|
|
223
|
+
/** Optional non-interactive decoration (e.g., a leader line drawn from
|
|
224
|
+
* a bounds edge to a handle — visual only, not draggable). Receives
|
|
225
|
+
* raw state + view because the decoration may live outside any single
|
|
226
|
+
* target's local frame. Most affordances leave this undefined. */
|
|
227
|
+
decorate?(state: ChromeState, view: View): DrawCommand[];
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* @experimental
|
|
231
|
+
* One interactive region produced by an affordance. The framework owns
|
|
232
|
+
* the local↔world transform for `targetId` (when non-null), so `shape`,
|
|
233
|
+
* `paint.sizePx`, and `hitRadiusPx` are always specified in coordinates
|
|
234
|
+
* the affordance can reason about directly.
|
|
235
|
+
*/
|
|
236
|
+
interface AffordanceRegion<TScratch = unknown> {
|
|
237
|
+
/** Stable id, e.g. `corner-min-min`. Used for debug overlays + a11y. */
|
|
238
|
+
id: string;
|
|
239
|
+
/** Target id whose `state.boundsOf(targetId)` defines this region's
|
|
240
|
+
* local frame. `bounds.rotation` (if present) is the only transform
|
|
241
|
+
* applied — translation is the AABB origin; scale is identity. Pass
|
|
242
|
+
* `null` for affordances anchored to the viewport / world frame
|
|
243
|
+
* (identity transform). */
|
|
244
|
+
targetId: string | null;
|
|
245
|
+
/** Region geometry, expressed in the target's local frame.
|
|
246
|
+
*
|
|
247
|
+
* - `point` — circular hit (`hitRadiusPx` is screen-space).
|
|
248
|
+
* - `rect` — axis-aligned rect (target rotation applies).
|
|
249
|
+
* - `annulus` — outer ellipse minus inner rect cutout. Used for
|
|
250
|
+
* invisible zones that sit *around* the AABB (e.g. rotate-on-
|
|
251
|
+
* hover band). The outer ellipse is defined by world-space
|
|
252
|
+
* semi-axes `rx` / `ry` around `(cx, cy)`; the inner rect is the
|
|
253
|
+
* same target-local rect that defines the AABB. Hit-test:
|
|
254
|
+
* inside outer ellipse AND outside inner rect. */
|
|
255
|
+
shape: {
|
|
256
|
+
kind: 'point';
|
|
257
|
+
x: number;
|
|
258
|
+
y: number;
|
|
259
|
+
hitRadiusPx: number;
|
|
260
|
+
} | {
|
|
261
|
+
kind: 'rect';
|
|
262
|
+
x: number;
|
|
263
|
+
y: number;
|
|
264
|
+
width: number;
|
|
265
|
+
height: number;
|
|
266
|
+
} | {
|
|
267
|
+
kind: 'annulus';
|
|
268
|
+
/** Outer-ellipse center (target-local). */
|
|
269
|
+
cx: number;
|
|
270
|
+
cy: number;
|
|
271
|
+
/** Outer-ellipse semi-axes (target-local). */
|
|
272
|
+
rx: number;
|
|
273
|
+
ry: number;
|
|
274
|
+
/** Inner rect (target-local) — the cutout. Typically the
|
|
275
|
+
* selection's AABB. */
|
|
276
|
+
innerX: number;
|
|
277
|
+
innerY: number;
|
|
278
|
+
innerWidth: number;
|
|
279
|
+
innerHeight: number;
|
|
280
|
+
/** Minimum band thickness outside the inner rect, in **screen**
|
|
281
|
+
* pixels. The framework widens `rx`/`ry` to at least
|
|
282
|
+
* `innerHalfExtent + minBandPx / meanScale(view.scale)` for both
|
|
283
|
+
* paint and hit-test.
|
|
284
|
+
*
|
|
285
|
+
* This exists because the clamp has to know the view and the
|
|
286
|
+
* affordance doesn't: `ChromeState` carries no scale. Expressing the
|
|
287
|
+
* floor in world units instead (which is what the rotate ring used
|
|
288
|
+
* to do) makes the band shrink on screen as you zoom in, until the
|
|
289
|
+
* ring around a small shape is too thin to hover. */
|
|
290
|
+
minBandPx?: number;
|
|
291
|
+
};
|
|
292
|
+
/** Optional paint. World position is derived from `shape` + target
|
|
293
|
+
* transform; visual size stays in screen pixels (so handles don't
|
|
294
|
+
* warp under zoom or non-uniform scale). Omit for hit-only regions.
|
|
295
|
+
*
|
|
296
|
+
* - `square` — small fixed-size square (only valid over `point` shapes).
|
|
297
|
+
* - `annulus` — fill + stroke the annulus ring (only valid over
|
|
298
|
+
* `annulus` shapes). Uses even-odd fill rule to punch the inner-rect
|
|
299
|
+
* cutout.
|
|
300
|
+
* - `custom` — emit arbitrary draw commands; receives a {@link CustomPaintContext}. */
|
|
301
|
+
paint?: {
|
|
302
|
+
kind: 'square';
|
|
303
|
+
sizePx: number;
|
|
304
|
+
fill?: FillStyle;
|
|
305
|
+
stroke?: Stroke;
|
|
306
|
+
} | {
|
|
307
|
+
kind: 'annulus';
|
|
308
|
+
fill?: FillStyle;
|
|
309
|
+
stroke?: Stroke;
|
|
310
|
+
insetPx?: number;
|
|
311
|
+
} | {
|
|
312
|
+
kind: 'custom';
|
|
313
|
+
draw: (ctx: CustomPaintContext) => DrawCommand[];
|
|
314
|
+
};
|
|
315
|
+
/** Discriminator a press on this region reports as `AffordanceHit.kind` —
|
|
316
|
+
* the string routing specs match on (`'handle:top-left'`,
|
|
317
|
+
* `'rotate-handle'`, `'anchor:3'`). Omit for regions that only exist
|
|
318
|
+
* inside a consumer-registered layer, where the layer id is the
|
|
319
|
+
* discriminator; `buildAffordanceAt` falls back to
|
|
320
|
+
* `<affordanceId>:<regionId>`. */
|
|
321
|
+
hitKind?: string;
|
|
322
|
+
/** Cursor to show while hovering this region. Read by the hover-cursor
|
|
323
|
+
* pump in `useGestureDispatcher` via `AffordanceHit.cursor`, which
|
|
324
|
+
* `buildAffordanceAt` fills in from the region the walk landed on. */
|
|
325
|
+
cursor?: CursorSpec;
|
|
326
|
+
/** `'exclusive'` bars every binding whose target doesn't consult the
|
|
327
|
+
* affordance. Read only when the affordance is composed into a
|
|
328
|
+
* consumer-registered layer; kit chrome routes through
|
|
329
|
+
* `buildAffordanceAt`, which reports `'shared'`. */
|
|
330
|
+
strength?: 'exclusive' | 'shared';
|
|
331
|
+
/** Which gestures an exclusive claim bars. Omitted bars all of them. */
|
|
332
|
+
claimedKinds?: readonly ClaimableGesture[];
|
|
333
|
+
/** Drag binding produced when this region is hit. Lazily called so
|
|
334
|
+
* affordances don't pay binding-construction cost on every paint frame —
|
|
335
|
+
* state snapshots (e.g., capturing per-leaf poses at click time) belong
|
|
336
|
+
* inside `bind()`, not inside `regions()`. */
|
|
337
|
+
bind(): AffordanceBinding<TScratch>;
|
|
338
|
+
}
|
|
339
|
+
/** Context passed to a region's `paint.kind === 'custom'` draw callback.
|
|
340
|
+
* Provides both the world-space anchor (already transformed) and the
|
|
341
|
+
* original local shape, for affordances that want to do additional
|
|
342
|
+
* geometry themselves. */
|
|
343
|
+
interface CustomPaintContext {
|
|
344
|
+
/** World-space mapping of `shape`. For `point`, only `x`/`y` are set.
|
|
345
|
+
* For `rect`, all four fields are set. */
|
|
346
|
+
world: {
|
|
347
|
+
x: number;
|
|
348
|
+
y: number;
|
|
349
|
+
width?: number;
|
|
350
|
+
height?: number;
|
|
351
|
+
};
|
|
352
|
+
/** The original local shape (same object identity as `region.shape`). */
|
|
353
|
+
local: AffordanceRegion['shape'];
|
|
354
|
+
view: View;
|
|
355
|
+
state: ChromeState;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* @experimental
|
|
359
|
+
* Result of an affordance hit — what the region computed about itself.
|
|
360
|
+
*
|
|
361
|
+
* `initialScratch` is the payload: what the region already knows (which
|
|
362
|
+
* corner, which target id) so the action that picks up the drag doesn't
|
|
363
|
+
* re-derive it. `<SceneCanvas>` reads it out of the layer hit-test and packs
|
|
364
|
+
* it into `AffordanceHit`, which flows to the matching action through
|
|
365
|
+
* `InvocationCtx.drag.affordance`.
|
|
366
|
+
*
|
|
367
|
+
* This used to also carry a `drag: DragChannel` naming the handlers the
|
|
368
|
+
* tool-routing dispatcher should wire up. Every implementation supplied a
|
|
369
|
+
* no-op stub that claimed, because the real routing had already moved to
|
|
370
|
+
* bindings; the field went with that dispatcher.
|
|
371
|
+
*/
|
|
372
|
+
interface AffordanceBinding<TScratch = unknown> {
|
|
373
|
+
initialScratch?: TScratch;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* The fields `buildAffordanceAt` lifts out of a region's `initialScratch`
|
|
377
|
+
* when it turns a region hit into an `AffordanceHit`.
|
|
378
|
+
*
|
|
379
|
+
* Scratch is otherwise opaque — whatever the affordance wants to hand the
|
|
380
|
+
* action that picks up the drag. These few names are the exception: they mean
|
|
381
|
+
* the same thing to every affordance, and the actions that consume them
|
|
382
|
+
* (`resizeAction`, `rotateAction`) read them off `AffordanceHit` rather than
|
|
383
|
+
* out of scratch. An affordance that doesn't set them simply produces a hit
|
|
384
|
+
* without those fields.
|
|
385
|
+
*/
|
|
386
|
+
interface CommonAffordanceScratch {
|
|
387
|
+
/** The node (or `MULTI_RESIZE_TARGET_ID`) this chrome acts on. Becomes
|
|
388
|
+
* `AffordanceHit.targetIds`. */
|
|
389
|
+
targetId?: string;
|
|
390
|
+
/** For resize chrome: which corner stays pinned. Mirrors the kit's
|
|
391
|
+
* `ResizeAnchor`, spelled inline so `affordances/` doesn't take a type
|
|
392
|
+
* dependency on the gesture layer for one field. */
|
|
393
|
+
anchor?: {
|
|
394
|
+
x: 'min' | 'max' | 'free';
|
|
395
|
+
y: 'min' | 'max' | 'free';
|
|
396
|
+
};
|
|
397
|
+
/** World-space invariant point of the transform — the fixed corner for a
|
|
398
|
+
* resize, the pivot for a rotation. */
|
|
399
|
+
fixedPoint?: {
|
|
400
|
+
x: number;
|
|
401
|
+
y: number;
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* What a **registered layer's** `hitTest` returns. Extends `AffordanceBinding`
|
|
406
|
+
* so existing implementations keep typechecking; the added fields are how a
|
|
407
|
+
* consumer's own chrome says the things kit chrome says through
|
|
408
|
+
* `AffordanceRegion` — which cursor to show, and whether it owns the point
|
|
409
|
+
* outright.
|
|
410
|
+
*/
|
|
411
|
+
interface LayerHit<TScratch = unknown> extends AffordanceBinding<TScratch> {
|
|
412
|
+
/** Cursor while the pointer is over this hit. Reaches the hover-cursor
|
|
413
|
+
* pump as `AffordanceHit.cursor`, the same path kit chrome uses. */
|
|
414
|
+
cursor?: CursorSpec;
|
|
415
|
+
/** `'exclusive'` bars every binding whose target doesn't consult the
|
|
416
|
+
* affordance. Omitted means `'shared'` — today's behavior. Same name and
|
|
417
|
+
* meaning as `AffordanceHit.strength`, which it becomes. */
|
|
418
|
+
strength?: 'exclusive' | 'shared';
|
|
419
|
+
/** Which gestures an exclusive claim bars. Omitted bars all of them. */
|
|
420
|
+
claimedKinds?: readonly ClaimableGesture[];
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Canvas size in CSS pixels — passed to `draw` for layers that anchor to
|
|
425
|
+
* canvas edges (e.g. the debug overlay's layer-list panel). The GL backend
|
|
426
|
+
* supplies it explicitly so layers don't have to know about DPR.
|
|
427
|
+
*/
|
|
428
|
+
interface Dims {
|
|
429
|
+
width: number;
|
|
430
|
+
height: number;
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* What a layer's `draw` threw, and which layer threw it.
|
|
434
|
+
*
|
|
435
|
+
* A `draw` runs on the frame loop, so a throw that escapes it surfaces as an
|
|
436
|
+
* uncaught `requestAnimationFrame` error on the window and takes the whole
|
|
437
|
+
* frame with it — every other layer included. One broken layer painting
|
|
438
|
+
* nothing, named in the console, is the lesser wrong.
|
|
439
|
+
*/
|
|
440
|
+
interface LayerDrawFailure {
|
|
441
|
+
layerId: string;
|
|
442
|
+
error: unknown;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Several consecutive layers composited as one.
|
|
446
|
+
*
|
|
447
|
+
* A layer's own `effects` run over that layer alone, which is the wrong
|
|
448
|
+
* picture whenever a pass reads neighboring pixels: `blur(A over B)` is not
|
|
449
|
+
* `blur(A) over blur(B)`, and it costs a buffer and a pass chain per layer. A
|
|
450
|
+
* group draws its members into one buffer, runs one chain over it, and
|
|
451
|
+
* composites the result back once.
|
|
452
|
+
*
|
|
453
|
+
* Membership is by `RenderLayer.id` — the same names `layerOrder` and
|
|
454
|
+
* `layerVisibility` use, not the `layers` map's slot keys.
|
|
455
|
+
*
|
|
456
|
+
* Only *consecutive* members share a buffer, because anything drawn between
|
|
457
|
+
* two members has to land between them. A group whose members are separated in
|
|
458
|
+
* the render order is drawn as one bracket per run, with a warning: the
|
|
459
|
+
* picture is right, the declaration almost certainly is not.
|
|
460
|
+
*
|
|
461
|
+
* This is a render-stack bracket, not a scene `ContainerNode` — it holds no
|
|
462
|
+
* ids, survives no reload, and nothing in the scene knows about it.
|
|
463
|
+
*/
|
|
464
|
+
interface LayerGroup {
|
|
465
|
+
/** Names the group in warnings; not a layer id and never drawn. */
|
|
466
|
+
id: string;
|
|
467
|
+
/** Member layer ids. Order here is ignored — the render order decides. */
|
|
468
|
+
layers: readonly string[];
|
|
469
|
+
/**
|
|
470
|
+
* Passes over the group's combined pixels, in order. A thunk is re-read on
|
|
471
|
+
* every frame, so an animating radius costs no React render; an array is
|
|
472
|
+
* read once per frame either way.
|
|
473
|
+
*/
|
|
474
|
+
effects?: readonly Effect[] | ((view: View, dims: Dims) => readonly Effect[]);
|
|
475
|
+
/** Opacity applied to the group's composited result, not to each member. */
|
|
476
|
+
alpha?: number;
|
|
477
|
+
/** 4×5 color matrix (row-major, 20 numbers) applied to the composited
|
|
478
|
+
* result. See `GroupDrawCommand.colorMatrix`. */
|
|
479
|
+
colorMatrix?: number[];
|
|
480
|
+
}
|
|
481
|
+
/** One layer's memoized output, keyed by layer id. Owned by the canvas that
|
|
482
|
+
* calls `drawLayers`, not by `drawLayers` itself — the function is pure. */
|
|
483
|
+
type LayerCommandCache = Map<string, {
|
|
484
|
+
deps: readonly unknown[];
|
|
485
|
+
cmds: DrawCommand[];
|
|
486
|
+
}>;
|
|
487
|
+
/**
|
|
488
|
+
* A single named render sub-layer within a canvas renderer.
|
|
489
|
+
*
|
|
490
|
+
* @template TData - The data object passed to each draw call.
|
|
491
|
+
*/
|
|
492
|
+
interface RenderLayer<TData> {
|
|
493
|
+
/** Unique identifier used in visibility maps and ordering arrays. When a
|
|
494
|
+
* cache is in use, an id must identify the same logical layer across
|
|
495
|
+
* frames — reusing it for a different layer can serve cross-layer commands. */
|
|
496
|
+
id: string;
|
|
497
|
+
/** Human-readable name for UI toggles. */
|
|
498
|
+
label: string;
|
|
499
|
+
/**
|
|
500
|
+
* Emit a DrawCommand tree for the GL backend to dispatch.
|
|
501
|
+
*
|
|
502
|
+
* For world-space layers (the default), emit commands in WORLD COORDS —
|
|
503
|
+
* `drawLayers` automatically wraps them in `{ kind: 'group', transform:
|
|
504
|
+
* viewToMat3(view), ... }` before handing them to the renderer. Do NOT
|
|
505
|
+
* apply the view transform yourself.
|
|
506
|
+
*
|
|
507
|
+
* For screen-space layers (`space: 'screen'`), emit commands in CSS-pixel
|
|
508
|
+
* coords directly; `drawLayers` passes them through unchanged. If part
|
|
509
|
+
* of a screen-space layer's output needs to track the view, wrap that
|
|
510
|
+
* subset manually with `viewToMat3(view)`.
|
|
511
|
+
*/
|
|
512
|
+
draw: (data: TData, view: View, dims: Dims) => DrawCommand[];
|
|
513
|
+
/**
|
|
514
|
+
* Optional cache key. When present and a `LayerCommandCache` is supplied to
|
|
515
|
+
* `drawLayers`, the layer's previous `DrawCommand[]` is reused as long as
|
|
516
|
+
* every entry is `Object.is`-equal to the previous call's. A layer with no
|
|
517
|
+
* `deps` rebuilds on every frame.
|
|
518
|
+
*
|
|
519
|
+
* **The returned commands must be treated as immutable.** A cached tree is
|
|
520
|
+
* handed to the renderer again on later frames, so mutating a tree you
|
|
521
|
+
* previously returned corrupts the cache silently rather than erroring.
|
|
522
|
+
*
|
|
523
|
+
* **Screen-space layers are not protected against a stale `view`/`dims`
|
|
524
|
+
* the way world-space layers are** (see `space` below) — include them in
|
|
525
|
+
* `deps` if `draw` reads them.
|
|
526
|
+
*/
|
|
527
|
+
deps?: (data: TData, view: View, dims: Dims) => readonly unknown[];
|
|
528
|
+
/**
|
|
529
|
+
* Whether the layer is shown when no explicit visibility entry exists.
|
|
530
|
+
* Defaults to `true` when absent.
|
|
531
|
+
*/
|
|
532
|
+
defaultVisible?: boolean;
|
|
533
|
+
/**
|
|
534
|
+
* When true, the layer is always drawn regardless of the visibility map.
|
|
535
|
+
* Useful for layers that must never be hidden (e.g. base grid).
|
|
536
|
+
*/
|
|
537
|
+
alwaysOn?: boolean;
|
|
538
|
+
/**
|
|
539
|
+
* Coordinate space the layer draws in.
|
|
540
|
+
*
|
|
541
|
+
* - `'world'` (default): the layer's `draw` returns world-space commands;
|
|
542
|
+
* `drawLayers` wraps them in a `kind: 'group'` with `viewToMat3(view)`
|
|
543
|
+
* automatically.
|
|
544
|
+
* - `'screen'`: the layer's `draw` returns screen-space (CSS-pixel)
|
|
545
|
+
* commands; `drawLayers` passes them through unchanged. World-anchored
|
|
546
|
+
* chrome inside a screen-space layer must call `worldToScreen` or wrap
|
|
547
|
+
* the relevant subset with `viewToMat3(view)` manually.
|
|
548
|
+
*/
|
|
549
|
+
space?: 'world' | 'screen';
|
|
550
|
+
/**
|
|
551
|
+
* Full-screen passes run over this layer's own pixels before it joins the
|
|
552
|
+
* frame — a blur here blurs the world and leaves the HUD drawn above it
|
|
553
|
+
* sharp, which is the thing a CSS `filter` on the `<canvas>` cannot do.
|
|
554
|
+
*
|
|
555
|
+
* Costs nothing while empty: the renderer allocates no offscreen buffer
|
|
556
|
+
* until a layer actually declares one. See `GroupDrawCommand.effects` for
|
|
557
|
+
* what a pass may read, and {@link LayerGroup} to run one chain over
|
|
558
|
+
* several layers at once instead of one chain each.
|
|
559
|
+
*/
|
|
560
|
+
effects?: readonly Effect[];
|
|
561
|
+
/**
|
|
562
|
+
* Optional hit-test for **consumer-attached** layers.
|
|
563
|
+
*
|
|
564
|
+
* Only layers registered through `CanvasExtensionApi.registerLayer` are
|
|
565
|
+
* hit-tested: `hitTestExtras` walks them last-registered-first on
|
|
566
|
+
* pointerdown, and `<SceneCanvas>` folds the result into its `affordanceAt`
|
|
567
|
+
* thunk ahead of the kit's own selection chrome. First non-null result
|
|
568
|
+
* wins; null means "I don't claim this hit, try the next layer."
|
|
569
|
+
*
|
|
570
|
+
* Layers that reach the draw stack some other way — a `Tool.overlay`, an
|
|
571
|
+
* entry in the `layers` map — are painted but never hit-tested, so defining
|
|
572
|
+
* `hitTest` on one has no effect. (The kit's own chrome doesn't need it: it
|
|
573
|
+
* goes through `buildAffordanceAt`.)
|
|
574
|
+
*
|
|
575
|
+
* Coordinates are world-space. The `data` arg is the layer's
|
|
576
|
+
* configured data slot (same as `draw`); `view` and `dims` mirror
|
|
577
|
+
* `draw`'s arguments.
|
|
578
|
+
*/
|
|
579
|
+
hitTest?: (worldX: number, worldY: number, data: TData, view: View, dims: Dims,
|
|
580
|
+
/** Chrome-caps visibility predicate. When supplied, the layer must
|
|
581
|
+
* not return a hit from any chrome element whose id reports
|
|
582
|
+
* `false`. Absent → every element is hittable. */
|
|
583
|
+
isVisible?: (id: string) => boolean) => LayerHit | null;
|
|
584
|
+
/**
|
|
585
|
+
* Called on every pointermove when no gesture is currently captured.
|
|
586
|
+
* Lets layers (e.g. HUD widgets) track hover state without participating
|
|
587
|
+
* in the drag pipeline. Coords are world-space; the layer is responsible
|
|
588
|
+
* for any further conversion (e.g. world→screen for screen-space layers)
|
|
589
|
+
* and for its own throttling.
|
|
590
|
+
*/
|
|
591
|
+
onUncapturedMove?: (worldX: number, worldY: number, evt: PointerEvent, view: View, dims: Dims) => void;
|
|
592
|
+
/**
|
|
593
|
+
* Called when the cursor leaves the canvas element. Lets layers clear
|
|
594
|
+
* any hover state they're holding.
|
|
595
|
+
*/
|
|
596
|
+
onUncapturedLeave?: () => void;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Walk visible layers and concatenate their emitted DrawCommand arrays into
|
|
600
|
+
* one flat list, ready to feed to `WeaselRenderer.render(commands)`.
|
|
601
|
+
*
|
|
602
|
+
* Visibility resolution order:
|
|
603
|
+
* 1. `alwaysOn` — always drawn, ignores visibility map.
|
|
604
|
+
* 2. Explicit entry in `visibility` map — overrides default.
|
|
605
|
+
* 3. `layer.defaultVisible` — falls back to `true` when absent.
|
|
606
|
+
*
|
|
607
|
+
* Transform composition: world-space layers (the default; `space` unset or
|
|
608
|
+
* `'world'`) have their commands wrapped in a `kind: 'group'` with
|
|
609
|
+
* `viewToMat3(view)` before they reach the renderer. Screen-space layers
|
|
610
|
+
* (`space: 'screen'`) pass through unchanged.
|
|
611
|
+
*
|
|
612
|
+
* A layer whose `draw` throws is dropped for the frame and reported through
|
|
613
|
+
* `onLayerError` — the rest of the frame still paints.
|
|
614
|
+
*
|
|
615
|
+
* `groups` brackets runs of consecutive layers so they composite as one — see
|
|
616
|
+
* `LayerGroup`. A layer named by no group is emitted exactly as it was before
|
|
617
|
+
* groups existed, and a frame that declares none allocates nothing.
|
|
618
|
+
*/
|
|
619
|
+
declare function drawLayers<TData>(layers: RenderLayer<TData>[], data: TData, visibility: Record<string, boolean>, order: string[] | undefined, view: View | undefined, dims: Dims, cache?: LayerCommandCache, onLayerError?: (failure: LayerDrawFailure) => void, groups?: readonly LayerGroup[]): DrawCommand[];
|
|
620
|
+
/**
|
|
621
|
+
* Resolve one layer's visibility: `alwaysOn` wins, then an explicit entry in
|
|
622
|
+
* `visibility`, then `defaultVisible`, defaulting to shown.
|
|
623
|
+
*/
|
|
624
|
+
declare function isLayerVisible<TData>(layer: RenderLayer<TData>, visibility: Record<string, boolean>): boolean;
|
|
625
|
+
/**
|
|
626
|
+
* Does this layer reach the screen at all — both gates, in the order
|
|
627
|
+
* `drawLayers` applies them.
|
|
628
|
+
*
|
|
629
|
+
* **A listed `order` is the whole list**, so omission from it drops a layer
|
|
630
|
+
* that `visibility` would have shown, and `alwaysOn` does not rescue it.
|
|
631
|
+
* Hit-testing asks this, not `isLayerVisible`: a layer that is not painted
|
|
632
|
+
* but still claims pointer events is a pointer landing on nothing the user
|
|
633
|
+
* can see.
|
|
634
|
+
*/
|
|
635
|
+
declare function isLayerPainted<TData>(layer: RenderLayer<TData>, visibility: Record<string, boolean>, order: string[] | undefined): boolean;
|
|
636
|
+
/**
|
|
637
|
+
* Draw one layer and put its commands in the space its `space` declares:
|
|
638
|
+
* world-space output wrapped in a `viewToMat3(view)` group, screen-space
|
|
639
|
+
* output passed through.
|
|
640
|
+
*
|
|
641
|
+
* Anything rendering layers through a view — the canvas itself, a viewport
|
|
642
|
+
* node's inner pass — goes through here. A second copy of this rule that
|
|
643
|
+
* forgets the wrap draws world content at raw world coords, which looks
|
|
644
|
+
* plausible at the identity view and wrong everywhere else.
|
|
645
|
+
*
|
|
646
|
+
* A `draw` that throws yields no commands, and `onLayerError` is told which
|
|
647
|
+
* layer it was. The layer's cache entry goes with it, so the next frame is a
|
|
648
|
+
* real re-attempt rather than a stale tree served under fresh deps.
|
|
649
|
+
*/
|
|
650
|
+
declare function drawOneLayer<TData>(layer: RenderLayer<TData>, data: TData, view: View, dims: Dims, cache?: LayerCommandCache, onLayerError?: (failure: LayerDrawFailure) => void): DrawCommand[];
|
|
651
|
+
|
|
128
652
|
/**
|
|
129
653
|
* Grid overlay — a reusable render layer that draws a world-space grid with
|
|
130
654
|
* optional finer subdivisions and accent lines every N cells.
|
|
@@ -264,6 +788,12 @@ interface CreateViewResolverOpts {
|
|
|
264
788
|
left: number;
|
|
265
789
|
top: number;
|
|
266
790
|
};
|
|
791
|
+
/**
|
|
792
|
+
* Whether something painted over every view claims a canvas-local point —
|
|
793
|
+
* chrome on the surface's own frame. Such a point resolves to the root even
|
|
794
|
+
* inside a view's rect. Asked only where a view would otherwise win.
|
|
795
|
+
*/
|
|
796
|
+
occluded?: (x: number, y: number) => boolean;
|
|
267
797
|
}
|
|
268
798
|
declare function createViewResolver(opts: CreateViewResolverOpts): ViewResolver;
|
|
269
799
|
|
|
@@ -670,7 +1200,8 @@ interface NodeOverlayFrame {
|
|
|
670
1200
|
};
|
|
671
1201
|
/** Node box frame → overlay pixels, rotation and view included. */
|
|
672
1202
|
toScreen: (p: OverlayPoint) => OverlayPoint;
|
|
673
|
-
/** Overlay pixels → node box frame. Inverts `toScreen
|
|
1203
|
+
/** Overlay pixels → node box frame. Inverts `toScreen`; while a live view
|
|
1204
|
+
* flattens an axis, it keeps the last mapping that had an inverse. */
|
|
674
1205
|
toLocal: (p: OverlayPoint) => OverlayPoint;
|
|
675
1206
|
/** The container's size in CSS pixels — the overlay's own box. */
|
|
676
1207
|
width: number;
|
|
@@ -890,7 +1421,8 @@ interface Scale2 {
|
|
|
890
1421
|
x: number;
|
|
891
1422
|
y: number;
|
|
892
1423
|
}
|
|
893
|
-
/** One screen-pixel length as world-space extents, per axis.
|
|
1424
|
+
/** One screen-pixel length as world-space extents, per axis. `scale` is a
|
|
1425
|
+
* view's, so neither axis is zero (see `View`). */
|
|
894
1426
|
declare function pxExtent(px: number, scale: Scale2): {
|
|
895
1427
|
x: number;
|
|
896
1428
|
y: number;
|
|
@@ -913,59 +1445,6 @@ declare function withinPxBox(dx: number, dy: number, px: number, scale: Scale2):
|
|
|
913
1445
|
/** Is a world-space delta inside a screen-space circle of radius `px`? */
|
|
914
1446
|
declare function withinPxRadius(dx: number, dy: number, px: number, scale: Scale2): boolean;
|
|
915
1447
|
|
|
916
|
-
/**
|
|
917
|
-
* The DOM half of a drag: one pointer, held down, from press to release.
|
|
918
|
-
*
|
|
919
|
-
* Every pointerdown-to-pointerup lifecycle in the kit used to answer capture,
|
|
920
|
-
* pointer identity, teardown and lost-pointer recovery for itself, and each
|
|
921
|
-
* answered them differently. This is the one place those are decided; anything
|
|
922
|
-
* above it — thresholds, coordinate spaces, what the drag *means* — belongs to
|
|
923
|
-
* its caller.
|
|
924
|
-
*/
|
|
925
|
-
/** Why a session ended without the pointer being released. */
|
|
926
|
-
type PointerSessionCancelReason =
|
|
927
|
-
/** The browser cancelled the pointer (touch interrupted, palm rejection). */
|
|
928
|
-
'pointercancel'
|
|
929
|
-
/** The origin left the document mid-gesture, taking capture with it. */
|
|
930
|
-
| 'lostcapture'
|
|
931
|
-
/** `cancel()` — an unmount, a window blur, Escape, a consumer's own rule. */
|
|
932
|
-
| 'aborted'
|
|
933
|
-
/** A new press arrived on this pointer, so the tracked one had ended. */
|
|
934
|
-
| 'superseded';
|
|
935
|
-
interface PointerSessionCallbacks {
|
|
936
|
-
/** Every move belonging to this pointer, while it is still held. */
|
|
937
|
-
onMove?: (e: PointerEvent) => void;
|
|
938
|
-
/** The pointer was released. Fires once, before teardown completes. */
|
|
939
|
-
onEnd?: (e: PointerEvent) => void;
|
|
940
|
-
/** The session ended without a release. Fires once. */
|
|
941
|
-
onCancel?: (reason: PointerSessionCancelReason) => void;
|
|
942
|
-
}
|
|
943
|
-
interface PointerSessionOptions {
|
|
944
|
-
/** Ask the origin element to capture the pointer. Default `true`. Capture
|
|
945
|
-
* keeps hover and click off everything the drag passes over; the session
|
|
946
|
-
* does not depend on it to keep receiving events. */
|
|
947
|
-
capture?: boolean;
|
|
948
|
-
}
|
|
949
|
-
interface PointerSession {
|
|
950
|
-
readonly pointerId: number;
|
|
951
|
-
/** False once the session has ended, by any route. */
|
|
952
|
-
readonly active: boolean;
|
|
953
|
-
/** End the session now, reporting `'aborted'`. Idempotent. */
|
|
954
|
-
cancel: () => void;
|
|
955
|
-
}
|
|
956
|
-
/**
|
|
957
|
-
* Open a session for the pointer that `down` belongs to.
|
|
958
|
-
*
|
|
959
|
-
* Listens on the origin's document rather than on the element: a captured
|
|
960
|
-
* element that is removed mid-drag stops receiving events, and every listener
|
|
961
|
-
* hung on it goes with it. Three recovery rules close the gaps a plain
|
|
962
|
-
* pointerup/pointercancel pair leaves — losing capture cancels only once the
|
|
963
|
-
* origin has left the document, a move reporting no held button is read as
|
|
964
|
-
* the release that never arrived, and a fresh press on the same pointer says
|
|
965
|
-
* the tracked one had already ended.
|
|
966
|
-
*/
|
|
967
|
-
declare function openPointerSession(origin: Element, down: PointerEvent | React.PointerEvent, cb: PointerSessionCallbacks, opts?: PointerSessionOptions): PointerSession;
|
|
968
|
-
|
|
969
1448
|
/** A 2D point in the rect element's local coordinate space. */
|
|
970
1449
|
interface HandleDragPoint {
|
|
971
1450
|
x: number;
|
|
@@ -1119,33 +1598,6 @@ interface CanvasSizeSnapshot extends CanvasSize {
|
|
|
1119
1598
|
* query instead. */
|
|
1120
1599
|
declare function useCanvasSize(containerRef: RefObject<HTMLElement | null>): CanvasSizeSnapshot;
|
|
1121
1600
|
|
|
1122
|
-
/**
|
|
1123
|
-
* Handle/hit multiplier applied on a coarse pointer.
|
|
1124
|
-
*
|
|
1125
|
-
* 8px handle → 14px; 24px rotation distance → 42px. Counting the
|
|
1126
|
-
* surrounding grab zone, that lands in the Apple HIG 44pt / Material 48dp
|
|
1127
|
-
* minimum-touch-target band. One constant so it is tunable in one place.
|
|
1128
|
-
*/
|
|
1129
|
-
declare const COARSE_TARGET_SCALE = 1.75;
|
|
1130
|
-
/**
|
|
1131
|
-
* Fold consumer overrides over detected facts and derive `targetScale`.
|
|
1132
|
-
*
|
|
1133
|
-
* `targetScale` is re-derived AFTER the merge, so an override of
|
|
1134
|
-
* `coarsePointer` alone scales the chrome as expected. An explicit
|
|
1135
|
-
* `targetScale` override wins over the derivation.
|
|
1136
|
-
*/
|
|
1137
|
-
declare function resolveDeviceProfile(detected: DetectedDeviceFacts, overrides?: Partial<DeviceProfile>): DeviceProfile;
|
|
1138
|
-
/**
|
|
1139
|
-
* Assumed when `matchMedia` is unavailable (SSR, jsdom) and used as the
|
|
1140
|
-
* absent-means value for `RuleCtx.device`.
|
|
1141
|
-
*
|
|
1142
|
-
* Derived from `resolveDeviceProfile` rather than hand-written, so it can
|
|
1143
|
-
* never drift from what the function would compute for the same facts. A
|
|
1144
|
-
* mouse-like device is the safe default: it is what the kit has always
|
|
1145
|
-
* assumed, so an absent profile changes nothing for existing consumers.
|
|
1146
|
-
*/
|
|
1147
|
-
declare const DEFAULT_DEVICE_PROFILE: DeviceProfile;
|
|
1148
|
-
|
|
1149
1601
|
/**
|
|
1150
1602
|
* Base sizes for grabbable chrome, in CSS pixels at `targetScale = 1`, and the
|
|
1151
1603
|
* one accessor that resolves them for a live pointer type.
|
|
@@ -1219,7 +1671,7 @@ interface ZoomClampOpts {
|
|
|
1219
1671
|
min?: ZoomBound;
|
|
1220
1672
|
max?: ZoomBound;
|
|
1221
1673
|
}
|
|
1222
|
-
declare function zoomAt(
|
|
1674
|
+
declare function zoomAt(input: View, anchor: {
|
|
1223
1675
|
x: number;
|
|
1224
1676
|
y: number;
|
|
1225
1677
|
}, factor: ZoomFactor, opts?: ZoomClampOpts): View;
|
|
@@ -1235,6 +1687,23 @@ declare function zoomAt(view: View, anchor: {
|
|
|
1235
1687
|
*/
|
|
1236
1688
|
declare const DEFAULT_MIN_ZOOM = 0.1;
|
|
1237
1689
|
declare const DEFAULT_MAX_ZOOM = 8;
|
|
1690
|
+
/**
|
|
1691
|
+
* The smallest zoom magnitude a view can hold, in `View.scale` units.
|
|
1692
|
+
*
|
|
1693
|
+
* A view's zoom is always finite and at least this far from 0. Nothing can be
|
|
1694
|
+
* drawn or picked through a zoom of 0, and every screen↔world conversion
|
|
1695
|
+
* divides by it, so it is ruled out where views are made rather than handled
|
|
1696
|
+
* by each conversion. This is validity, not an interaction limit: that is
|
|
1697
|
+
* {@link DEFAULT_MIN_ZOOM}, which a consumer may set far below.
|
|
1698
|
+
*/
|
|
1699
|
+
declare const ZOOM_FLOOR = 1e-9;
|
|
1700
|
+
/**
|
|
1701
|
+
* The one rule for a zoom magnitude: a finite number no smaller than
|
|
1702
|
+
* {@link ZOOM_FLOOR}. Anything else (0, negative, NaN, ±Infinity) becomes the
|
|
1703
|
+
* floor. Dev builds warn once when a zoom that was never valid arrives; a
|
|
1704
|
+
* positive zoom that merely undershoots the floor clamps silently.
|
|
1705
|
+
*/
|
|
1706
|
+
declare function normalizeZoom(zoom: number): number;
|
|
1238
1707
|
|
|
1239
1708
|
/** Options for {@link sceneNodeClientRect}. */
|
|
1240
1709
|
interface SceneNodeClientRectOpts {
|
|
@@ -1285,323 +1754,86 @@ declare function computeFitViewport(viewportW: number, viewportH: number, conten
|
|
|
1285
1754
|
declare function useAutoCenter(width: number, height: number, contentW: number, contentH: number, setZoom: (z: number) => void, setPan: (x: number, y: number) => void): void;
|
|
1286
1755
|
|
|
1287
1756
|
/**
|
|
1288
|
-
*
|
|
1289
|
-
* (`
|
|
1290
|
-
*
|
|
1291
|
-
*
|
|
1292
|
-
* Extracted from the deleted singular `useKeybinding` hook so the remaining
|
|
1293
|
-
* consumers don't depend on its disappearance.
|
|
1757
|
+
* Project an action's keyboard bindings into the shape a shortcut chip
|
|
1758
|
+
* renders from (`formatShortcut` / `formatShortcutParts` in
|
|
1759
|
+
* `@weasel-js/ui`). Palette and menu surfaces show what an action answers
|
|
1760
|
+
* to; the dispatcher reads the specs themselves.
|
|
1294
1761
|
*/
|
|
1762
|
+
|
|
1763
|
+
/** One keyboard shortcut, flattened for display. Structurally the
|
|
1764
|
+
* `ShortcutInput` weasel-ui formats — kept local so core doesn't depend on
|
|
1765
|
+
* the UI package. */
|
|
1766
|
+
interface ActionShortcut {
|
|
1767
|
+
key: string;
|
|
1768
|
+
mod: boolean;
|
|
1769
|
+
alt: boolean;
|
|
1770
|
+
shift: boolean;
|
|
1771
|
+
}
|
|
1295
1772
|
/**
|
|
1296
|
-
*
|
|
1297
|
-
*
|
|
1298
|
-
*
|
|
1773
|
+
* The chip form of a single gesture spec, or `undefined` when the spec has
|
|
1774
|
+
* none.
|
|
1775
|
+
*
|
|
1776
|
+
* Two kinds of collapsing, both because a binding list is written for a
|
|
1777
|
+
* matcher rather than for a reader:
|
|
1778
|
+
*
|
|
1779
|
+
* - A spec's `key` may list spellings of one keycap (`['[', '{']` — the
|
|
1780
|
+
* shifted bracket reports as `'{'`). The first is the shortcut's name.
|
|
1781
|
+
* - A modifier declared `'optional'` matches held or unheld, so it isn't
|
|
1782
|
+
* part of what the user has to press.
|
|
1783
|
+
*
|
|
1784
|
+
* Non-keyboard specs (drag, wheel, click) have no chip form. Neither does a
|
|
1785
|
+
* *required* `ctrl` or `meta` — nothing in the kit declares one, and the
|
|
1786
|
+
* display shape carries only `mod`.
|
|
1299
1787
|
*/
|
|
1300
|
-
|
|
1301
|
-
/**
|
|
1302
|
-
* Key or list of keys to match. Compared case-insensitively against
|
|
1303
|
-
* `event.key`, so `'a'` matches both `'a'` and `'A'`.
|
|
1304
|
-
*/
|
|
1305
|
-
key: string | readonly string[];
|
|
1306
|
-
/**
|
|
1307
|
-
* Require Cmd (mac) or Ctrl (others). When `true`, exactly one of
|
|
1308
|
-
* `metaKey`/`ctrlKey` must be held. Default `false` (both forbidden).
|
|
1309
|
-
*/
|
|
1310
|
-
mod?: boolean;
|
|
1311
|
-
/** Require Alt. Default `false` (forbidden). */
|
|
1312
|
-
alt?: boolean;
|
|
1313
|
-
/**
|
|
1314
|
-
* Shift policy. `undefined`/`false` forbids shift, `true` requires
|
|
1315
|
-
* shift, `'optional'` allows either. Default `undefined`.
|
|
1316
|
-
*/
|
|
1317
|
-
shift?: boolean | 'optional';
|
|
1318
|
-
/** Skip when focus is in an editable element. Default `true`. */
|
|
1319
|
-
skipInEditable?: boolean;
|
|
1320
|
-
/** When `false`, the listener is not attached. Default `true`. */
|
|
1321
|
-
enabled?: boolean;
|
|
1322
|
-
/** Call `preventDefault` before the handler. Default `true`. */
|
|
1323
|
-
preventDefault?: boolean;
|
|
1324
|
-
}
|
|
1325
|
-
/** Returns true when the target is an input, textarea, or contenteditable element. */
|
|
1326
|
-
declare function isEditableTarget(target: EventTarget | null): boolean;
|
|
1788
|
+
declare function keySpecShortcut(spec: GestureSpec): ActionShortcut | undefined;
|
|
1327
1789
|
/**
|
|
1328
|
-
*
|
|
1329
|
-
*
|
|
1330
|
-
*
|
|
1331
|
-
* gesture dispatcher so the rules can't drift.
|
|
1790
|
+
* Every keyboard shortcut an action answers to, in declaration order.
|
|
1791
|
+
* Specs `keySpecShortcut` has no chip for are skipped, and bindings it leaves
|
|
1792
|
+
* identical are emitted once; an action bound only to those returns empty.
|
|
1332
1793
|
*/
|
|
1333
|
-
declare function
|
|
1794
|
+
declare function actionShortcuts(action: Action): readonly ActionShortcut[];
|
|
1334
1795
|
|
|
1335
1796
|
/**
|
|
1336
|
-
*
|
|
1337
|
-
* the tree against a RuleCtx; combinator methods produce new Conditions
|
|
1338
|
-
* wrapping `all`/`any`/`not` nodes.
|
|
1797
|
+
* `moveAction` — first `ongoing`-timing Action descriptor.
|
|
1339
1798
|
*
|
|
1340
|
-
*
|
|
1341
|
-
* `
|
|
1342
|
-
*
|
|
1343
|
-
* `
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
1799
|
+
* Mirrors the per-frame translate semantics of the `useMove` hook:
|
|
1800
|
+
* - `start`: capture origin poses for all selected nodes; record the
|
|
1801
|
+
* current drag delta in scratch each frame.
|
|
1802
|
+
* - `onMove`: update the in-scratch `currentDelta`, and publish the frame's
|
|
1803
|
+
* poses as ephemeral overrides. No *document* writes, so the undo stack
|
|
1804
|
+
* still sees one entry for the whole drag.
|
|
1805
|
+
* - `onEnd('commit')`: emit the final delta as transform ops and route
|
|
1806
|
+
* them through the consumer `applyOps` hook when present, else
|
|
1807
|
+
* `scene.applyBatch(ops, 'Move', adapter)` — either way a single batch
|
|
1808
|
+
* → exactly one undo entry for the whole drag.
|
|
1809
|
+
* - `onEnd('cancel')`: drop the overrides — the document was never mutated,
|
|
1810
|
+
* so the committed poses are the restoration.
|
|
1346
1811
|
*
|
|
1347
|
-
*
|
|
1348
|
-
* produces `{ all: [a, b, c] }` rather than `{ all: [{ all: [a, b] }, c] }`.
|
|
1349
|
-
* Canonical form simplifies downstream introspection.
|
|
1812
|
+
* ## Why no per-frame document writes
|
|
1350
1813
|
*
|
|
1351
|
-
*
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
*
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
*
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
*
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
*
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
/** Active action's kind matches `kind` (e.g. `actionIs('move')`). */
|
|
1375
|
-
declare const actionIs: (kind: string) => Condition;
|
|
1376
|
-
/** Nothing selected. */
|
|
1377
|
-
declare const selectionEmpty: Condition;
|
|
1378
|
-
/** Exactly `n` items selected. */
|
|
1379
|
-
declare const selectionIs: (n: number) => Condition;
|
|
1380
|
-
/** At least `n` items selected. `selectionAtLeast(1)` is the common
|
|
1381
|
-
* "something is selected" check. */
|
|
1382
|
-
declare const selectionAtLeast: (n: number) => Condition;
|
|
1383
|
-
/** Multi-mode handle behavior active (single shared union-bounds
|
|
1384
|
-
* handle vs per-item handles). Implemented as a `when` because
|
|
1385
|
-
* `multiActive` is a derived single-call read on RuleCtx, not a
|
|
1386
|
-
* selector-table key. Stable; safe to introspect. */
|
|
1387
|
-
declare const multiActive: Condition;
|
|
1388
|
-
/** Pointer is hovering some node. */
|
|
1389
|
-
declare const hovering: Condition;
|
|
1390
|
-
/** Pointer is hovering a node that is currently selected. */
|
|
1391
|
-
declare const hoveringSelected: Condition;
|
|
1392
|
-
/** Named modifier key currently held. */
|
|
1393
|
-
declare const modifierHeld: (m: keyof ModifierState) => Condition;
|
|
1394
|
-
/** View scale (uniform or geometric mean for non-uniform) is at least
|
|
1395
|
-
* `z`. Useful for "hide hairline chrome at low zoom" rules. */
|
|
1396
|
-
declare const zoomAtLeast: (z: number) => Condition;
|
|
1397
|
-
/** Active mode equals `m`. */
|
|
1398
|
-
declare const modeIs: (m: string) => Condition;
|
|
1399
|
-
/** Active mode is one of `modes`. */
|
|
1400
|
-
declare const modeIn: (modes: readonly string[]) => Condition;
|
|
1401
|
-
/** Active mode is NOT `m`. */
|
|
1402
|
-
declare const modeNot: (m: string) => Condition;
|
|
1403
|
-
/** Active mode's `allows` includes capability `cap`. */
|
|
1404
|
-
declare const capabilityIs: (cap: string) => Condition;
|
|
1405
|
-
/** Active mode's `allows` includes ANY of `caps` (OR). */
|
|
1406
|
-
declare const capabilityIn: (caps: readonly string[]) => Condition;
|
|
1407
|
-
/** Active mode's `allows` includes ALL of `caps` (AND). */
|
|
1408
|
-
declare const capabilityAll: (caps: readonly string[]) => Condition;
|
|
1409
|
-
/** Active mode's `allows` does NOT include capability `cap`. */
|
|
1410
|
-
declare const capabilityNot: (cap: string) => Condition;
|
|
1411
|
-
/** Primary pointer is imprecise (touch, most styluses). Absent device
|
|
1412
|
-
* profile → false, so a rule written with this atom is inert on the
|
|
1413
|
-
* mouse-shaped default rather than silently flipping. */
|
|
1414
|
-
declare const coarsePointer: Condition;
|
|
1415
|
-
/** Primary pointer can hover. Absent device profile → true. Pair with
|
|
1416
|
-
* `not(...)` to gate chrome that only makes sense with a hovering
|
|
1417
|
-
* pointer: `not(canHover)` is "this device cannot hover". */
|
|
1418
|
-
declare const canHover: Condition;
|
|
1419
|
-
|
|
1420
|
-
/**
|
|
1421
|
-
* Kit-shipped defaults. Merged with the consumer's `chromeVisibility` map
|
|
1422
|
-
* at resolve time; consumer entries take precedence per id.
|
|
1423
|
-
*
|
|
1424
|
-
* Written as literal Rule trees rather than fluent chains so the inputs
|
|
1425
|
-
* each rule depends on are immediately visible. The fluent atoms compile
|
|
1426
|
-
* to the same trees; either form is valid in a VisibilityRules entry.
|
|
1427
|
-
*
|
|
1428
|
-
* Gating is written in terms of **capabilities, not mode ids**. A
|
|
1429
|
-
* capability rule keeps holding when a new mode is added that permits the
|
|
1430
|
-
* same thing; a mode rule has to be found and edited every time. There is
|
|
1431
|
-
* no `mode:` rule left in this table — the `path-edit.*` chrome used to be
|
|
1432
|
-
* the exception, on the theory that it's the visual signature of one mode;
|
|
1433
|
-
* see the comment on those rules below for why that was wrong in both
|
|
1434
|
-
* directions and what replaced it.
|
|
1435
|
-
*
|
|
1436
|
-
* Chrome that gates on the *absence* of a capability (the selection
|
|
1437
|
-
* outline, suppressed while an anchor-editing overlay owns the visuals)
|
|
1438
|
-
* uses `capability: { not: … }` for the same reason.
|
|
1439
|
-
*/
|
|
1440
|
-
declare const defaultVisibilityRules: VisibilityRules;
|
|
1441
|
-
|
|
1442
|
-
/**
|
|
1443
|
-
* Build the per-frame visibility check. Merges consumer rules on top
|
|
1444
|
-
* of the kit defaults, then closes over `ctx` so each chrome-id
|
|
1445
|
-
* lookup runs its rule against the current state.
|
|
1446
|
-
*
|
|
1447
|
-
* `VisibilityRules` entries may be either fluent `Condition` values
|
|
1448
|
-
* (callable) or raw `Rule` trees — we normalize at lookup time.
|
|
1449
|
-
*
|
|
1450
|
-
* Predicates are O(1) and run once per chrome id per frame; no
|
|
1451
|
-
* memoization in v1 — profile before adding any.
|
|
1452
|
-
*
|
|
1453
|
-
* `ChromeCtx` is the legacy shape; surfaces still on it get `mode='normal'`
|
|
1454
|
-
* and `DEFAULT_ALLOWED_CAPABILITIES` filled in here, so a caller that never
|
|
1455
|
-
* opted into modality behaves exactly like one sitting in normal mode.
|
|
1456
|
-
*/
|
|
1457
|
-
declare function resolveVisibility(consumer: VisibilityRules | undefined, ctx: ChromeCtx | RuleCtx): (id: ChromeId) => boolean;
|
|
1458
|
-
|
|
1459
|
-
/**
|
|
1460
|
-
* Pure assembler for {@link ChromeCtx}.
|
|
1461
|
-
*
|
|
1462
|
-
* Called once per frame on the rendering side from whichever surface
|
|
1463
|
-
* needs to evaluate visibility rules — `composeAffordanceLayer`,
|
|
1464
|
-
* `createSelectionOverlayLayer`, the dispatcher overlay layer, etc.
|
|
1465
|
-
*
|
|
1466
|
-
* Sources are passed as plain getters / values rather than the live
|
|
1467
|
-
* objects they come from. This keeps `chrome-caps` from depending on
|
|
1468
|
-
* React, the dispatcher's concrete type, or `ChromeState`'s bounds
|
|
1469
|
-
* machinery — the same builder works from a test harness, a Storybook
|
|
1470
|
-
* fixture, or `<SceneCanvas>`.
|
|
1471
|
-
*/
|
|
1472
|
-
|
|
1473
|
-
/** The pieces of live canvas state a `ChromeCtx` is assembled from. */
|
|
1474
|
-
interface BuildChromeCtxArgs {
|
|
1475
|
-
focused: boolean;
|
|
1476
|
-
selection: readonly NodeId[];
|
|
1477
|
-
multiActive: boolean;
|
|
1478
|
-
modifiers: ModifierState;
|
|
1479
|
-
action: {
|
|
1480
|
-
kind: string | null;
|
|
1481
|
-
id: string | null;
|
|
1482
|
-
};
|
|
1483
|
-
hover: NodeId | null;
|
|
1484
|
-
view: View;
|
|
1485
|
-
}
|
|
1486
|
-
/** Gather the current canvas state into the context that chrome-visibility
|
|
1487
|
-
* rules are evaluated against. Rebuilt per frame. */
|
|
1488
|
-
declare function buildChromeCtx(args: BuildChromeCtxArgs): ChromeCtx;
|
|
1489
|
-
|
|
1490
|
-
/**
|
|
1491
|
-
* useHoverTracking — last-hovered NodeId for chrome-caps rules.
|
|
1492
|
-
*
|
|
1493
|
-
* Attaches a `pointermove` listener to the supplied canvas; on each move it
|
|
1494
|
-
* runs the supplied `nodeAtClientPoint` and caches the resulting id on a ref.
|
|
1495
|
-
* Cleared on `pointerleave` (pointer left the canvas → nothing is hovered).
|
|
1496
|
-
*
|
|
1497
|
-
* Returns a stable getter — call once per frame from `buildChromeCtx`.
|
|
1498
|
-
*
|
|
1499
|
-
* No re-render: the ref updates silently, and the next render that
|
|
1500
|
-
* reads it picks up the fresh value. Chrome-caps rules are evaluated
|
|
1501
|
-
* during paint, so the hover state is always read fresh.
|
|
1502
|
-
*/
|
|
1503
|
-
|
|
1504
|
-
/** Options for `useHoverTracking`. */
|
|
1505
|
-
interface UseHoverTrackingArgs {
|
|
1506
|
-
canvasRef: RefObject<HTMLElement | null>;
|
|
1507
|
-
/** Topmost id under a client point, or null. One lookup rather than a
|
|
1508
|
-
* client→world thunk beside a world-space picker: a screen-pixel pick
|
|
1509
|
-
* tolerance converts against the camera the point resolved to, and two
|
|
1510
|
-
* thunks are two chances to disagree about which view that is. */
|
|
1511
|
-
nodeAtClientPoint: (clientX: number, clientY: number) => {
|
|
1512
|
-
id: NodeId;
|
|
1513
|
-
} | null;
|
|
1514
|
-
enabled?: boolean;
|
|
1515
|
-
}
|
|
1516
|
-
/** Track which node the pointer is over. Returns a getter rather than state,
|
|
1517
|
-
* so per-frame code can read the current value without the hover re-rendering
|
|
1518
|
-
* the component on every pointer move. */
|
|
1519
|
-
declare function useHoverTracking(args: UseHoverTrackingArgs): () => NodeId | null;
|
|
1520
|
-
|
|
1521
|
-
/**
|
|
1522
|
-
* Project an action's keyboard bindings into the shape a shortcut chip
|
|
1523
|
-
* renders from (`formatShortcut` / `formatShortcutParts` in
|
|
1524
|
-
* `@weasel-js/ui`). Palette and menu surfaces show what an action answers
|
|
1525
|
-
* to; the dispatcher reads the specs themselves.
|
|
1526
|
-
*/
|
|
1527
|
-
|
|
1528
|
-
/** One keyboard shortcut, flattened for display. Structurally the
|
|
1529
|
-
* `ShortcutInput` weasel-ui formats — kept local so core doesn't depend on
|
|
1530
|
-
* the UI package. */
|
|
1531
|
-
interface ActionShortcut {
|
|
1532
|
-
key: string;
|
|
1533
|
-
mod: boolean;
|
|
1534
|
-
alt: boolean;
|
|
1535
|
-
shift: boolean;
|
|
1536
|
-
}
|
|
1537
|
-
/**
|
|
1538
|
-
* The chip form of a single gesture spec, or `undefined` when the spec has
|
|
1539
|
-
* none.
|
|
1540
|
-
*
|
|
1541
|
-
* Two kinds of collapsing, both because a binding list is written for a
|
|
1542
|
-
* matcher rather than for a reader:
|
|
1543
|
-
*
|
|
1544
|
-
* - A spec's `key` may list spellings of one keycap (`['[', '{']` — the
|
|
1545
|
-
* shifted bracket reports as `'{'`). The first is the shortcut's name.
|
|
1546
|
-
* - A modifier declared `'optional'` matches held or unheld, so it isn't
|
|
1547
|
-
* part of what the user has to press.
|
|
1548
|
-
*
|
|
1549
|
-
* Non-keyboard specs (drag, wheel, click) have no chip form. Neither does a
|
|
1550
|
-
* *required* `ctrl` or `meta` — nothing in the kit declares one, and the
|
|
1551
|
-
* display shape carries only `mod`.
|
|
1552
|
-
*/
|
|
1553
|
-
declare function keySpecShortcut(spec: GestureSpec): ActionShortcut | undefined;
|
|
1554
|
-
/**
|
|
1555
|
-
* Every keyboard shortcut an action answers to, in declaration order.
|
|
1556
|
-
* Specs `keySpecShortcut` has no chip for are skipped, and bindings it leaves
|
|
1557
|
-
* identical are emitted once; an action bound only to those returns empty.
|
|
1558
|
-
*/
|
|
1559
|
-
declare function actionShortcuts(action: Action): readonly ActionShortcut[];
|
|
1560
|
-
|
|
1561
|
-
/**
|
|
1562
|
-
* `moveAction` — first `ongoing`-timing Action descriptor.
|
|
1563
|
-
*
|
|
1564
|
-
* Mirrors the per-frame translate semantics of the `useMove` hook:
|
|
1565
|
-
* - `start`: capture origin poses for all selected nodes; record the
|
|
1566
|
-
* current drag delta in scratch each frame.
|
|
1567
|
-
* - `onMove`: update the in-scratch `currentDelta`, and publish the frame's
|
|
1568
|
-
* poses as ephemeral overrides. No *document* writes, so the undo stack
|
|
1569
|
-
* still sees one entry for the whole drag.
|
|
1570
|
-
* - `onEnd('commit')`: emit the final delta as transform ops and route
|
|
1571
|
-
* them through the consumer `applyOps` hook when present, else
|
|
1572
|
-
* `scene.applyBatch(ops, 'Move', adapter)` — either way a single batch
|
|
1573
|
-
* → exactly one undo entry for the whole drag.
|
|
1574
|
-
* - `onEnd('cancel')`: drop the overrides — the document was never mutated,
|
|
1575
|
-
* so the committed poses are the restoration.
|
|
1576
|
-
*
|
|
1577
|
-
* ## Why no per-frame document writes
|
|
1578
|
-
*
|
|
1579
|
-
* `Scene.setPose` calls `executeAndLog`, which immediately records an undo
|
|
1580
|
-
* entry on the scene's history engine. Per-frame writes during drag would
|
|
1581
|
-
* create O(frames) history entries, so the drag commits one
|
|
1582
|
-
* `createTransformOp` batch at the end.
|
|
1583
|
-
*
|
|
1584
|
-
* The per-frame poses still go *somewhere* the scene can see: the ephemeral
|
|
1585
|
-
* override table, which bypasses history entirely. That is what lets a node
|
|
1586
|
-
* deriving its geometry from a dragged one follow the drag — `sceneDepLookup`
|
|
1587
|
-
* and the pick source both read overrides, and neither can see this action's
|
|
1588
|
-
* scratch. Keeping the frame in scratch alone is why the edge used to stay
|
|
1589
|
-
* anchored to the old endpoint and jump on drop.
|
|
1590
|
-
*
|
|
1591
|
-
* The behavior pipeline (snap-to-grid, snap-back-or-delete, snap-to-container,
|
|
1592
|
-
* etc.) via `opts.behaviors` from `BindingOpts` IS wired: `start` builds a
|
|
1593
|
-
* `GestureContext` + scene-backed adapter (`moveGestureAdapter`), `onMove`
|
|
1594
|
-
* folds each behavior's proposed-transform result, and `onEnd` runs a
|
|
1595
|
-
* first-non-undefined-wins reducer (`Op[]` commits via `scene.applyBatch`,
|
|
1596
|
-
* `null` aborts, all-`undefined` falls through to the default translate path).
|
|
1597
|
-
*
|
|
1598
|
-
* ## Pose generics
|
|
1599
|
-
*
|
|
1600
|
-
* `scene` dep is typed `Scene<unknown, string, unknown>` (the erased DepSchema
|
|
1601
|
-
* entry). Poses are read and written as `unknown`; `translatePoseGeneric`
|
|
1602
|
-
* delegates to `RECT_POSE_DESCRIPTOR.translate` which treats any pose as
|
|
1603
|
-
* `{x, y, ...}`. Consumers with non-rect poses should register a custom
|
|
1604
|
-
* action with a typed translatePose.
|
|
1814
|
+
* `Scene.setPose` calls `executeAndLog`, which immediately records an undo
|
|
1815
|
+
* entry on the scene's history engine. Per-frame writes during drag would
|
|
1816
|
+
* create O(frames) history entries, so the drag commits one
|
|
1817
|
+
* `createTransformOp` batch at the end.
|
|
1818
|
+
*
|
|
1819
|
+
* The per-frame poses still go *somewhere* the scene can see: the ephemeral
|
|
1820
|
+
* override table, which bypasses history entirely. That is what lets a node
|
|
1821
|
+
* deriving its geometry from a dragged one follow the drag — `sceneDepLookup`
|
|
1822
|
+
* and the pick source both read overrides, and neither can see this action's
|
|
1823
|
+
* scratch. Keeping the frame in scratch alone is why the edge used to stay
|
|
1824
|
+
* anchored to the old endpoint and jump on drop.
|
|
1825
|
+
*
|
|
1826
|
+
* The behavior pipeline (snap-to-grid, snap-back-or-delete, snap-to-container,
|
|
1827
|
+
* etc.) via `opts.behaviors` from `BindingOpts` IS wired: `start` builds a
|
|
1828
|
+
* `GestureContext` + scene-backed adapter (`moveGestureAdapter`), `onMove`
|
|
1829
|
+
* folds each behavior's proposed-transform result, and `onEnd` runs a
|
|
1830
|
+
* first-non-undefined-wins reducer (`Op[]` commits via `scene.applyBatch`,
|
|
1831
|
+
* `null` aborts, all-`undefined` falls through to the default translate path).
|
|
1832
|
+
*
|
|
1833
|
+
* ## Pose generics
|
|
1834
|
+
*
|
|
1835
|
+
* Poses are `unknown`; every read and write goes through the `poseDescriptor`
|
|
1836
|
+
* dep (`AUTO_POSE_DESCRIPTOR` when unsourced).
|
|
1605
1837
|
*/
|
|
1606
1838
|
|
|
1607
1839
|
/**
|
|
@@ -1629,17 +1861,14 @@ declare const moveAction: Action & {
|
|
|
1629
1861
|
* start poses, applies per-frame bounds remapping, and commits a single
|
|
1630
1862
|
* `scene.batch` entry on end.
|
|
1631
1863
|
*
|
|
1632
|
-
* ## Behaviors / point-snap / expandIds
|
|
1864
|
+
* ## Behaviors / point-snap / expandIds — via the `resizePolicy` dep
|
|
1633
1865
|
*
|
|
1634
|
-
* The
|
|
1635
|
-
*
|
|
1636
|
-
*
|
|
1637
|
-
* the dep is registered, this invoker:
|
|
1866
|
+
* The `resizePolicy` dep carries the behavior options the legacy `useResize`
|
|
1867
|
+
* hook exposed (`behaviors`, `pointSnapBehaviors`, `expandIds`). When the dep
|
|
1868
|
+
* is registered, this invoker:
|
|
1638
1869
|
*
|
|
1639
1870
|
* - Calls `expandIds([id])` at start. When the result expands beyond the
|
|
1640
1871
|
* starting id, takes the group path (union-AABB origin, per-leaf remap).
|
|
1641
|
-
* - Projects poses through the supplied `geometry: PoseProjection<TPose>`
|
|
1642
|
-
* instead of the rect-shaped `RECT_POSE_DESCRIPTOR` default.
|
|
1643
1872
|
* - Runs `behaviors[]` after the raw anchor-math bounds are computed.
|
|
1644
1873
|
* Behaviors return `{ pose? }` and rewrite the proposed bounds before
|
|
1645
1874
|
* they're projected back into pose space.
|
|
@@ -1648,12 +1877,17 @@ declare const moveAction: Action & {
|
|
|
1648
1877
|
* frame's world point lands on the snap target.
|
|
1649
1878
|
*
|
|
1650
1879
|
* When the dep is absent the invoker falls back to identity defaults
|
|
1651
|
-
* (no behaviors, no snap, `ids => ids` expansion
|
|
1652
|
-
*
|
|
1653
|
-
*
|
|
1880
|
+
* (no behaviors, no snap, `ids => ids` expansion).
|
|
1881
|
+
*
|
|
1882
|
+
* ## Pose geometry — via the `poseDescriptor` dep
|
|
1883
|
+
*
|
|
1884
|
+
* Every pose read and rewrite goes through the `poseDescriptor` dep, which
|
|
1885
|
+
* `<SceneCanvas>` sources from its `poseDescriptor` prop. Unsourced it is
|
|
1886
|
+
* `AUTO_POSE_DESCRIPTOR`, which dispatches per call to `pathPoseDescriptor`
|
|
1887
|
+
* for Path-shaped poses and to `RECT_POSE_DESCRIPTOR` for everything else.
|
|
1654
1888
|
*
|
|
1655
1889
|
* @see useResize — the React hook this descriptor mirrors.
|
|
1656
|
-
* @see src/interactions/actions/resize/geometry.ts — `
|
|
1890
|
+
* @see src/interactions/actions/resize/geometry.ts — `PoseDescriptor`.
|
|
1657
1891
|
*/
|
|
1658
1892
|
|
|
1659
1893
|
/**
|
|
@@ -1673,7 +1907,7 @@ declare const resizeAction: Action & {
|
|
|
1673
1907
|
*
|
|
1674
1908
|
* ## Status: REAL (unrotated-pivot path)
|
|
1675
1909
|
*
|
|
1676
|
-
* Implements the core rotation math from `useRotate
|
|
1910
|
+
* Implements the core rotation math from `useRotate`:
|
|
1677
1911
|
* - `start`: captures origin poses + AABB centers; computes start pointer
|
|
1678
1912
|
* angle around the union center of selected nodes.
|
|
1679
1913
|
* - `onMove`: derives pointer angle delta from start, applies to each node's
|
|
@@ -1688,8 +1922,9 @@ declare const resizeAction: Action & {
|
|
|
1688
1922
|
*
|
|
1689
1923
|
* ## Constraints vs `useRotate`
|
|
1690
1924
|
*
|
|
1691
|
-
* -
|
|
1692
|
-
*
|
|
1925
|
+
* - Reads and writes poses through the `poseDescriptor` dep; a pose whose
|
|
1926
|
+
* descriptor has no `withRotation`, or reports `supportsRotation` false, is
|
|
1927
|
+
* left alone.
|
|
1693
1928
|
* - No behavior pipeline (snap, etc.). Behaviors wait for a later phase.
|
|
1694
1929
|
* - No overlay rendering — deferred to Phase 7 overlay surface.
|
|
1695
1930
|
* - Shift-snap (15° quantum) is NOT wired in this phase — omitted deliberately
|
|
@@ -1703,9 +1938,7 @@ declare const resizeAction: Action & {
|
|
|
1703
1938
|
*
|
|
1704
1939
|
* Requires dep-schema entries: `selection`, `scene`.
|
|
1705
1940
|
*
|
|
1706
|
-
* Implements the unrotated-pivot rotation path from `useRotate
|
|
1707
|
-
* shaped poses. Non-rect or behavior-rich consumers should register a custom
|
|
1708
|
-
* `rotateAction` with a typed `RotateGeometry` dep.
|
|
1941
|
+
* Implements the unrotated-pivot rotation path from `useRotate`.
|
|
1709
1942
|
*
|
|
1710
1943
|
* @see useRotate — the React hook this descriptor mirrors for the rect case.
|
|
1711
1944
|
*/
|
|
@@ -1920,9 +2153,7 @@ declare const clearSelectionAction: Action & {
|
|
|
1920
2153
|
*
|
|
1921
2154
|
* ## Pose generics
|
|
1922
2155
|
*
|
|
1923
|
-
* Poses are translated
|
|
1924
|
-
* `moveAction`. Non-rect poses with custom layout (e.g. paths) should register
|
|
1925
|
-
* a custom clone action with a typed geometry dep.
|
|
2156
|
+
* Poses are translated through the `poseDescriptor` dep, as `moveAction` does.
|
|
1926
2157
|
*/
|
|
1927
2158
|
|
|
1928
2159
|
/**
|
|
@@ -2225,12 +2456,25 @@ declare const lassoSelectAction: Action & {
|
|
|
2225
2456
|
};
|
|
2226
2457
|
|
|
2227
2458
|
/**
|
|
2228
|
-
*
|
|
2229
|
-
*
|
|
2230
|
-
*
|
|
2231
|
-
* ## Status: REAL
|
|
2459
|
+
* @experimental
|
|
2460
|
+
* Static descriptor for the `slice` Action.
|
|
2232
2461
|
*
|
|
2233
|
-
*
|
|
2462
|
+
* Ongoing drag invoker: tracks a slice line from drag start to current
|
|
2463
|
+
* pointer, publishes it as a `'cut'` overlay while the gesture is in flight,
|
|
2464
|
+
* and on commit calls `SliceDep.commit(a, b)`. No-ops gracefully when
|
|
2465
|
+
* the `slice` dep is absent.
|
|
2466
|
+
*/
|
|
2467
|
+
declare const sliceAction: Action & {
|
|
2468
|
+
requires: string[];
|
|
2469
|
+
};
|
|
2470
|
+
|
|
2471
|
+
/**
|
|
2472
|
+
* `pinchZoomAction` — ongoing Action descriptor for two-finger pinch zoom
|
|
2473
|
+
* and pan. The id and label stay `pinchZoom` / `Pinch Zoom`.
|
|
2474
|
+
*
|
|
2475
|
+
* ## Status: REAL
|
|
2476
|
+
*
|
|
2477
|
+
* Implements pinch-zoom via the multi-touch pointer stream:
|
|
2234
2478
|
* - `start`: captures startSpread from `ctx.multiTouch.pinch.startSpread`
|
|
2235
2479
|
* (or falls back to `ctx.multiTouch.spread`). Records the initial centroid.
|
|
2236
2480
|
* - `onMove`: computes zoom factor = currentSpread / startSpread, anchors
|
|
@@ -2287,6 +2531,143 @@ declare const pinchZoomAction: Action & {
|
|
|
2287
2531
|
requires: string[];
|
|
2288
2532
|
};
|
|
2289
2533
|
|
|
2534
|
+
/**
|
|
2535
|
+
* @experimental
|
|
2536
|
+
* Static descriptor for the `clipboard.copy` Action (Cmd/Ctrl+C).
|
|
2537
|
+
*/
|
|
2538
|
+
declare const clipboardCopyAction: Action & {
|
|
2539
|
+
requires: string[];
|
|
2540
|
+
};
|
|
2541
|
+
/**
|
|
2542
|
+
* @experimental
|
|
2543
|
+
* Static descriptor for the `clipboard.cut` Action (Cmd/Ctrl+X) — copy, then
|
|
2544
|
+
* the same batched delete `deleteAction` performs, as one undo entry.
|
|
2545
|
+
*/
|
|
2546
|
+
declare const clipboardCutAction: Action & {
|
|
2547
|
+
requires: string[];
|
|
2548
|
+
};
|
|
2549
|
+
|
|
2550
|
+
/**
|
|
2551
|
+
* `enterTextEditAction` — immediate Action descriptor for entering in-place
|
|
2552
|
+
* text editing on a selected text node.
|
|
2553
|
+
*
|
|
2554
|
+
* ## Status: REAL
|
|
2555
|
+
*
|
|
2556
|
+
* Fires via `useTextTool.bindings` when the user clicks on a
|
|
2557
|
+
* selected text node. Calls `deps.textEdit.startEdit(id)` to activate the
|
|
2558
|
+
* contenteditable overlay managed by `useTextEdit` / `useSceneTextEdit`.
|
|
2559
|
+
*
|
|
2560
|
+
* ## No defaultBinding / defaultBinding
|
|
2561
|
+
*
|
|
2562
|
+
* This action has no ambient key or gesture binding — it fires ONLY via
|
|
2563
|
+
* `useTextTool`'s `Tool.bindings` entry:
|
|
2564
|
+
*
|
|
2565
|
+
* ```ts
|
|
2566
|
+
* bindings: [
|
|
2567
|
+
* { spec: { kind: 'click', target: 'selected-body' }, actionId: 'enterTextEdit' },
|
|
2568
|
+
* ]
|
|
2569
|
+
* ```
|
|
2570
|
+
*
|
|
2571
|
+
* Keeping it binding-free avoids ambient double-fire and scopes the action to
|
|
2572
|
+
* the text tool context where `classifyTarget` is already wired.
|
|
2573
|
+
*
|
|
2574
|
+
* ## Self-guard: only act on text nodes
|
|
2575
|
+
*
|
|
2576
|
+
* The `'selected-body'` target yields a match for any selected node kind. To
|
|
2577
|
+
* avoid entering text-edit mode when the text tool happens to have a non-text
|
|
2578
|
+
* node selected, the action self-guards via an optional `isTextNode` predicate
|
|
2579
|
+
* on `TextEditDep`:
|
|
2580
|
+
*
|
|
2581
|
+
* - When `isTextNode` is absent: action fires unconditionally (the binding
|
|
2582
|
+
* spec is the real gate — consumers should only bind this action from the
|
|
2583
|
+
* text tool).
|
|
2584
|
+
* - When `isTextNode(id)` returns `false`: action is a no-op for that node.
|
|
2585
|
+
*
|
|
2586
|
+
* ### Pre-filtering at dispatch time
|
|
2587
|
+
*
|
|
2588
|
+
* `classifyTarget` now surfaces node kind, so a binding can pre-filter instead
|
|
2589
|
+
* of relying on the self-guard:
|
|
2590
|
+
*
|
|
2591
|
+
* ```ts
|
|
2592
|
+
* { spec: { kind: 'click', target: 'kind:text:selected' }, actionId: 'enterTextEdit' }
|
|
2593
|
+
* ```
|
|
2594
|
+
*
|
|
2595
|
+
* That reads the *routing trait's* kind, so it matches whatever names the
|
|
2596
|
+
* consumer registered in `<SceneCanvas routing>` — `'text'` under the kit's
|
|
2597
|
+
* inferred default. `isTextNode` stays on `TextEditDep` because it also covers
|
|
2598
|
+
* consumers who bind the broader `'selected-body'` target, and because it is
|
|
2599
|
+
* the only guard for a consumer who opted out of routing entirely.
|
|
2600
|
+
*
|
|
2601
|
+
* ## Migration plan for useTextTool
|
|
2602
|
+
*
|
|
2603
|
+
* When wiring `useTextTool` to `Tool.bindings`:
|
|
2604
|
+
*
|
|
2605
|
+
* 1. Add to `useTextTool`'s `bindings`:
|
|
2606
|
+
* ```ts
|
|
2607
|
+
* { spec: { kind: 'click', target: 'selected-body' }, actionId: 'enterTextEdit' }
|
|
2608
|
+
* ```
|
|
2609
|
+
* 2. Register a `textEdit` dep sourced from the `useTextEdit` / `useSceneTextEdit`
|
|
2610
|
+
* return value, plus an `isTextNode` predicate that checks `data.kind === 'text'`
|
|
2611
|
+
* (or however the consumer identifies text nodes).
|
|
2612
|
+
* 3. The existing `hitExisting` gate in `useTextTool`'s click route becomes
|
|
2613
|
+
* redundant — remove it in the same pass.
|
|
2614
|
+
*/
|
|
2615
|
+
|
|
2616
|
+
/**
|
|
2617
|
+
* @experimental
|
|
2618
|
+
* Static descriptor for the `enterTextEdit` Action.
|
|
2619
|
+
*
|
|
2620
|
+
* Requires dep-schema entries: `textEdit`, `selection`.
|
|
2621
|
+
*
|
|
2622
|
+
* No `defaultBinding` / `defaultBinding` — fires only via `Tool.bindings`.
|
|
2623
|
+
* Self-guards via `TextEditDep.isTextNode` when provided.
|
|
2624
|
+
*/
|
|
2625
|
+
declare const enterTextEditAction: Action & {
|
|
2626
|
+
requires: string[];
|
|
2627
|
+
};
|
|
2628
|
+
|
|
2629
|
+
/** Somewhere selection can live outside this hook. `Scene` satisfies it;
|
|
2630
|
+
* so does any store with the same three methods. */
|
|
2631
|
+
interface SelectionStore {
|
|
2632
|
+
getSelection(): readonly NodeId[];
|
|
2633
|
+
setSelection(ids: readonly NodeId[]): void;
|
|
2634
|
+
subscribe(listener: () => void): () => void;
|
|
2635
|
+
}
|
|
2636
|
+
/** Options for {@link useSelection}. */
|
|
2637
|
+
interface UseSelectionOptions {
|
|
2638
|
+
/** Default `'single'`. */
|
|
2639
|
+
mode?: SelectionMode;
|
|
2640
|
+
/** Default `'shift'`. Ignored in single-mode. */
|
|
2641
|
+
extend?: SelectionExtendKey;
|
|
2642
|
+
/** Default `[]`. */
|
|
2643
|
+
initial?: readonly NodeId[];
|
|
2644
|
+
/** Keep the selection on this store rather than in the hook, so every
|
|
2645
|
+
* consumer of the same scene shares one selection and undo / redo can
|
|
2646
|
+
* restore it. `initial` then only seeds a store that has none yet.
|
|
2647
|
+
* Omit it and the hook owns a selection nobody else sees. */
|
|
2648
|
+
scene?: SelectionStore;
|
|
2649
|
+
/** When `true`, every mutator (`set`/`add`/`remove`/`toggle`/`clear`/
|
|
2650
|
+
* `applyClick`) is a no-op — selection stays at whatever `initial`
|
|
2651
|
+
* pinned it to. Useful for demos that exist to showcase a single
|
|
2652
|
+
* pre-selected node and don't want a
|
|
2653
|
+
* stray click to deselect. */
|
|
2654
|
+
lock?: boolean;
|
|
2655
|
+
}
|
|
2656
|
+
/**
|
|
2657
|
+
* Default implementation of the `getSelection` / `setSelection` adapter
|
|
2658
|
+
* contract every action hook (delete, duplicate, nudge, group, ...) requires.
|
|
2659
|
+
*
|
|
2660
|
+
* Owns selection state, exposes a click-policy helper (single vs multi with
|
|
2661
|
+
* an extend key), and pre-builds the two adapter methods consumers otherwise
|
|
2662
|
+
* hand-roll in every demo:
|
|
2663
|
+
*
|
|
2664
|
+
* ```tsx
|
|
2665
|
+
* const selection = useSelection({ mode: 'multi' });
|
|
2666
|
+
* const adapter = { ...arrayAdapter({...}), ...selection.adapterMethods };
|
|
2667
|
+
* ```
|
|
2668
|
+
*/
|
|
2669
|
+
declare function useSelection(opts?: UseSelectionOptions): SelectionApi;
|
|
2670
|
+
|
|
2290
2671
|
/** @experimental */
|
|
2291
2672
|
interface UseStandardActionsOptions {
|
|
2292
2673
|
/** Kit selection state — ids of currently selected nodes. */
|
|
@@ -2352,289 +2733,26 @@ declare function defaultCommitAdapter<TPose>(scene: Scene<unknown, string, TPose
|
|
|
2352
2733
|
/** Options for `useResizePolicy`. Each omitted field falls back to the kit
|
|
2353
2734
|
* default. */
|
|
2354
2735
|
interface UseResizePolicyOptions<TPose> {
|
|
2355
|
-
constraints?: TPose extends
|
|
2356
|
-
pointSnap?: TPose extends
|
|
2736
|
+
constraints?: TPose extends Bounds ? BoundsConstraint<TPose>[] : never[];
|
|
2737
|
+
pointSnap?: TPose extends Bounds ? PointSnapBehavior<TPose>[] : never[];
|
|
2357
2738
|
expandIds?: (ids: string[]) => string[];
|
|
2358
|
-
projection?: PoseProjection<TPose>;
|
|
2359
2739
|
}
|
|
2360
2740
|
/** Publish how resizing should behave — constraints, point snapping, group
|
|
2361
|
-
* expansion
|
|
2741
|
+
* expansion — for the resize action to consult. */
|
|
2362
2742
|
declare function useResizePolicy<TPose>(options: UseResizePolicyOptions<TPose>): void;
|
|
2363
2743
|
|
|
2744
|
+
/** Publish the pose descriptor every built-in action reads. */
|
|
2745
|
+
declare function usePoseDescriptorDepSource(descriptor: PoseDescriptor<unknown> | undefined): void;
|
|
2746
|
+
|
|
2747
|
+
/** Publish the scene's pose-composition strategy to the built-in actions.
|
|
2748
|
+
* Absent is the absolute-pose model: `scenePoseFrame` falls back to identity
|
|
2749
|
+
* and every world/local conversion in an action is a no-op. */
|
|
2750
|
+
declare function usePoseCompositionDepSource(composition: PoseComposition<unknown> | undefined): void;
|
|
2751
|
+
|
|
2364
2752
|
/** Publish how a slice (knife cut) is performed, so the `slice` action can
|
|
2365
2753
|
* run against the consumer's geometry. */
|
|
2366
2754
|
declare function useSliceDep(dep: SliceDep): void;
|
|
2367
2755
|
|
|
2368
|
-
/**
|
|
2369
|
-
* The painted cursor a surface is currently showing, shared between whoever
|
|
2370
|
-
* decides it and the layer that draws it.
|
|
2371
|
-
*
|
|
2372
|
-
* Two slots rather than one, mirroring the precedence the cursor pipeline
|
|
2373
|
-
* already has: `<Canvas>` writes the active tool's cursor to `base` from
|
|
2374
|
-
* render, and the hover pump writes an affordance's or an action's cursor to
|
|
2375
|
-
* `override` imperatively. The override wins while it is set, and clearing it
|
|
2376
|
-
* restores the base without a React commit — the same reason the pump uses an
|
|
2377
|
-
* inline style for the CSS tier.
|
|
2378
|
-
*/
|
|
2379
|
-
|
|
2380
|
-
/** The painted arm of `ResolvedCursor` — what this module stores. */
|
|
2381
|
-
type PaintedCursor = Extract<ResolvedCursor, {
|
|
2382
|
-
kind: 'painted';
|
|
2383
|
-
}>;
|
|
2384
|
-
interface PaintedCursorFrame {
|
|
2385
|
-
readonly cursor: PaintedCursor;
|
|
2386
|
-
/** Pointer position in the layer's own space: canvas-local CSS px. */
|
|
2387
|
-
readonly at: {
|
|
2388
|
-
readonly x: number;
|
|
2389
|
-
readonly y: number;
|
|
2390
|
-
};
|
|
2391
|
-
}
|
|
2392
|
-
interface PaintedCursorState {
|
|
2393
|
-
setBase(cursor: PaintedCursor | null): void;
|
|
2394
|
-
setOverride(cursor: PaintedCursor | null): void;
|
|
2395
|
-
/** Canvas-local CSS px. */
|
|
2396
|
-
setPointer(x: number, y: number): void;
|
|
2397
|
-
/** Pointer left the surface: nothing to draw until it returns. */
|
|
2398
|
-
clearPointer(): void;
|
|
2399
|
-
/**
|
|
2400
|
-
* Whether a painted cursor is set at all, regardless of where the pointer is.
|
|
2401
|
-
*
|
|
2402
|
-
* Lets the pointer path skip measuring the canvas rect on every move in the
|
|
2403
|
-
* overwhelmingly common case where the compositor is drawing the cursor and
|
|
2404
|
-
* nothing here needs its position.
|
|
2405
|
-
*/
|
|
2406
|
-
active(): boolean;
|
|
2407
|
-
/** What the layer should draw this frame, or null for none. */
|
|
2408
|
-
current(): PaintedCursorFrame | null;
|
|
2409
|
-
/** Run `fn` whenever the answer to `current()` may have changed. */
|
|
2410
|
-
subscribe(fn: () => void): () => void;
|
|
2411
|
-
}
|
|
2412
|
-
declare function createPaintedCursorState(): PaintedCursorState;
|
|
2413
|
-
|
|
2414
|
-
/**
|
|
2415
|
-
* Everything about handling an input event that depends on *which view* it
|
|
2416
|
-
* landed in: the dispatcher that runs it, and the three lookups that resolve
|
|
2417
|
-
* a client point against that view's camera.
|
|
2418
|
-
*
|
|
2419
|
-
* @internal One per view. The hook builds the `id: null` one from its flat
|
|
2420
|
-
* options; `views` supplies the rest, and the hook chooses between them per
|
|
2421
|
-
* event, so that it — and its listener set — still mounts exactly once.
|
|
2422
|
-
*/
|
|
2423
|
-
interface DispatcherViewTarget {
|
|
2424
|
-
/** `null` is the root view — the whole canvas. Matches `ViewTarget.id`. */
|
|
2425
|
-
id: string | null;
|
|
2426
|
-
dispatcher: Dispatcher;
|
|
2427
|
-
affordanceAt: UseGestureDispatcherOptions['affordanceAt'];
|
|
2428
|
-
classifyTarget: UseGestureDispatcherOptions['classifyTarget'];
|
|
2429
|
-
clientToWorld: UseGestureDispatcherOptions['clientToWorld'];
|
|
2430
|
-
/**
|
|
2431
|
-
* The deps this view answers for itself — its camera, its selection, and
|
|
2432
|
-
* whatever else is per-view rather than per-canvas. Read per event; every
|
|
2433
|
-
* name it does not carry still resolves through the canvas registry.
|
|
2434
|
-
*
|
|
2435
|
-
* This is why a view does not get a `DepRegistryProvider` of its own. The
|
|
2436
|
-
* registry is where a consumer registers *sources*, and one per view would
|
|
2437
|
-
* fragment that: a consumer overriding `insert` would have to know how many
|
|
2438
|
-
* views exist and override each. An overlay keeps one place to register and
|
|
2439
|
-
* one authority per dep, with the view claiming only what is genuinely its.
|
|
2440
|
-
*
|
|
2441
|
-
* Without this a gesture inside a panel pans the whole canvas and selects
|
|
2442
|
-
* into the canvas's selection — correct coordinates alone do not make
|
|
2443
|
-
* routing correct.
|
|
2444
|
-
*/
|
|
2445
|
-
deps?: () => Partial<DepSchema>;
|
|
2446
|
-
/**
|
|
2447
|
-
* This view's chrome-caps rule context, for the eligibility filter. The rule
|
|
2448
|
-
* table is the surface's, but a rule keyed on selection or the in-flight
|
|
2449
|
-
* action answers per view — so an action hidden in one panel must not
|
|
2450
|
-
* decline a gesture in another. `undefined` means "nothing gates here", the
|
|
2451
|
-
* same answer a surface with no mode registry gives.
|
|
2452
|
-
*/
|
|
2453
|
-
getRuleCtx?: () => RuleCtx | undefined;
|
|
2454
|
-
}
|
|
2455
|
-
/**
|
|
2456
|
-
* The part of `features/viewports`' `ViewResolver` the dispatcher needs: which
|
|
2457
|
-
* view a client point belongs to, pinned to the view a gesture began in.
|
|
2458
|
-
*
|
|
2459
|
-
* @internal Structural on purpose — a `ViewResolver` satisfies it, and the
|
|
2460
|
-
* dispatcher stays free of the viewport module.
|
|
2461
|
-
*/
|
|
2462
|
-
interface ViewIdResolver {
|
|
2463
|
-
begin(pointerId: number, clientX: number, clientY: number): {
|
|
2464
|
-
id: string | null;
|
|
2465
|
-
};
|
|
2466
|
-
at(pointerId: number | null, clientX: number, clientY: number): {
|
|
2467
|
-
id: string | null;
|
|
2468
|
-
};
|
|
2469
|
-
end(pointerId: number): void;
|
|
2470
|
-
}
|
|
2471
|
-
/** Options for `useGestureDispatcher`: the element to listen on, the actions
|
|
2472
|
-
* and tools in play, and the hooks that turn raw DOM events into the world
|
|
2473
|
-
* coordinates and hit targets bindings match against. */
|
|
2474
|
-
interface UseGestureDispatcherOptions {
|
|
2475
|
-
/** Ref to the canvas element. Pointer/wheel/multitouch listeners attach here. */
|
|
2476
|
-
canvasRef: RefObject<HTMLElement | null>;
|
|
2477
|
-
/** Action registry (ActionsRegistry from registry.tsx). */
|
|
2478
|
-
actions: ActionsRegistry;
|
|
2479
|
-
/** Tool definitions keyed by id. Typically passes an empty Map. */
|
|
2480
|
-
toolsById: ReadonlyMap<string, Tool>;
|
|
2481
|
-
/** Default true. Set false to opt out of dispatcher wiring (e.g. demos that disable it). */
|
|
2482
|
-
enabled?: boolean;
|
|
2483
|
-
/**
|
|
2484
|
-
* Observer fired whenever the dispatcher synthesizes a double click, in
|
|
2485
|
-
* world coordinates. Runs BEFORE the event is dispatched and independently
|
|
2486
|
-
* of which binding (if any) handles it.
|
|
2487
|
-
*
|
|
2488
|
-
* This is deliberately not an Action. `<SceneCanvas onDoubleClick>` is a
|
|
2489
|
-
* notification — "the user double-clicked, here's what they hit" — and a
|
|
2490
|
-
* notification must not compete with behavior for the gesture. As a binding
|
|
2491
|
-
* it would lose to `enterPathEdit` on any body hit and silently never fire.
|
|
2492
|
-
* Routing it here keeps a single definition of "double click" (the point of
|
|
2493
|
-
* consolidating the kit's three detectors) without giving it
|
|
2494
|
-
* first-match-wins semantics it shouldn't have.
|
|
2495
|
-
*/
|
|
2496
|
-
onDoubleClick?: (world: {
|
|
2497
|
-
x: number;
|
|
2498
|
-
y: number;
|
|
2499
|
-
}) => void;
|
|
2500
|
-
/**
|
|
2501
|
-
* Default true. Set false to leave the window `keydown`/`keyup` listeners
|
|
2502
|
-
* unattached so keyboard-bound actions never dispatch — pointer, wheel, and
|
|
2503
|
-
* contextmenu channels stay live. `<SceneCanvas>` wires this to
|
|
2504
|
-
* `enableKeybindings`, so opting out of keybindings disables the modern
|
|
2505
|
-
* dispatcher key path as well as the legacy `useKeybindings` hook.
|
|
2506
|
-
*/
|
|
2507
|
-
keyboard?: boolean;
|
|
2508
|
-
/**
|
|
2509
|
-
* Optional affordance classifier. Called on every pointerdown with the
|
|
2510
|
-
* world-space coordinates of the pointer. Returns an `AffordanceHit` when
|
|
2511
|
-
* the pointer lands on a known affordance (resize handle, rotate handle, etc.)
|
|
2512
|
-
* or `null` when the pointer hit open canvas.
|
|
2513
|
-
*
|
|
2514
|
-
* The hit is packed into `InputEvent.pointerdown.affordance` and flows
|
|
2515
|
-
* through into `InvocationCtx.drag.affordance`. Action invokers that require
|
|
2516
|
-
* a specific affordance (e.g. `resizeAction` requires `handle:*`) use this
|
|
2517
|
-
* field as a guard in their `start` body.
|
|
2518
|
-
*
|
|
2519
|
-
* When omitted, `affordance` is always `undefined` — meaning only consumers
|
|
2520
|
-
* that explicitly wire a classifier get affordance-gated behavior.
|
|
2521
|
-
* `<SceneCanvas>` wires the full chrome→dispatcher bridge.
|
|
2522
|
-
*/
|
|
2523
|
-
affordanceAt?: (worldPoint: {
|
|
2524
|
-
x: number;
|
|
2525
|
-
y: number;
|
|
2526
|
-
}) => AffordanceHit | null;
|
|
2527
|
-
/**
|
|
2528
|
-
* Optional body classifier. Called on every pointerdown with the world-space
|
|
2529
|
-
* coordinates of the pointer. Its result is packed onto the event as
|
|
2530
|
-
* `bodyTarget` + `bodyKind`, which `matchTarget` reads to resolve the
|
|
2531
|
-
* string-form `TargetSpec` values in `Tool.bindings`.
|
|
2532
|
-
*
|
|
2533
|
-
* `body` is `'empty'` when nothing is under the pointer, `'selected-body'`
|
|
2534
|
-
* when the topmost hit belongs to the current selection, or
|
|
2535
|
-
* `'unselected-body'` when it belongs to a node that isn't selected. `kind`
|
|
2536
|
-
* is the hit node's semantic kind, when the scene can name it.
|
|
2537
|
-
*
|
|
2538
|
-
* When omitted, every body-derived target form (`'empty'`,
|
|
2539
|
-
* `'selected-body'`, `'unselected-body'`, `kind:<k>`, `kind:<k>:selected`)
|
|
2540
|
-
* never matches — bindings using those specs are silently skipped.
|
|
2541
|
-
* `<SceneCanvas>` wires this.
|
|
2542
|
-
*/
|
|
2543
|
-
classifyTarget?: (worldPoint: {
|
|
2544
|
-
x: number;
|
|
2545
|
-
y: number;
|
|
2546
|
-
}) => BodyClassification;
|
|
2547
|
-
/**
|
|
2548
|
-
* Optional pre-created `Dispatcher`. When provided, this hook pumps events
|
|
2549
|
-
* into the supplied instance instead of creating its own. Lets a parent
|
|
2550
|
-
* scope (e.g. `<SceneCanvas>`) share one dispatcher between the gesture
|
|
2551
|
-
* mounter and other consumers (the preview-ghost layer).
|
|
2552
|
-
*/
|
|
2553
|
-
dispatcher?: Dispatcher;
|
|
2554
|
-
/**
|
|
2555
|
-
* Converts a client-space pointer position (e.g. `e.clientX`, `e.clientY`)
|
|
2556
|
-
* to world-space coordinates. When supplied, every pointer/wheel event's
|
|
2557
|
-
* `x`/`y` is converted before the dispatcher builds `InvocationCtx.world`.
|
|
2558
|
-
*
|
|
2559
|
-
* Without this, `ctx.world` is populated with the raw client coords, which
|
|
2560
|
-
* silently breaks any action whose overlay/output uses absolute world
|
|
2561
|
-
* positions (marquee, lasso polyline, world-space affordances). Actions
|
|
2562
|
-
* that only read `drag.delta` are unaffected because client→world deltas
|
|
2563
|
-
* are equal at scale 1, but as soon as a consumer pans/zooms the view the
|
|
2564
|
-
* deltas diverge too.
|
|
2565
|
-
*
|
|
2566
|
-
* `<SceneCanvas>` always wires this via its canvas rect + current view.
|
|
2567
|
-
* Tests / harnesses without a view can omit it and continue passing raw
|
|
2568
|
-
* coordinates as before.
|
|
2569
|
-
*/
|
|
2570
|
-
clientToWorld?: (clientX: number, clientY: number) => {
|
|
2571
|
-
x: number;
|
|
2572
|
-
y: number;
|
|
2573
|
-
};
|
|
2574
|
-
/**
|
|
2575
|
-
* Invoked once per pump event (`pointermove`, `pointerup`, `pointercancel`,
|
|
2576
|
-
* `key-held` up-phase, `multitouch` move) when a dispatcher-side handle is
|
|
2577
|
-
* in flight. Lets the host canvas schedule a redraw so dispatcher-only
|
|
2578
|
-
* overlays (marquee, lasso, preview-ghost) repaint on each frame.
|
|
2579
|
-
*
|
|
2580
|
-
* Required because dispatcher actions don't go through the legacy
|
|
2581
|
-
* `tools.dispatcher.onGestureChange` redraw bump that ambient tool drags
|
|
2582
|
-
* relied on. Without it, the overlay layer's `draw` never runs between
|
|
2583
|
-
* pointerdown and pointerup, and the chrome flashes once at gesture start
|
|
2584
|
-
* and then sits frozen until the gesture ends.
|
|
2585
|
-
*
|
|
2586
|
-
* `<SceneCanvas>` wires this to the canvas's `requestRedraw`. Test
|
|
2587
|
-
* harnesses can omit it; their dispatchers won't paint between events but
|
|
2588
|
-
* that's already the test contract.
|
|
2589
|
-
*/
|
|
2590
|
-
requestRedraw?: () => void;
|
|
2591
|
-
/**
|
|
2592
|
-
* The surface's painted-cursor channel, read live because the canvas handle
|
|
2593
|
-
* it lives on arrives a render after this hook runs.
|
|
2594
|
-
*
|
|
2595
|
-
* Given one, a cursor the CSS tier cannot express — sized in world units, or
|
|
2596
|
-
* past the size the browser drops the image at — is published here and drawn
|
|
2597
|
-
* by the painted-cursor layer instead. Without one, such a cursor resolves to
|
|
2598
|
-
* `none` and the pointer shows nothing.
|
|
2599
|
-
*/
|
|
2600
|
-
paintedCursor?: () => PaintedCursorState | undefined;
|
|
2601
|
-
/**
|
|
2602
|
-
* Thunk returning the live `RuleCtx` for the current frame. When supplied,
|
|
2603
|
-
* the dispatcher filters matched candidates by their declared
|
|
2604
|
-
* `Action.eligible` rule (omitted => always eligible). `<SceneCanvas>`
|
|
2605
|
-
* wires this; tests / harnesses without chrome-caps state can omit it.
|
|
2606
|
-
*/
|
|
2607
|
-
getRuleCtx?: () => RuleCtx | undefined;
|
|
2608
|
-
/**
|
|
2609
|
-
* Routing for a canvas hosting more than one view: the non-root dispatch
|
|
2610
|
-
* records to choose between, read fresh per event, and the resolver that
|
|
2611
|
-
* chooses. Omit for a single view — then every event runs on the record the
|
|
2612
|
-
* flat options above describe, which is what they are: view zero.
|
|
2613
|
-
*
|
|
2614
|
-
* A resolved id with no live record falls back to the root, so a view that
|
|
2615
|
-
* unmounts mid-gesture degrades instead of dropping the event.
|
|
2616
|
-
*
|
|
2617
|
-
* Keyboard and paste have no coordinates to resolve; they run on the view
|
|
2618
|
-
* the last coordinate-bearing event resolved to.
|
|
2619
|
-
*
|
|
2620
|
-
* @internal
|
|
2621
|
-
*/
|
|
2622
|
-
views?: {
|
|
2623
|
-
targets: () => readonly DispatcherViewTarget[];
|
|
2624
|
-
resolver: ViewIdResolver;
|
|
2625
|
-
};
|
|
2626
|
-
}
|
|
2627
|
-
/**
|
|
2628
|
-
* Attach the input pipeline to a canvas: DOM pointer, wheel, keyboard and
|
|
2629
|
-
* multitouch listeners in, normalized input events out, routed through the
|
|
2630
|
-
* dispatcher to whichever action a binding names.
|
|
2631
|
-
*
|
|
2632
|
-
* Everything it needs beyond its options — the active tool, the dep registry —
|
|
2633
|
-
* comes from context, so it must be mounted inside `<SceneCanvas>`'s
|
|
2634
|
-
* providers.
|
|
2635
|
-
*/
|
|
2636
|
-
declare function useGestureDispatcher(opts: UseGestureDispatcherOptions): void;
|
|
2637
|
-
|
|
2638
2756
|
/**
|
|
2639
2757
|
* The one place weasel decides whether a frame may run, so that "a loop does no
|
|
2640
2758
|
* work nobody can see" holds by construction rather than by every loop author
|
|
@@ -2738,14 +2856,6 @@ declare function wheelPan(view: View, delta: {
|
|
|
2738
2856
|
/** Pure reducer: the whole wheel convention in one call. */
|
|
2739
2857
|
declare function computeWheelAction(view: View, input: WheelInput, clamp?: ZoomClampOpts, opts?: Pick<WheelPanOpts, 'axis'>): View;
|
|
2740
2858
|
|
|
2741
|
-
/**
|
|
2742
|
-
* Convert client coords to element CSS-pixel coords (relative to the element's
|
|
2743
|
-
* top-left). Apps drawing in CSS-pixel space feed the result directly into
|
|
2744
|
-
* world math when pan/zoom is identity. With pan/zoom, compose this with
|
|
2745
|
-
* your inverse-viewport transform.
|
|
2746
|
-
*/
|
|
2747
|
-
declare function clientToCanvas(canvas: HTMLElement, clientX: number, clientY: number): [number, number];
|
|
2748
|
-
|
|
2749
2859
|
/** Records recent deltas and reports the current velocity, averaged over the
|
|
2750
2860
|
* last 100ms — the throw speed a momentum decay starts from. */
|
|
2751
2861
|
interface VelocityTracker {
|
|
@@ -2785,93 +2895,28 @@ declare function usePinchGesture(canvasRef: React.RefObject<HTMLElement | null>,
|
|
|
2785
2895
|
declare function interpolateView(from: View, to: View): (t: number) => View;
|
|
2786
2896
|
|
|
2787
2897
|
/**
|
|
2788
|
-
*
|
|
2789
|
-
*
|
|
2790
|
-
* This used to be a translator: `ToolDef` carried `initial` / `engaged` phase
|
|
2791
|
-
* tables of hit-keyed route handlers, and `defineTool` compiled them into the
|
|
2792
|
-
* imperative `pointer` / `drag` / `keyboard` / `wheel` handlers the
|
|
2793
|
-
* tool-routing dispatcher called. Both ends of that are gone — tools declare
|
|
2794
|
-
* `bindings` and the gesture dispatcher routes them — so what remains is
|
|
2795
|
-
* identity plumbing plus the id check and the cursor resolver.
|
|
2898
|
+
* The routing types that carry an overlay, bound to the kit's `RenderLayer`.
|
|
2796
2899
|
*
|
|
2797
|
-
*
|
|
2798
|
-
*
|
|
2799
|
-
*
|
|
2900
|
+
* `@weasel-js/routing` never reads an overlay — it collects the live ones and
|
|
2901
|
+
* hands them back in scope order — so it leaves the element type open. What a
|
|
2902
|
+
* weasel canvas draws is a `RenderLayer`, and every kit call site should see
|
|
2903
|
+
* that rather than `unknown`, so core binds the parameter once, here, and
|
|
2904
|
+
* re-exports these names under the ones they have always had.
|
|
2800
2905
|
*/
|
|
2801
|
-
declare function defineTool<TScratch = void>(def: ToolDef<TScratch>): Tool<TScratch>;
|
|
2802
2906
|
|
|
2803
|
-
/**
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
* more than the type gymnastics it replaced.
|
|
2815
|
-
*/
|
|
2907
|
+
/** What a canvas overlay is, at this layer. */
|
|
2908
|
+
type Overlay = RenderLayer<unknown>;
|
|
2909
|
+
type Contribution = Contribution$1<Overlay>;
|
|
2910
|
+
type ContributionChrome = ContributionChrome$1<Overlay>;
|
|
2911
|
+
type Tool<TScratch = unknown> = Tool$1<TScratch, Overlay>;
|
|
2912
|
+
type AnyTool = AnyToolOf<Overlay>;
|
|
2913
|
+
type ToolDef<TScratch = void> = ToolDef$1<TScratch, Overlay>;
|
|
2914
|
+
type ViewportToolDef<TScratch = void> = ViewportToolDef$1<TScratch, Overlay>;
|
|
2915
|
+
type ToolsApi = ToolsApi$1<Overlay>;
|
|
2916
|
+
type UseToolsOptions = UseToolsOptions$1<Overlay>;
|
|
2917
|
+
declare function defineTool<TScratch = void>(def: ToolDef<TScratch>): Tool<TScratch>;
|
|
2816
2918
|
declare function defineViewportTool<TScratch = void>(def: ViewportToolDef<TScratch>): Tool<TScratch>;
|
|
2817
|
-
|
|
2818
|
-
/** Options for `useTools`: which tools exist, which one starts active, and
|
|
2819
|
-
* which run continuously regardless of the active one. */
|
|
2820
|
-
interface UseToolsOptions {
|
|
2821
|
-
/** Initial active-slot tool id. Must exist in `registry`. */
|
|
2822
|
-
active: string;
|
|
2823
|
-
/** Tools eligible for the active slot or hotkey slot. The keys are the
|
|
2824
|
-
* tool ids; the values are the tool records. A tool with `hotkey` set
|
|
2825
|
-
* is wired into the hotkey slot whenever the engagement state matches. */
|
|
2826
|
-
registry: Record<string, AnyTool>;
|
|
2827
|
-
/** Always-on tools — listen continuously regardless of active slot. */
|
|
2828
|
-
ambient?: AnyTool[];
|
|
2829
|
-
}
|
|
2830
|
-
/** The tool registry's runtime surface: which tool is active, which is
|
|
2831
|
-
* temporarily held by a hotkey, and how to change either. */
|
|
2832
|
-
interface ToolsApi {
|
|
2833
|
-
/** Current active-slot tool id. */
|
|
2834
|
-
active: string;
|
|
2835
|
-
/** Set the active-slot tool. The gesture dispatcher watches the active
|
|
2836
|
-
* tool and cancels any in-flight handle itself. */
|
|
2837
|
-
setActive: (id: string) => void;
|
|
2838
|
-
/** Currently hotkey-engaged tool id (or `null`). Derived as the top of
|
|
2839
|
-
* the hotkey stack for backwards compat with the pre-stack API. */
|
|
2840
|
-
hotkeyEngaged: string | null;
|
|
2841
|
-
/** Engage a hotkey-slot tool by id. */
|
|
2842
|
-
engageHotkey: (id: string) => void;
|
|
2843
|
-
/** Disengage the hotkey-slot tool, if any. */
|
|
2844
|
-
disengageHotkey: () => void;
|
|
2845
|
-
/** All always-on tools, in registration order. */
|
|
2846
|
-
ambient: readonly AnyTool[];
|
|
2847
|
-
/** Full registry — for userland UI (palette buttons, etc.). */
|
|
2848
|
-
registry: Readonly<Record<string, AnyTool>>;
|
|
2849
|
-
/** Returns true if a tool with the given id is in the registry or ambient list. */
|
|
2850
|
-
has(id: string): boolean;
|
|
2851
|
-
/** All overlay layers from currently-engaged tools (active slot, hotkey
|
|
2852
|
-
* slot if engaged, all ambient slot tools) that declare `position`.
|
|
2853
|
-
* Filters out tools with no `overlay` field. Order: active, then hotkey
|
|
2854
|
-
* (if engaged), then ambient (registration order). */
|
|
2855
|
-
getActiveOverlays(position?: OverlayPosition): RenderLayer<unknown>[];
|
|
2856
|
-
}
|
|
2857
|
-
/**
|
|
2858
|
-
* Manages the active tool and hotkey slot.
|
|
2859
|
-
*
|
|
2860
|
-
* A thin shim over {@link useContributions}: the `registry` / `ambient`
|
|
2861
|
-
* arguments are restated as declared eligibility (`focus` / `always`), and
|
|
2862
|
-
* assembly happens in one place for tools and non-tool contributions alike.
|
|
2863
|
-
*
|
|
2864
|
-
* Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /
|
|
2865
|
-
* `<SceneCanvas>`, which mount one internally) in scope: active/hotkey state
|
|
2866
|
-
* lives in the context so the gesture dispatcher and any sibling
|
|
2867
|
-
* `useTools` calls all read the same source of truth.
|
|
2868
|
-
*
|
|
2869
|
-
* **First-mount-wins semantics**: if `opts.active` differs from the context
|
|
2870
|
-
* default (`'select'`) on first mount, `useTools` pushes `opts.active` to
|
|
2871
|
-
* the context. Subsequent mounts respect whatever the context currently
|
|
2872
|
-
* holds (the first caller wins).
|
|
2873
|
-
*/
|
|
2874
|
-
declare function useTools(opts: UseToolsOptions): ToolsApi;
|
|
2919
|
+
declare const useTools: (opts: UseToolsOptions) => ToolsApi;
|
|
2875
2920
|
|
|
2876
2921
|
/** Options for `useKeybindings`. */
|
|
2877
2922
|
interface UseKeybindingsOptions {
|
|
@@ -2927,6 +2972,9 @@ interface ToolPrefBase<K extends string, Value> {
|
|
|
2927
2972
|
}
|
|
2928
2973
|
/** How a schema-driven UI should present a number pref. */
|
|
2929
2974
|
type ToolPrefNumberControl = 'input' | 'slider';
|
|
2975
|
+
/** How a schema-driven UI should show a number pref's value. `compact`
|
|
2976
|
+
* abbreviates from a thousand up, as in `2.0M`. */
|
|
2977
|
+
type ToolPrefNumberFormat = 'plain' | 'compact';
|
|
2930
2978
|
/** How a schema-driven UI should present a boolean pref. */
|
|
2931
2979
|
type ToolPrefBooleanControl = 'checkbox' | 'switch' | 'toggle';
|
|
2932
2980
|
/** How a schema-driven UI should present a string pref. */
|
|
@@ -2941,7 +2989,21 @@ interface ToolPrefNumberUnit {
|
|
|
2941
2989
|
fromDisplay: (display: number) => number;
|
|
2942
2990
|
/** Shown after the input, e.g. `'°'`. */
|
|
2943
2991
|
suffix?: string;
|
|
2992
|
+
/** Suffixes a person may type, each mapped to the factor that turns a
|
|
2993
|
+
* number in that unit into a display number: `{ mm: 0.1, cm: 1 }` for a
|
|
2994
|
+
* field showing centimeters. */
|
|
2995
|
+
accepts?: Readonly<Record<string, number>>;
|
|
2944
2996
|
}
|
|
2997
|
+
/**
|
|
2998
|
+
* A display unit built from a {@link UnitSystem}: values are stored in the
|
|
2999
|
+
* system's base and shown in `display`, rounded to `precision` places when
|
|
3000
|
+
* given, and every unit in the system is accepted as typed text. `suffix`
|
|
3001
|
+
* defaults to the unit's name and is accepted too.
|
|
3002
|
+
*/
|
|
3003
|
+
declare function prefUnit(system: UnitSystem, display: Unit, opts?: {
|
|
3004
|
+
precision?: number;
|
|
3005
|
+
suffix?: string;
|
|
3006
|
+
}): ToolPrefNumberUnit;
|
|
2945
3007
|
/** A numeric pref, optionally bounded and stepped, and optionally stored in a
|
|
2946
3008
|
* different unit from the one shown. */
|
|
2947
3009
|
interface ToolPrefNumber extends ToolPrefBase<'number', number> {
|
|
@@ -2949,6 +3011,7 @@ interface ToolPrefNumber extends ToolPrefBase<'number', number> {
|
|
|
2949
3011
|
max?: number;
|
|
2950
3012
|
step?: number;
|
|
2951
3013
|
control?: ToolPrefNumberControl;
|
|
3014
|
+
format?: ToolPrefNumberFormat;
|
|
2952
3015
|
unit?: ToolPrefNumberUnit;
|
|
2953
3016
|
}
|
|
2954
3017
|
/** An on/off pref. */
|
|
@@ -3096,21 +3159,144 @@ interface ToolPrefGroup {
|
|
|
3096
3159
|
children: Record<string, ToolPrefLeaf | ToolPrefGroup>;
|
|
3097
3160
|
}
|
|
3098
3161
|
|
|
3162
|
+
/**
|
|
3163
|
+
* `DebugSink`, `HitShape` and `HandleKind` are declared in
|
|
3164
|
+
* `@weasel-js/routing` — `ToolCtx.debug` carries a sink, so routing has to
|
|
3165
|
+
* name the type. Re-exported here, beside the overlay that reads one.
|
|
3166
|
+
*/
|
|
3167
|
+
|
|
3168
|
+
/** One bit per debug feature; absent keys are off. */
|
|
3169
|
+
interface DebugConfig {
|
|
3170
|
+
hitboxes?: boolean;
|
|
3171
|
+
handles?: boolean;
|
|
3172
|
+
bounds?: boolean;
|
|
3173
|
+
origins?: boolean;
|
|
3174
|
+
snap?: boolean;
|
|
3175
|
+
layers?: boolean;
|
|
3176
|
+
/** Render each tracked node's id as a label at the top-left of its
|
|
3177
|
+
* bounds. Pulls from the same `recordBounds` stream `bounds` uses, so
|
|
3178
|
+
* no extra sink calls are required to enable. */
|
|
3179
|
+
ids?: boolean;
|
|
3180
|
+
/** Rolling FPS counter rendered in the top-left corner of the canvas.
|
|
3181
|
+
* Tracks the rate at which the debug overlay's draw callback runs;
|
|
3182
|
+
* this matches the canvas's effective repaint rate. */
|
|
3183
|
+
fps?: boolean;
|
|
3184
|
+
/** Optional per-feature color overrides; falls back to the default theme. */
|
|
3185
|
+
theme?: Partial<DebugTheme>;
|
|
3186
|
+
/** Optional per-feature line-width / dash overrides; falls back to
|
|
3187
|
+
* {@link DEFAULT_DEBUG_STROKES}. */
|
|
3188
|
+
strokes?: Partial<DebugStrokes>;
|
|
3189
|
+
}
|
|
3190
|
+
/** The name of one debug-overlay feature — the keys of {@link DebugConfig}
|
|
3191
|
+
* that toggle a visualization. */
|
|
3192
|
+
type DebugFeature = 'hitboxes' | 'handles' | 'bounds' | 'origins' | 'snap' | 'layers' | 'ids' | 'fps';
|
|
3193
|
+
/** Colors the debug overlay draws with, one entry per feature. */
|
|
3194
|
+
interface DebugTheme {
|
|
3195
|
+
hitboxFill: string;
|
|
3196
|
+
hitboxStroke: string;
|
|
3197
|
+
handle: string;
|
|
3198
|
+
bounds: string;
|
|
3199
|
+
origin: string;
|
|
3200
|
+
snap: string;
|
|
3201
|
+
layerText: string;
|
|
3202
|
+
layerTextBg: string;
|
|
3203
|
+
/** Color for the per-node id label rendered when `config.ids` is on. */
|
|
3204
|
+
idText: string;
|
|
3205
|
+
/** Foreground / background for the FPS panel. */
|
|
3206
|
+
fpsText: string;
|
|
3207
|
+
fpsTextBg: string;
|
|
3208
|
+
}
|
|
3209
|
+
/** Line width and dash pattern for one stroked debug feature. An empty (or
|
|
3210
|
+
* omitted) `dash` is a solid line. */
|
|
3211
|
+
interface DebugStroke {
|
|
3212
|
+
width: number;
|
|
3213
|
+
dash?: readonly number[];
|
|
3214
|
+
}
|
|
3215
|
+
/** The stroked half of the debug overlay's appearance, split from
|
|
3216
|
+
* {@link DebugTheme} because only some features draw a line at all — text
|
|
3217
|
+
* panels and filled origin dots take color and nothing else. */
|
|
3218
|
+
interface DebugStrokes {
|
|
3219
|
+
hitbox: DebugStroke;
|
|
3220
|
+
bounds: DebugStroke;
|
|
3221
|
+
handle: DebugStroke;
|
|
3222
|
+
/** Rejected snap candidates only; accepted ones paint as a filled dot. */
|
|
3223
|
+
snap: DebugStroke;
|
|
3224
|
+
}
|
|
3225
|
+
/** A hit region tested during the current frame. */
|
|
3226
|
+
interface RecordedHitbox {
|
|
3227
|
+
id: string;
|
|
3228
|
+
kind: 'body' | 'handle' | 'rotation' | 'anchor';
|
|
3229
|
+
shape: HitShape;
|
|
3230
|
+
}
|
|
3231
|
+
/** A handle drawn during the current frame, and where. */
|
|
3232
|
+
interface RecordedHandle {
|
|
3233
|
+
id: string;
|
|
3234
|
+
position: {
|
|
3235
|
+
x: number;
|
|
3236
|
+
y: number;
|
|
3237
|
+
};
|
|
3238
|
+
kind: HandleKind;
|
|
3239
|
+
}
|
|
3240
|
+
/** A node's bounds as computed during the current frame. */
|
|
3241
|
+
interface RecordedBounds {
|
|
3242
|
+
id: string;
|
|
3243
|
+
bounds: {
|
|
3244
|
+
x: number;
|
|
3245
|
+
y: number;
|
|
3246
|
+
width: number;
|
|
3247
|
+
height: number;
|
|
3248
|
+
};
|
|
3249
|
+
}
|
|
3250
|
+
/** A node's transform origin as used during the current frame. */
|
|
3251
|
+
interface RecordedOrigin {
|
|
3252
|
+
id: string;
|
|
3253
|
+
point: {
|
|
3254
|
+
x: number;
|
|
3255
|
+
y: number;
|
|
3256
|
+
};
|
|
3257
|
+
}
|
|
3258
|
+
/** A snap candidate considered during the current gesture, and whether it
|
|
3259
|
+
* won. Unlike the other records these survive across frames, until the
|
|
3260
|
+
* gesture ends. */
|
|
3261
|
+
interface RecordedSnap {
|
|
3262
|
+
point: {
|
|
3263
|
+
x: number;
|
|
3264
|
+
y: number;
|
|
3265
|
+
};
|
|
3266
|
+
accepted: boolean;
|
|
3267
|
+
}
|
|
3268
|
+
/** A render layer that drew during the current frame. */
|
|
3269
|
+
interface RecordedLayer {
|
|
3270
|
+
id: string;
|
|
3271
|
+
label: string;
|
|
3272
|
+
space: 'world' | 'screen';
|
|
3273
|
+
index: number;
|
|
3274
|
+
}
|
|
3275
|
+
/** Everything the sink collected, ready for the overlay to draw. */
|
|
3276
|
+
interface DebugSnapshot {
|
|
3277
|
+
hitboxes: RecordedHitbox[];
|
|
3278
|
+
handles: RecordedHandle[];
|
|
3279
|
+
bounds: RecordedBounds[];
|
|
3280
|
+
origins: RecordedOrigin[];
|
|
3281
|
+
snap: RecordedSnap[];
|
|
3282
|
+
layers: RecordedLayer[];
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3099
3285
|
/** Options for `useSelectTool`: how a point resolves to nodes, how a click
|
|
3100
3286
|
* chooses among them, and the appearance of the marquee. */
|
|
3101
3287
|
interface UseSelectToolOptions<TPose> {
|
|
3102
3288
|
/** Return ids of all objects whose painted body covers (worldX, worldY).
|
|
3103
3289
|
* Order doesn't matter — the tool collapses parent/child overlap via
|
|
3104
|
-
* `pickTopMostHit`. When omitted, defaults to
|
|
3105
|
-
*
|
|
3106
|
-
*
|
|
3107
|
-
* (path / polygon hit-tests). */
|
|
3290
|
+
* `pickTopMostHit`. When omitted, defaults to an AABB-vs-point scan over
|
|
3291
|
+
* `adapter.getNodes()` using the pose descriptor. Override for tighter
|
|
3292
|
+
* shapes (path / polygon hit-tests). */
|
|
3108
3293
|
pickEvery?: (worldX: number, worldY: number) => string[];
|
|
3109
3294
|
/** Optional alt-aware selection-update hit returning the single id the
|
|
3110
3295
|
* click should act on. */
|
|
3111
3296
|
pickBest?: (worldX: number, worldY: number, alt: boolean, selection: readonly string[]) => string | null;
|
|
3112
|
-
/**
|
|
3113
|
-
|
|
3297
|
+
/** How to read poses for the default `pickEvery`. Default
|
|
3298
|
+
* `AUTO_POSE_DESCRIPTOR`. */
|
|
3299
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
3114
3300
|
/**
|
|
3115
3301
|
* How the default `pickEvery` decides a **leaf** node covers the pointer.
|
|
3116
3302
|
* Ignored when `pickEvery` is supplied.
|
|
@@ -3141,6 +3327,13 @@ interface UseSelectToolOptions<TPose> {
|
|
|
3141
3327
|
* Without some slop a hairline outline is an unhittable target.
|
|
3142
3328
|
*/
|
|
3143
3329
|
pickTolerance?: number;
|
|
3330
|
+
/** Painted alpha per node in the view this tool picks for. A node painted
|
|
3331
|
+
* at alpha 0 is not under the pointer. Ignored when `pickEvery` is
|
|
3332
|
+
* supplied. */
|
|
3333
|
+
alphaOf?: (id: string) => number;
|
|
3334
|
+
/** Whether a node's `layer` reaches the screen in the view this tool picks
|
|
3335
|
+
* for. Ignored when `pickEvery` is supplied. */
|
|
3336
|
+
layerIsPainted?: (layer: string) => boolean;
|
|
3144
3337
|
/** Move-action options. The move gesture is dispatcher-routed,
|
|
3145
3338
|
* so only `behaviors` is consumed here — threaded into the move binding's
|
|
3146
3339
|
* `opts.behaviors`. Other `UseMoveOptions` fields are accepted for API shape
|
|
@@ -3699,25 +3892,387 @@ interface PencilPoint {
|
|
|
3699
3892
|
* `{ kind: 'pencil', samples }`. The kit's default `insert` dep runs
|
|
3700
3893
|
* `schneiderFit` over the samples to produce a cubic-Bezier path.
|
|
3701
3894
|
*/
|
|
3702
|
-
declare function usePencilTool(): Tool<null>;
|
|
3895
|
+
declare function usePencilTool(): Tool<null>;
|
|
3896
|
+
|
|
3897
|
+
/**
|
|
3898
|
+
* Live state read by chrome-visibility {@link Condition}s. Backward-compat
|
|
3899
|
+
* alias for the legacy ChromeCtx shape — kept for consumers that still
|
|
3900
|
+
* import `ChromeCtx`. Subset of `RuleCtx`: legacy ChromeCtx didn't carry
|
|
3901
|
+
* mode/capability info. The resolver builds a `RuleCtx` for evaluation;
|
|
3902
|
+
* surfaces that still operate in `ChromeCtx` shape supply defaults
|
|
3903
|
+
* (mode='normal', empty allowedCapabilities) at the construction site.
|
|
3904
|
+
*/
|
|
3905
|
+
interface ChromeCtx {
|
|
3906
|
+
readonly focused: boolean;
|
|
3907
|
+
readonly selection: readonly NodeId[];
|
|
3908
|
+
readonly multiActive: boolean;
|
|
3909
|
+
readonly modifiers: ModifierState;
|
|
3910
|
+
readonly action: {
|
|
3911
|
+
readonly kind: string | null;
|
|
3912
|
+
readonly id: string | null;
|
|
3913
|
+
};
|
|
3914
|
+
readonly hover: NodeId | null;
|
|
3915
|
+
readonly view: View;
|
|
3916
|
+
}
|
|
3917
|
+
/**
|
|
3918
|
+
* Composable visibility predicate with fluent surface. Carries its underlying
|
|
3919
|
+
* `Rule` tree at `.rule` so the resolver can introspect / share trees with
|
|
3920
|
+
* the affordance pipeline and the dispatcher's eligibility filter.
|
|
3921
|
+
*
|
|
3922
|
+
* Callable form `cond(ctx)` evaluates the tree against ctx. The fluent
|
|
3923
|
+
* methods return new Conditions wrapping new trees.
|
|
3924
|
+
*
|
|
3925
|
+
* **Chain semantics: strict left-to-right, no precedence.**
|
|
3926
|
+
* `a.and(b).or(c)` is `(a && b) || c`; `a.or(b).and(c)` is
|
|
3927
|
+
* `(a || b) && c`. Mix `.and` and `.or` only when you mean
|
|
3928
|
+
* left-to-right evaluation. For grouped disjunction, name the
|
|
3929
|
+
* subexpression or use the top-level `or(...)`.
|
|
3930
|
+
*/
|
|
3931
|
+
interface Condition {
|
|
3932
|
+
(ctx: RuleCtx): boolean;
|
|
3933
|
+
readonly rule: Rule;
|
|
3934
|
+
/** `this && other` */
|
|
3935
|
+
and(other: Condition | Rule): Condition;
|
|
3936
|
+
/** `this || other` */
|
|
3937
|
+
or(other: Condition | Rule): Condition;
|
|
3938
|
+
/** `this && !other` */
|
|
3939
|
+
andNot(other: Condition | Rule): Condition;
|
|
3940
|
+
/** `this || !other` */
|
|
3941
|
+
orNot(other: Condition | Rule): Condition;
|
|
3942
|
+
}
|
|
3943
|
+
/**
|
|
3944
|
+
* Stable identifier for one user-visible chrome element. The same id
|
|
3945
|
+
* gates both paint and hit-test — there is no separate
|
|
3946
|
+
* `affordance.X` / `selection.X` split — so toggling a rule cannot
|
|
3947
|
+
* leave a visually-present but un-hittable handle (or vice versa).
|
|
3948
|
+
*
|
|
3949
|
+
* Naming convention by lifecycle:
|
|
3950
|
+
*
|
|
3951
|
+
* - `selection.*` — chrome reflecting committed selection state
|
|
3952
|
+
* (persists between actions).
|
|
3953
|
+
* - `action.*` — chrome that only exists during an in-flight
|
|
3954
|
+
* action (vanishes on commit / cancel).
|
|
3955
|
+
* - `snap.*` — snapping system chrome (guides, target highlights).
|
|
3956
|
+
* - `grid`, `debug.*` — environment chrome.
|
|
3957
|
+
*
|
|
3958
|
+
* The intersection `(string & {})` keeps the union open so consumers
|
|
3959
|
+
* can register their own ids; the kit's built-ins are listed
|
|
3960
|
+
* explicitly for autocomplete.
|
|
3961
|
+
*/
|
|
3962
|
+
type ChromeId = 'selection.outline' | 'selection.resize-handles' | 'selection.rotation-handle' | 'action.marquee' | 'action.lasso' | 'action.move-ghosts' | 'action.insert-preview' | 'action.polyline' | 'snap.guides' | 'snap.targets' | 'grid' | (string & {});
|
|
3963
|
+
/**
|
|
3964
|
+
* Consumer override map. Merged on top of the kit's
|
|
3965
|
+
* `defaultVisibilityRules`; absent keys fall through to defaults,
|
|
3966
|
+
* absent ids fall through to `always`. Entries may be either fluent
|
|
3967
|
+
* `Condition` instances OR raw `Rule` trees — the resolver normalizes.
|
|
3968
|
+
*/
|
|
3969
|
+
type VisibilityRules = Partial<Record<ChromeId, Condition | Rule>>;
|
|
3970
|
+
|
|
3971
|
+
/**
|
|
3972
|
+
* Promote a Rule tree to a fluent Condition. The function form evaluates
|
|
3973
|
+
* the tree against a RuleCtx; combinator methods produce new Conditions
|
|
3974
|
+
* wrapping `all`/`any`/`not` nodes.
|
|
3975
|
+
*
|
|
3976
|
+
* **Chain semantics: strict left-to-right.** No boolean precedence.
|
|
3977
|
+
* `focused.or(hovering).and(selectionIs(1))` evaluates
|
|
3978
|
+
* `((focused || hovering) && selectionIs(1))` — NOT
|
|
3979
|
+
* `(focused || (hovering && selectionIs(1)))` as standard precedence
|
|
3980
|
+
* would give. For grouped disjunction, use the top-level `or` / `and` /
|
|
3981
|
+
* `not` helpers or name intermediates.
|
|
3982
|
+
*
|
|
3983
|
+
* Combinators flatten same-kind nesting on construction so `a.and(b).and(c)`
|
|
3984
|
+
* produces `{ all: [a, b, c] }` rather than `{ all: [{ all: [a, b] }, c] }`.
|
|
3985
|
+
* Canonical form simplifies downstream introspection.
|
|
3986
|
+
*
|
|
3987
|
+
* Use {@link when} for the inline-lambda escape hatch.
|
|
3988
|
+
*/
|
|
3989
|
+
declare function cond(rule: Rule): Condition;
|
|
3990
|
+
/** Inline-lambda escape hatch. Wraps the closure as a `when` rule node. */
|
|
3991
|
+
declare function when(fn: (ctx: RuleCtx) => boolean): Condition;
|
|
3992
|
+
/** `(a && b && c && ...)` — useful when chain mixing makes left-to-right
|
|
3993
|
+
* semantics ambiguous. */
|
|
3994
|
+
declare function and(...cs: (Condition | Rule)[]): Condition;
|
|
3995
|
+
/** `(a || b || c || ...)` — preferred over `.or` chains when mixed with
|
|
3996
|
+
* `.and` to make grouping explicit. */
|
|
3997
|
+
declare function or(...cs: (Condition | Rule)[]): Condition;
|
|
3998
|
+
/** `!c` — top-level negation. Most rules use `.andNot()` / `.orNot()`
|
|
3999
|
+
* instead; this is for the lead-with-negation case. */
|
|
4000
|
+
declare function not(c: Condition | Rule): Condition;
|
|
4001
|
+
/** Always true. The fallback for any chrome id without a registered rule. */
|
|
4002
|
+
declare const always: Condition;
|
|
4003
|
+
/** Always false. Useful for "turn this chrome off entirely":
|
|
4004
|
+
* `chromeVisibility={{ 'snap.guides': never }}`. */
|
|
4005
|
+
declare const never: Condition;
|
|
4006
|
+
/** Canvas surface currently focused. */
|
|
4007
|
+
declare const focused: Condition;
|
|
4008
|
+
/** Any action currently in flight (read: user is gesturing). */
|
|
4009
|
+
declare const gesturing: Condition;
|
|
4010
|
+
/** Active action's kind matches `kind` (e.g. `actionIs('move')`). */
|
|
4011
|
+
declare const actionIs: (kind: string) => Condition;
|
|
4012
|
+
/** Nothing selected. */
|
|
4013
|
+
declare const selectionEmpty: Condition;
|
|
4014
|
+
/** Exactly `n` items selected. */
|
|
4015
|
+
declare const selectionIs: (n: number) => Condition;
|
|
4016
|
+
/** At least `n` items selected. `selectionAtLeast(1)` is the common
|
|
4017
|
+
* "something is selected" check. */
|
|
4018
|
+
declare const selectionAtLeast: (n: number) => Condition;
|
|
4019
|
+
/** Multi-mode handle behavior active (single shared union-bounds
|
|
4020
|
+
* handle vs per-item handles). Implemented as a `when` because
|
|
4021
|
+
* `multiActive` is a derived single-call read on RuleCtx, not a
|
|
4022
|
+
* selector-table key. Stable; safe to introspect. */
|
|
4023
|
+
declare const multiActive: Condition;
|
|
4024
|
+
/** Pointer is hovering some node. */
|
|
4025
|
+
declare const hovering: Condition;
|
|
4026
|
+
/** Pointer is hovering a node that is currently selected. */
|
|
4027
|
+
declare const hoveringSelected: Condition;
|
|
4028
|
+
/** Named modifier key currently held. */
|
|
4029
|
+
declare const modifierHeld: (m: keyof ModifierState) => Condition;
|
|
4030
|
+
/** View scale (uniform or geometric mean for non-uniform) is at least
|
|
4031
|
+
* `z`. Useful for "hide hairline chrome at low zoom" rules. */
|
|
4032
|
+
declare const zoomAtLeast: (z: number) => Condition;
|
|
4033
|
+
/** Active mode equals `m`. */
|
|
4034
|
+
declare const modeIs: (m: string) => Condition;
|
|
4035
|
+
/** Active mode is one of `modes`. */
|
|
4036
|
+
declare const modeIn: (modes: readonly string[]) => Condition;
|
|
4037
|
+
/** Active mode is NOT `m`. */
|
|
4038
|
+
declare const modeNot: (m: string) => Condition;
|
|
4039
|
+
/** Active mode's `allows` includes capability `cap`. */
|
|
4040
|
+
declare const capabilityIs: (cap: string) => Condition;
|
|
4041
|
+
/** Active mode's `allows` includes ANY of `caps` (OR). */
|
|
4042
|
+
declare const capabilityIn: (caps: readonly string[]) => Condition;
|
|
4043
|
+
/** Active mode's `allows` includes ALL of `caps` (AND). */
|
|
4044
|
+
declare const capabilityAll: (caps: readonly string[]) => Condition;
|
|
4045
|
+
/** Active mode's `allows` does NOT include capability `cap`. */
|
|
4046
|
+
declare const capabilityNot: (cap: string) => Condition;
|
|
4047
|
+
/** Primary pointer is imprecise (touch, most styluses). Absent device
|
|
4048
|
+
* profile → false, so a rule written with this atom is inert on the
|
|
4049
|
+
* mouse-shaped default rather than silently flipping. */
|
|
4050
|
+
declare const coarsePointer: Condition;
|
|
4051
|
+
/** Primary pointer can hover. Absent device profile → true. Pair with
|
|
4052
|
+
* `not(...)` to gate chrome that only makes sense with a hovering
|
|
4053
|
+
* pointer: `not(canHover)` is "this device cannot hover". */
|
|
4054
|
+
declare const canHover: Condition;
|
|
4055
|
+
|
|
4056
|
+
/**
|
|
4057
|
+
* Kit-shipped defaults. Merged with the consumer's `chromeVisibility` map
|
|
4058
|
+
* at resolve time; consumer entries take precedence per id.
|
|
4059
|
+
*
|
|
4060
|
+
* Written as literal Rule trees rather than fluent chains so the inputs
|
|
4061
|
+
* each rule depends on are immediately visible. The fluent atoms compile
|
|
4062
|
+
* to the same trees; either form is valid in a VisibilityRules entry.
|
|
4063
|
+
*
|
|
4064
|
+
* Gating is written in terms of **capabilities, not mode ids**. A
|
|
4065
|
+
* capability rule keeps holding when a new mode is added that permits the
|
|
4066
|
+
* same thing; a mode rule has to be found and edited every time. There is
|
|
4067
|
+
* no `mode:` rule left in this table — the `path-edit.*` chrome used to be
|
|
4068
|
+
* the exception, on the theory that it's the visual signature of one mode;
|
|
4069
|
+
* see the comment on those rules below for why that was wrong in both
|
|
4070
|
+
* directions and what replaced it.
|
|
4071
|
+
*
|
|
4072
|
+
* Chrome that gates on the *absence* of a capability (the selection
|
|
4073
|
+
* outline, suppressed while an anchor-editing overlay owns the visuals)
|
|
4074
|
+
* uses `capability: { not: … }` for the same reason.
|
|
4075
|
+
*/
|
|
4076
|
+
declare const defaultVisibilityRules: VisibilityRules;
|
|
4077
|
+
|
|
4078
|
+
/**
|
|
4079
|
+
* Build the per-frame visibility check. Merges consumer rules on top
|
|
4080
|
+
* of the kit defaults, then closes over `ctx` so each chrome-id
|
|
4081
|
+
* lookup runs its rule against the current state.
|
|
4082
|
+
*
|
|
4083
|
+
* `VisibilityRules` entries may be either fluent `Condition` values
|
|
4084
|
+
* (callable) or raw `Rule` trees — we normalize at lookup time.
|
|
4085
|
+
*
|
|
4086
|
+
* Predicates are O(1) and run once per chrome id per frame; no
|
|
4087
|
+
* memoization in v1 — profile before adding any.
|
|
4088
|
+
*
|
|
4089
|
+
* `ChromeCtx` is the legacy shape; surfaces still on it get `mode='normal'`
|
|
4090
|
+
* and `DEFAULT_ALLOWED_CAPABILITIES` filled in here, so a caller that never
|
|
4091
|
+
* opted into modality behaves exactly like one sitting in normal mode.
|
|
4092
|
+
*/
|
|
4093
|
+
declare function resolveVisibility(consumer: VisibilityRules | undefined, ctx: ChromeCtx | RuleCtx): (id: ChromeId) => boolean;
|
|
4094
|
+
|
|
4095
|
+
/**
|
|
4096
|
+
* Pure assembler for {@link ChromeCtx}.
|
|
4097
|
+
*
|
|
4098
|
+
* Called once per frame on the rendering side from whichever surface
|
|
4099
|
+
* needs to evaluate visibility rules — `composeAffordanceLayer`,
|
|
4100
|
+
* `createSelectionOverlayLayer`, the dispatcher overlay layer, etc.
|
|
4101
|
+
*
|
|
4102
|
+
* Sources are passed as plain getters / values rather than the live
|
|
4103
|
+
* objects they come from. This keeps `chrome-caps` from depending on
|
|
4104
|
+
* React, the dispatcher's concrete type, or `ChromeState`'s bounds
|
|
4105
|
+
* machinery — the same builder works from a test harness, a Storybook
|
|
4106
|
+
* fixture, or `<SceneCanvas>`.
|
|
4107
|
+
*/
|
|
4108
|
+
|
|
4109
|
+
/** The pieces of live canvas state a `ChromeCtx` is assembled from. */
|
|
4110
|
+
interface BuildChromeCtxArgs {
|
|
4111
|
+
focused: boolean;
|
|
4112
|
+
selection: readonly NodeId[];
|
|
4113
|
+
multiActive: boolean;
|
|
4114
|
+
modifiers: ModifierState;
|
|
4115
|
+
action: {
|
|
4116
|
+
kind: string | null;
|
|
4117
|
+
id: string | null;
|
|
4118
|
+
};
|
|
4119
|
+
hover: NodeId | null;
|
|
4120
|
+
view: View;
|
|
4121
|
+
}
|
|
4122
|
+
/** Gather the current canvas state into the context that chrome-visibility
|
|
4123
|
+
* rules are evaluated against. Rebuilt per frame. */
|
|
4124
|
+
declare function buildChromeCtx(args: BuildChromeCtxArgs): ChromeCtx;
|
|
4125
|
+
|
|
4126
|
+
/**
|
|
4127
|
+
* useHoverTracking — last-hovered NodeId for chrome-caps rules.
|
|
4128
|
+
*
|
|
4129
|
+
* Attaches a `pointermove` listener to the supplied canvas; on each move it
|
|
4130
|
+
* runs the supplied `nodeAtClientPoint` and caches the resulting id on a ref.
|
|
4131
|
+
* Cleared on `pointerleave` (pointer left the canvas → nothing is hovered).
|
|
4132
|
+
*
|
|
4133
|
+
* Returns a stable getter — call once per frame from `buildChromeCtx`.
|
|
4134
|
+
*
|
|
4135
|
+
* No re-render: the ref updates silently, and the next render that
|
|
4136
|
+
* reads it picks up the fresh value. Chrome-caps rules are evaluated
|
|
4137
|
+
* during paint, so the hover state is always read fresh.
|
|
4138
|
+
*/
|
|
4139
|
+
|
|
4140
|
+
/** Options for `useHoverTracking`. */
|
|
4141
|
+
interface UseHoverTrackingArgs {
|
|
4142
|
+
canvasRef: RefObject<HTMLElement | null>;
|
|
4143
|
+
/** Topmost id under a client point, or null. One lookup rather than a
|
|
4144
|
+
* client→world thunk beside a world-space picker: a screen-pixel pick
|
|
4145
|
+
* tolerance converts against the camera the point resolved to, and two
|
|
4146
|
+
* thunks are two chances to disagree about which view that is. */
|
|
4147
|
+
nodeAtClientPoint: (clientX: number, clientY: number) => {
|
|
4148
|
+
id: NodeId;
|
|
4149
|
+
} | null;
|
|
4150
|
+
enabled?: boolean;
|
|
4151
|
+
}
|
|
4152
|
+
/** Track which node the pointer is over. Returns a getter rather than state,
|
|
4153
|
+
* so per-frame code can read the current value without the hover re-rendering
|
|
4154
|
+
* the component on every pointer move. */
|
|
4155
|
+
declare function useHoverTracking(args: UseHoverTrackingArgs): () => NodeId | null;
|
|
4156
|
+
|
|
4157
|
+
/** Standard slot names — render in this canonical order.
|
|
4158
|
+
* `cellHighlight` is internal: emitted from the `grid` slot's nested
|
|
4159
|
+
* `highlight` config, not a top-level layer key. */
|
|
4160
|
+
/** @internal */
|
|
4161
|
+
declare const STANDARD_SLOTS: readonly ["grid", "cellHighlight", "scene", "selectionOverlay"];
|
|
4162
|
+
/** Names of the slots `<Canvas>` supports out of the box (excluding the implicit cell-highlight overlay). */
|
|
4163
|
+
type StandardSlotName = Exclude<(typeof STANDARD_SLOTS)[number], 'cellHighlight'>;
|
|
4164
|
+
/** Custom layer entry — any key not in `STANDARD_SLOTS`. The presence of
|
|
4165
|
+
* `.layer` discriminates this from a slot config. */
|
|
4166
|
+
interface CustomLayerEntry {
|
|
4167
|
+
layer: RenderLayer<unknown>;
|
|
4168
|
+
/** Insert immediately after the named standard slot or another custom-layer key. */
|
|
4169
|
+
after?: StandardSlotName | (string & {});
|
|
4170
|
+
/** Insert immediately before the named standard slot or another custom-layer key. */
|
|
4171
|
+
before?: StandardSlotName | (string & {});
|
|
4172
|
+
}
|
|
4173
|
+
|
|
4174
|
+
/** A rect on the surface, in CSS pixels from the canvas top-left. */
|
|
4175
|
+
interface ViewRect {
|
|
4176
|
+
x: number;
|
|
4177
|
+
y: number;
|
|
4178
|
+
w: number;
|
|
4179
|
+
h: number;
|
|
4180
|
+
}
|
|
4181
|
+
/** Props for `<CanvasView>`. @experimental */
|
|
4182
|
+
interface CanvasViewProps {
|
|
4183
|
+
/** Identifies the view to the surface and to input routing. Must be unique
|
|
4184
|
+
* among the views on one canvas. */
|
|
4185
|
+
id: string;
|
|
4186
|
+
/** Where this view paints, recomputed every frame so the rect can track the
|
|
4187
|
+
* outer camera. A plain rect is accepted for a fixed panel. */
|
|
4188
|
+
bounds: ViewRect | ((outer: View, dims: Dims) => ViewRect);
|
|
4189
|
+
/** Camera. Supply this to control it; otherwise the view keeps its own,
|
|
4190
|
+
* seeded from `defaultView`. `onViewChange` fires either way.
|
|
4191
|
+
*
|
|
4192
|
+
* A thunk is a camera derived from the canvas's — a loupe following the
|
|
4193
|
+
* pointer — read fresh at every paint and every event, so the two cannot
|
|
4194
|
+
* disagree mid-gesture. It is controlled: a pan inside the view reaches
|
|
4195
|
+
* only `onViewChange`. */
|
|
4196
|
+
view?: View | ((outer: View, dims: Dims) => View);
|
|
4197
|
+
defaultView?: View;
|
|
4198
|
+
onViewChange?: (v: View) => void;
|
|
4199
|
+
/** Pan limits, applied to every camera change the same way `<Canvas>`
|
|
4200
|
+
* applies its own. */
|
|
4201
|
+
viewBounds?: Bounds;
|
|
4202
|
+
/** Which of the surface's layers this view paints. Defaults to all of them —
|
|
4203
|
+
* the same content through a second camera. */
|
|
4204
|
+
layers?: (surface: readonly RenderLayer<unknown>[]) => readonly RenderLayer<unknown>[];
|
|
4205
|
+
/**
|
|
4206
|
+
* Show or hide layers in this view only, by id — the map `<Canvas>` takes,
|
|
4207
|
+
* applied after `layers` narrows the stack. A scene layer paints as
|
|
4208
|
+
* `scene:<layerId>`; one hidden here neither paints nor picks in this view,
|
|
4209
|
+
* and a marquee or Cmd+A routed here passes over it. The surface and every
|
|
4210
|
+
* other view are unaffected.
|
|
4211
|
+
*/
|
|
4212
|
+
layerVisibility?: Record<string, boolean>;
|
|
4213
|
+
/** Draw order for this view, by layer id, bottom first. A listed order is
|
|
4214
|
+
* the whole list, so a layer left out of it is neither painted nor picked
|
|
4215
|
+
* here. */
|
|
4216
|
+
layerOrder?: string[];
|
|
4217
|
+
/** Opaque ground painted before the source layers, so the surface does not
|
|
4218
|
+
* show through where the inner camera sees nothing. */
|
|
4219
|
+
background?: string;
|
|
4220
|
+
/** Paint and hit order. Defaults to `Infinity` — after every view the
|
|
4221
|
+
* surface declared as a prop. */
|
|
4222
|
+
order?: number;
|
|
4223
|
+
/** Label for debug overlays. Defaults to the id. */
|
|
4224
|
+
label?: string;
|
|
4225
|
+
/**
|
|
4226
|
+
* Whether input over the view resolves through its camera. Default `true`:
|
|
4227
|
+
* a press selects what the view shows, and a drag moves it in the view's
|
|
4228
|
+
* world units. `false` paints only, and input over it reaches the canvas
|
|
4229
|
+
* beneath as though the view were not there.
|
|
4230
|
+
*
|
|
4231
|
+
* Views do not nest. A view paints and routes the surface's own stack,
|
|
4232
|
+
* never another view; overlapping views are hit in paint order.
|
|
4233
|
+
*/
|
|
4234
|
+
interactive?: boolean;
|
|
4235
|
+
/**
|
|
4236
|
+
* Whether the surface paints the view. Default `true`. `false` is for a
|
|
4237
|
+
* host that draws the view inside chrome of its own — a HUD window's
|
|
4238
|
+
* interior — through `SceneCanvasApi.addView`'s `draw`, so it lands in
|
|
4239
|
+
* that chrome's z-order rather than the surface's.
|
|
4240
|
+
*/
|
|
4241
|
+
paint?: boolean;
|
|
4242
|
+
/** A selection of this view's own, which actions dispatched inside it read
|
|
4243
|
+
* and write instead of the surface's. Omit both this and
|
|
4244
|
+
* `selectionOptions` and the view shares the surface's selection — the
|
|
4245
|
+
* default, so undo restores one selection rather than N. */
|
|
4246
|
+
selection?: SelectionApi;
|
|
4247
|
+
/** Opts this view into owning a selection, configured thus. Ignored when
|
|
4248
|
+
* `selection` is supplied. */
|
|
4249
|
+
selectionOptions?: UseSelectionOptions;
|
|
4250
|
+
}
|
|
4251
|
+
/**
|
|
4252
|
+
* @experimental
|
|
4253
|
+
*
|
|
4254
|
+
* One view on a shared canvas. Owns a camera, contributes the viewport node
|
|
4255
|
+
* that paints it, and registers the dispatch record that sends gestures inside
|
|
4256
|
+
* its rect to that camera rather than to the canvas's.
|
|
4257
|
+
*
|
|
4258
|
+
* Renders nothing itself — it is a declaration, and the surface does the
|
|
4259
|
+
* drawing. Outside a surface that mounts a view registry it is inert.
|
|
4260
|
+
*/
|
|
4261
|
+
declare function CanvasView(props: CanvasViewProps): null;
|
|
3703
4262
|
|
|
3704
|
-
/**
|
|
3705
|
-
*
|
|
3706
|
-
*
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
after?: StandardSlotName | (string & {});
|
|
3717
|
-
/** Insert immediately before the named standard slot or another custom-layer key. */
|
|
3718
|
-
before?: StandardSlotName | (string & {});
|
|
4263
|
+
/**
|
|
4264
|
+
* A view added through {@link SceneCanvasApi.addView}.
|
|
4265
|
+
* @experimental
|
|
4266
|
+
*/
|
|
4267
|
+
interface CanvasViewHandle {
|
|
4268
|
+
readonly id: string;
|
|
4269
|
+
/** Paint the view for one frame of the canvas: its layers through its own
|
|
4270
|
+
* camera, clipped to its rect. For a view added with `paint: false`, whose
|
|
4271
|
+
* host draws it; empty until the view has mounted. */
|
|
4272
|
+
draw(data: unknown, outer: View, dims: Dims): DrawCommand[];
|
|
4273
|
+
/** Stop painting and routing the view. */
|
|
4274
|
+
remove(): void;
|
|
3719
4275
|
}
|
|
3720
|
-
|
|
3721
4276
|
/**
|
|
3722
4277
|
* The **base imperative ref handle** shared by the canvas components. For
|
|
3723
4278
|
* `<SceneCanvas>` refs use {@link SceneCanvasApi} (this type plus the
|
|
@@ -3751,8 +4306,23 @@ interface CanvasExtensionApi {
|
|
|
3751
4306
|
*
|
|
3752
4307
|
* Under `paintInto` this is the caller's shared canvas, which co-tenant
|
|
3753
4308
|
* panes also paint into: its rect is the whole surface, not this pane's, so
|
|
3754
|
-
* read geometry off {@link element} rather than off this
|
|
4309
|
+
* read geometry off {@link element} rather than off this, and find this
|
|
4310
|
+
* pane's pixels on it with {@link getSurfaceRect}. */
|
|
3755
4311
|
readonly surface: HTMLCanvasElement | null;
|
|
4312
|
+
/**
|
|
4313
|
+
* The rect of {@link surface} this canvas paints into, in the surface's CSS
|
|
4314
|
+
* px — the rect the renderer is confined to. Under `paintInto` that is the
|
|
4315
|
+
* pane's `x`/`y` and this canvas's size; otherwise the whole canvas at the
|
|
4316
|
+
* origin. A point measured against {@link element} sits at
|
|
4317
|
+
* `(x + px, y + py)` on the surface, which is where a readback must look.
|
|
4318
|
+
* Read live: the value is the one the next paint uses.
|
|
4319
|
+
*/
|
|
4320
|
+
getSurfaceRect(): {
|
|
4321
|
+
x: number;
|
|
4322
|
+
y: number;
|
|
4323
|
+
width: number;
|
|
4324
|
+
height: number;
|
|
4325
|
+
};
|
|
3756
4326
|
requestRedraw(): void;
|
|
3757
4327
|
/**
|
|
3758
4328
|
* Run `fn` after every paint, on the frame that painted — for chrome that
|
|
@@ -3837,6 +4407,10 @@ interface CanvasExtensionApi {
|
|
|
3837
4407
|
x: number;
|
|
3838
4408
|
y: number;
|
|
3839
4409
|
}): void;
|
|
4410
|
+
/** Add a view to the canvas from outside React. See
|
|
4411
|
+
* {@link SceneCanvasApi.addView}; absent on the bare-primitive handle,
|
|
4412
|
+
* which hosts no views. */
|
|
4413
|
+
addView?(props: CanvasViewProps): CanvasViewHandle;
|
|
3840
4414
|
}
|
|
3841
4415
|
/**
|
|
3842
4416
|
* The imperative ref handle for `<SceneCanvas>` — everything on
|
|
@@ -3860,6 +4434,16 @@ interface SceneCanvasApi extends CanvasExtensionApi {
|
|
|
3860
4434
|
/** Cancel a camera animation. The view stays where it is. */
|
|
3861
4435
|
stopViewAnimation(): void;
|
|
3862
4436
|
isViewAnimating(): boolean;
|
|
4437
|
+
/**
|
|
4438
|
+
* Add a view — the same declaration as a `<CanvasView>` child, for code
|
|
4439
|
+
* outside React: chrome that opens a lens, a panel a plugin owns. Input over
|
|
4440
|
+
* it resolves through its camera unless `interactive` is `false`.
|
|
4441
|
+
*
|
|
4442
|
+
* Pass thunks for `bounds` and `view` rather than re-adding to move it.
|
|
4443
|
+
* Adding an id already present replaces that view.
|
|
4444
|
+
* @experimental
|
|
4445
|
+
*/
|
|
4446
|
+
addView(props: CanvasViewProps): CanvasViewHandle;
|
|
3863
4447
|
}
|
|
3864
4448
|
|
|
3865
4449
|
/**
|
|
@@ -4067,7 +4651,10 @@ interface CanvasHelpers<TPose> extends CanvasViewHelpers<TPose>, CanvasSurfaceHe
|
|
|
4067
4651
|
* Built-in entries (`kit:text`, `kit:path`, `kit:rect-fallback`) are
|
|
4068
4652
|
* registered at module load. Consumer entries added via
|
|
4069
4653
|
* `registerNodeShape` join the chain; the first entry whose
|
|
4070
|
-
* `matches` predicate returns true paints the node.
|
|
4654
|
+
* `matches` predicate returns true paints the node. Every built-in but
|
|
4655
|
+
* `kit:derived` additionally requires a rect-shaped pose — a scene whose
|
|
4656
|
+
* poses are some other shape matches none of them, and paints through a
|
|
4657
|
+
* consumer painter or not at all.
|
|
4071
4658
|
*
|
|
4072
4659
|
* Two priority tiers:
|
|
4073
4660
|
* - `'high'` — checked before all `'normal'` entries. Use this to
|
|
@@ -4101,6 +4688,10 @@ interface NodePaintCtx {
|
|
|
4101
4688
|
* the wrapper hands such a node the caller's own ctx untouched. `null`
|
|
4102
4689
|
* means the node derives but has nothing to draw. */
|
|
4103
4690
|
derivedPath?: Path | null;
|
|
4691
|
+
/** A node's animated per-anchor colors: given the colors a painter would paint
|
|
4692
|
+
* on `channel`, the colors to paint instead. **Absent** when nothing animates
|
|
4693
|
+
* the node. The kit's path painters apply it; see `withColorOverrides`. */
|
|
4694
|
+
vertexColors?: (channel: VertexColorChannel, base: readonly number[] | undefined) => readonly number[] | undefined;
|
|
4104
4695
|
}
|
|
4105
4696
|
/**
|
|
4106
4697
|
* Per-node draw function — the scene-slot `drawOne` signature shared by
|
|
@@ -4120,7 +4711,9 @@ interface NodeShapeEntry<TData = unknown, TPose = unknown> {
|
|
|
4120
4711
|
* something descriptive: `'kit:text'`, `'app:image'`, etc. */
|
|
4121
4712
|
id: string;
|
|
4122
4713
|
/** Returns true when this painter renders the node. The first matching
|
|
4123
|
-
* painter (`'high'` tier first, then `'normal'`) wins.
|
|
4714
|
+
* painter (`'high'` tier first, then `'normal'`) wins. The kit's own
|
|
4715
|
+
* painters also require a rect-shaped pose, since their geometry reads
|
|
4716
|
+
* `x`/`y`/`width`/`height` off it. */
|
|
4124
4717
|
matches(node: Node$1<TData, string, TPose>): boolean;
|
|
4125
4718
|
/** Emits the draw commands for the node's primary visual. `ctx` is an
|
|
4126
4719
|
* optional per-call paint context (see `NodePaintCtx`); painters that
|
|
@@ -4278,11 +4871,9 @@ declare function getNodeShapes(): readonly NodeShapeEntry[];
|
|
|
4278
4871
|
* `createSelectionOverlayLayer` is a thin convenience that returns a single
|
|
4279
4872
|
* `RenderLayer` whose draw runs the outline pass then the handles pass.
|
|
4280
4873
|
*
|
|
4281
|
-
* **Pose shape:** TPose is generic; callers
|
|
4282
|
-
*
|
|
4283
|
-
*
|
|
4284
|
-
* `boundsOfPath`. Container ids reduce via `unionAABB` over the projected
|
|
4285
|
-
* AABBs.
|
|
4874
|
+
* **Pose shape:** TPose is generic; callers pass `poseDescriptor` for poses
|
|
4875
|
+
* `AUTO_POSE_DESCRIPTOR` can't read. Container ids reduce via `unionAABB`
|
|
4876
|
+
* over the projected AABBs.
|
|
4286
4877
|
*/
|
|
4287
4878
|
|
|
4288
4879
|
/** Options for `composeSelectionPose`. */
|
|
@@ -4304,19 +4895,8 @@ interface ComposeSelectionPoseOpts<TPose> {
|
|
|
4304
4895
|
} | null;
|
|
4305
4896
|
/** Fallback pose lookup (typically the stored/committed pose). */
|
|
4306
4897
|
getStoredPose: (id: string) => TPose;
|
|
4307
|
-
/**
|
|
4308
|
-
|
|
4309
|
-
* into a single union AABB. Defaults to the identity — rect-shaped poses
|
|
4310
|
-
* (`{x, y, width, height}`) need no override. For `Path` poses pass
|
|
4311
|
-
* `boundsOfPath`.
|
|
4312
|
-
*/
|
|
4313
|
-
getBounds?: (pose: TPose) => Bounds;
|
|
4314
|
-
/**
|
|
4315
|
-
* Wrap an AABB back into a TPose. Called only when the resolver collapses
|
|
4316
|
-
* a container's leaves into a single union AABB. Defaults to the identity —
|
|
4317
|
-
* for `Path` poses pass `(b) => ({ kind: 'rect', ...b })`.
|
|
4318
|
-
*/
|
|
4319
|
-
fromBounds?: (bounds: Bounds) => TPose;
|
|
4898
|
+
/** How to read poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
4899
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
4320
4900
|
/** Walk a container's direct children (e.g. `scene.childrenOf`). With
|
|
4321
4901
|
* `isContainer`, a selected container resolves to the union AABB of its
|
|
4322
4902
|
* transitive leaf poses instead of its own stored pose. */
|
|
@@ -4336,12 +4916,8 @@ declare function composeSelectionPose<TPose>(opts: ComposeSelectionPoseOpts<TPos
|
|
|
4336
4916
|
* declared on {@link SelectionOverlayLayerOpts}, which makes both optional —
|
|
4337
4917
|
* omitted, they come off the draw envelope. */
|
|
4338
4918
|
interface SelectionLayerCommon<TPose> {
|
|
4339
|
-
/**
|
|
4340
|
-
|
|
4341
|
-
* poses (`{x, y, width, height}`) need no override. For `Path` poses pass
|
|
4342
|
-
* `boundsOfPath`.
|
|
4343
|
-
*/
|
|
4344
|
-
getBounds?: (pose: TPose) => Bounds;
|
|
4919
|
+
/** How to read poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
4920
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
4345
4921
|
/** Walk a container's direct children (e.g. `scene.childrenOf`). When
|
|
4346
4922
|
* supplied with `isContainer`, any id that resolves to a container is
|
|
4347
4923
|
* rendered using the union bounds of all its transitive leaves. */
|
|
@@ -4439,6 +5015,10 @@ interface HierarchicalAdapter<TNode, TPose> {
|
|
|
4439
5015
|
getNode(id: string): TNode | undefined;
|
|
4440
5016
|
getChildren(parentId: string | null): readonly string[];
|
|
4441
5017
|
getPose(id: string): TPose;
|
|
5018
|
+
/** Folds a child's local pose into its parent's frame. Absent means the
|
|
5019
|
+
* scene stores absolute poses and a parent contributes no transform —
|
|
5020
|
+
* see `PoseComposition`. */
|
|
5021
|
+
composePose?(parent: TPose, child: TPose): TPose;
|
|
4442
5022
|
}
|
|
4443
5023
|
|
|
4444
5024
|
/**
|
|
@@ -4618,16 +5198,15 @@ interface CanvasProps<TNode extends {
|
|
|
4618
5198
|
*/
|
|
4619
5199
|
selection?: SelectionApi;
|
|
4620
5200
|
/**
|
|
4621
|
-
*
|
|
4622
|
-
* the
|
|
4623
|
-
* non-rect poses (e.g. `Path`) don't require per-prop overrides.
|
|
5201
|
+
* How to read and rewrite a pose. Drives the default `boundsOf` fallback and
|
|
5202
|
+
* the selection-overlay bounds.
|
|
4624
5203
|
* Defaults to the rect identity (`AUTO_POSE_DESCRIPTOR`).
|
|
4625
5204
|
*
|
|
4626
5205
|
* This is a math helper, not a scene-shaped concern — it converts a pose
|
|
4627
5206
|
* value to an AABB and extracts rotation for the selection chrome. Bare-
|
|
4628
5207
|
* Canvas consumers that use a non-rect pose type should supply this.
|
|
4629
5208
|
*/
|
|
4630
|
-
|
|
5209
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
4631
5210
|
/**
|
|
4632
5211
|
* Used by `PickHud` to display the list of ids under the cursor.
|
|
4633
5212
|
* NOT used for tool routing — see `getNodeAtPoint` for that.
|
|
@@ -4637,7 +5216,7 @@ interface CanvasProps<TNode extends {
|
|
|
4637
5216
|
pickEvery?: (worldX: number, worldY: number) => string | string[] | null;
|
|
4638
5217
|
/**
|
|
4639
5218
|
* Override for committed bounds lookup. When supplied, takes precedence over
|
|
4640
|
-
* the `
|
|
5219
|
+
* the `poseDescriptor`-derived fallback. Used by the selection overlay, the
|
|
4641
5220
|
* multi-select union AABB, and `helpersRef.getEffectiveBounds`. Optional —
|
|
4642
5221
|
* bare-Canvas consumers that use a custom bounds shape should supply this;
|
|
4643
5222
|
* `<SceneCanvas>` derives it from its scene adapter and passes it via the
|
|
@@ -4902,6 +5481,12 @@ interface ReorderAdapter {
|
|
|
4902
5481
|
* touch an adapter directly. */
|
|
4903
5482
|
type SceneCanvasAdapter<TData, TLayer extends string, TPose> = MoveAdapter<Node$1<TData, TLayer, TPose>, TPose> & ResizeAdapter<Node$1<TData, TLayer, TPose>, TPose> & RotateAdapter<Node$1<TData, TLayer, TPose>, TPose> & AreaSelectAdapter & LassoSelectAdapter & LayerEnumerableAdapter<TLayer> & ReorderAdapter & Partial<InsertAdapter<Node$1<TData, TLayer, TPose>>> & {
|
|
4904
5483
|
getParent(id: string): string | null;
|
|
5484
|
+
/** The node's pose with every ancestor's frame folded in. Equal to
|
|
5485
|
+
* `getPose` unless a `poseComposition` is configured. */
|
|
5486
|
+
getWorldPose(id: string): TPose;
|
|
5487
|
+
/** Present only when a composing strategy is configured; the render
|
|
5488
|
+
* walk feature-detects it. */
|
|
5489
|
+
composePose?(parent: TPose, child: TPose): TPose;
|
|
4905
5490
|
getSelection(): string[];
|
|
4906
5491
|
setSelection(ids: string[]): void;
|
|
4907
5492
|
insertNode(node: Node$1<TData, TLayer, TPose>, index?: number): void;
|
|
@@ -4941,10 +5526,8 @@ interface SceneToAdapterOptions<TData, TLayer extends string, TPose> {
|
|
|
4941
5526
|
* fine for read-only or selection-less canvases, but the marquee gesture
|
|
4942
5527
|
* won't update any external selection state. */
|
|
4943
5528
|
selection?: SceneAdapterSelection;
|
|
4944
|
-
/**
|
|
4945
|
-
|
|
4946
|
-
* poses. */
|
|
4947
|
-
poseBounds?: (pose: TPose) => Bounds;
|
|
5529
|
+
/** How to read and rewrite this scene's poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
5530
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
4948
5531
|
/** Layout strategies keyed by container node id. When a container is
|
|
4949
5532
|
* configured here, `move` runs its layout-aware pass on drag (reflow on
|
|
4950
5533
|
* enter, reflow leftovers on exit, reparent + write reflowed poses on
|
|
@@ -4952,14 +5535,16 @@ interface SceneToAdapterOptions<TData, TLayer extends string, TPose> {
|
|
|
4952
5535
|
* either a static map, or a `getLayout(id)` function for dynamic
|
|
4953
5536
|
* resolution. */
|
|
4954
5537
|
layouts?: Record<string, LayoutStrategy<TPose>> | ((containerId: string) => LayoutStrategy<TPose> | null);
|
|
4955
|
-
/** When
|
|
4956
|
-
*
|
|
4957
|
-
*
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
*
|
|
4961
|
-
*
|
|
4962
|
-
|
|
5538
|
+
/** When true, `setPose` on a container translates every descendant by the
|
|
5539
|
+
* same delta, through the pose descriptor. Scene v1 stores absolute poses,
|
|
5540
|
+
* so without it children stay behind. */
|
|
5541
|
+
cascadeContainerPose?: boolean;
|
|
5542
|
+
/** How a child's stored pose folds into its parent's frame. Omit for the
|
|
5543
|
+
* absolute-pose model, where a parent contributes no transform. Supplying a
|
|
5544
|
+
* composing strategy makes a container's pose a **frame**: rotating the
|
|
5545
|
+
* container rotates its contents, and `setPose` on it must not also
|
|
5546
|
+
* translate them, so it cannot be combined with `cascadeContainerPose`. */
|
|
5547
|
+
poseComposition?: PoseComposition<TPose>;
|
|
4963
5548
|
}
|
|
4964
5549
|
/** Derive the adapter for a scene. Reads go straight to the scene; writes are
|
|
4965
5550
|
* ops applied through its history, so anything done through the adapter is
|
|
@@ -4984,27 +5569,17 @@ declare function useSceneAdapter<TData, TLayer extends string, TPose>(scene: Sce
|
|
|
4984
5569
|
* Consumers should import from here directly; `rotate.ts` re-exports the
|
|
4985
5570
|
* same symbols for back-compat. */
|
|
4986
5571
|
|
|
4987
|
-
/** Projects a pose to and from a rotated bounding box, so the rotate action
|
|
4988
|
-
* can work on pose shapes that carry rotation differently. */
|
|
4989
|
-
interface RotateGeometry<TPose> {
|
|
4990
|
-
getRotatedBounds(pose: TPose): RotatedPose;
|
|
4991
|
-
/** Write a new rotation back into the pose; bounds stay the same. */
|
|
4992
|
-
withRotation(pose: TPose, rotation: number): TPose;
|
|
4993
|
-
}
|
|
4994
5572
|
/** Options for the `rotate` action. */
|
|
4995
5573
|
interface UseRotateOptions<TPose> {
|
|
4996
5574
|
/** Behaviors are typed against the pose shape; the kit ships none yet
|
|
4997
5575
|
* (rotation snap behaviors are deferred). For non-rect TPose, behaviors
|
|
4998
|
-
* are typed `never`
|
|
5576
|
+
* are typed `never` for a pose without a numeric `rotation`. */
|
|
4999
5577
|
behaviors?: TPose extends RotatedPose ? RotateBehavior<TPose>[] : never;
|
|
5000
5578
|
rotateLabel?: string;
|
|
5001
5579
|
/** Reserved; rotate is never transient in practice. Ignored. */
|
|
5002
5580
|
transient?: boolean;
|
|
5003
5581
|
onGestureStart?: (id: string) => void;
|
|
5004
5582
|
onGestureEnd?: (committed: boolean) => void;
|
|
5005
|
-
/** Project pose ↔ rotated bounds. Defaults to the identity for
|
|
5006
|
-
* `RotatedPose`. Required for non-rect TPose (e.g. a rotated path). */
|
|
5007
|
-
geometry?: RotateGeometry<TPose>;
|
|
5008
5583
|
/** Optional debug sink. When supplied, records the rotation-handle
|
|
5009
5584
|
* position + circular hitbox at gesture start. Tree-shakes via
|
|
5010
5585
|
* optional-chain when omitted. */
|
|
@@ -5025,60 +5600,95 @@ interface UseRotateOptions<TPose> {
|
|
|
5025
5600
|
pivot?: 'each' | 'union';
|
|
5026
5601
|
}
|
|
5027
5602
|
|
|
5028
|
-
/** A rect on the surface, in CSS pixels from the canvas top-left. */
|
|
5029
|
-
interface ViewRect {
|
|
5030
|
-
x: number;
|
|
5031
|
-
y: number;
|
|
5032
|
-
w: number;
|
|
5033
|
-
h: number;
|
|
5034
|
-
}
|
|
5035
|
-
/** Props for `<CanvasView>`. @experimental */
|
|
5036
|
-
interface CanvasViewProps {
|
|
5037
|
-
/** Identifies the view to the surface and to input routing. Must be unique
|
|
5038
|
-
* among the views on one canvas. */
|
|
5039
|
-
id: string;
|
|
5040
|
-
/** Where this view paints, recomputed every frame so the rect can track the
|
|
5041
|
-
* outer camera. A plain rect is accepted for a fixed panel. */
|
|
5042
|
-
bounds: ViewRect | ((outer: View, dims: Dims) => ViewRect);
|
|
5043
|
-
/** Camera. Supply this to control it; otherwise the view keeps its own,
|
|
5044
|
-
* seeded from `defaultView`. `onViewChange` fires either way. */
|
|
5045
|
-
view?: View;
|
|
5046
|
-
defaultView?: View;
|
|
5047
|
-
onViewChange?: (v: View) => void;
|
|
5048
|
-
/** Pan limits, applied to every camera change the same way `<Canvas>`
|
|
5049
|
-
* applies its own. */
|
|
5050
|
-
viewBounds?: Bounds;
|
|
5051
|
-
/** Which of the surface's layers this view paints. Defaults to all of them —
|
|
5052
|
-
* the same content through a second camera. */
|
|
5053
|
-
layers?: (surface: readonly RenderLayer<unknown>[]) => readonly RenderLayer<unknown>[];
|
|
5054
|
-
/** Opaque ground painted before the source layers, so the surface does not
|
|
5055
|
-
* show through where the inner camera sees nothing. */
|
|
5056
|
-
background?: string;
|
|
5057
|
-
/** Paint and hit order. Defaults to `Infinity` — after every view the
|
|
5058
|
-
* surface declared as a prop. */
|
|
5059
|
-
order?: number;
|
|
5060
|
-
/** Label for debug overlays. Defaults to the id. */
|
|
5061
|
-
label?: string;
|
|
5062
|
-
/** A selection of this view's own, which actions dispatched inside it read
|
|
5063
|
-
* and write instead of the surface's. Omit both this and
|
|
5064
|
-
* `selectionOptions` and the view shares the surface's selection — the
|
|
5065
|
-
* default, so undo restores one selection rather than N. */
|
|
5066
|
-
selection?: SelectionApi;
|
|
5067
|
-
/** Opts this view into owning a selection, configured thus. Ignored when
|
|
5068
|
-
* `selection` is supplied. */
|
|
5069
|
-
selectionOptions?: UseSelectionOptions;
|
|
5070
|
-
}
|
|
5071
5603
|
/**
|
|
5072
|
-
*
|
|
5604
|
+
* The kit's built-in shape kinds — one table, every other spelling derived.
|
|
5073
5605
|
*
|
|
5074
|
-
*
|
|
5075
|
-
*
|
|
5076
|
-
*
|
|
5606
|
+
* Lives in `core/` rather than beside the shape tools because both layers ask
|
|
5607
|
+
* questions of the same set: the interactions layer decides whether
|
|
5608
|
+
* `insertAction` can paint a live preview for a kind, and the canvas layer
|
|
5609
|
+
* decides which shape tools `useBuiltinShapeTools` mounts and what
|
|
5610
|
+
* `BUNDLE_TOOLS` / `defaultNodeRouting` / `defaultNodeProperties` enumerate.
|
|
5077
5611
|
*
|
|
5078
|
-
*
|
|
5079
|
-
*
|
|
5612
|
+
* This module imports nothing on purpose: `useBuiltinShapeTools` imports the
|
|
5613
|
+
* package barrel, so anything barrel-reachable that needs these lists at
|
|
5614
|
+
* module-evaluation time must not route through it.
|
|
5080
5615
|
*/
|
|
5081
|
-
|
|
5616
|
+
/** What the kit knows about one built-in shape kind. */
|
|
5617
|
+
interface ShapeKindDescriptor {
|
|
5618
|
+
/** Mounted as a built-in shape tool by `useBuiltinShapeTools`, and so a
|
|
5619
|
+
* member of `BuiltinShapeToolId` / `KIT_SHAPE_KINDS`. `image` is false:
|
|
5620
|
+
* `useImageTool` needs a `src` and can't be auto-mounted. */
|
|
5621
|
+
readonly tool: boolean;
|
|
5622
|
+
/** `insertAction` emits an `insertPreview` overlay for this kind, and the
|
|
5623
|
+
* dispatcher overlay layer knows how to draw it. Kinds without one still
|
|
5624
|
+
* commit; they just have no live drag preview (`pen` and `lasso` don't
|
|
5625
|
+
* route through `insertAction` at all). */
|
|
5626
|
+
readonly insertPreview: boolean;
|
|
5627
|
+
}
|
|
5628
|
+
/**
|
|
5629
|
+
* Declaration order is the enumeration order of every derived list —
|
|
5630
|
+
* `KIT_SHAPE_KINDS`, and through it `defaultNodeRouting` /
|
|
5631
|
+
* `defaultNodeProperties` / `BUNDLE_TOOLS.exhaustive`.
|
|
5632
|
+
*/
|
|
5633
|
+
declare const SHAPE_KINDS: {
|
|
5634
|
+
readonly rect: {
|
|
5635
|
+
readonly tool: true;
|
|
5636
|
+
readonly insertPreview: true;
|
|
5637
|
+
};
|
|
5638
|
+
readonly ellipse: {
|
|
5639
|
+
readonly tool: true;
|
|
5640
|
+
readonly insertPreview: true;
|
|
5641
|
+
};
|
|
5642
|
+
readonly line: {
|
|
5643
|
+
readonly tool: true;
|
|
5644
|
+
readonly insertPreview: true;
|
|
5645
|
+
};
|
|
5646
|
+
readonly polygon: {
|
|
5647
|
+
readonly tool: true;
|
|
5648
|
+
readonly insertPreview: true;
|
|
5649
|
+
};
|
|
5650
|
+
readonly star: {
|
|
5651
|
+
readonly tool: true;
|
|
5652
|
+
readonly insertPreview: true;
|
|
5653
|
+
};
|
|
5654
|
+
readonly pen: {
|
|
5655
|
+
readonly tool: true;
|
|
5656
|
+
readonly insertPreview: false;
|
|
5657
|
+
};
|
|
5658
|
+
readonly pencil: {
|
|
5659
|
+
readonly tool: true;
|
|
5660
|
+
readonly insertPreview: true;
|
|
5661
|
+
};
|
|
5662
|
+
readonly lasso: {
|
|
5663
|
+
readonly tool: true;
|
|
5664
|
+
readonly insertPreview: false;
|
|
5665
|
+
};
|
|
5666
|
+
readonly text: {
|
|
5667
|
+
readonly tool: true;
|
|
5668
|
+
readonly insertPreview: true;
|
|
5669
|
+
};
|
|
5670
|
+
readonly image: {
|
|
5671
|
+
readonly tool: false;
|
|
5672
|
+
readonly insertPreview: true;
|
|
5673
|
+
};
|
|
5674
|
+
};
|
|
5675
|
+
/** The keys of a shape-kind table whose descriptor sets `F` to `true`. */
|
|
5676
|
+
type ShapeKindsWhere<T, F extends keyof ShapeKindDescriptor> = {
|
|
5677
|
+
[K in keyof T]: T[K] extends Record<F, true> ? K : never;
|
|
5678
|
+
}[keyof T];
|
|
5679
|
+
/**
|
|
5680
|
+
* Built-in shape tool ids handled by `useBuiltinShapeTools`. Each maps to a
|
|
5681
|
+
* kit tool hook + a default `create` that produces a leaf node compatible
|
|
5682
|
+
* with `PATH_PAINTER`.
|
|
5683
|
+
*/
|
|
5684
|
+
type BuiltinShapeToolId = ShapeKindsWhere<typeof SHAPE_KINDS, 'tool'>;
|
|
5685
|
+
/** The insert kinds the kit's dispatcher overlay layer knows how to render.
|
|
5686
|
+
* Consumer-defined kinds fall outside it: no live preview, commit unaffected. */
|
|
5687
|
+
type KitInsertShape = ShapeKindsWhere<typeof SHAPE_KINDS, 'insertPreview'>;
|
|
5688
|
+
/** Runtime, iterable list of the shape-tool ids in `BuiltinShapeToolId`.
|
|
5689
|
+
* Surfaced so consumers (e.g. the Bundle Inspector) can enumerate the
|
|
5690
|
+
* builtin shape kinds without re-encoding the union. */
|
|
5691
|
+
declare const KIT_SHAPE_KINDS: readonly BuiltinShapeToolId[];
|
|
5082
5692
|
|
|
5083
5693
|
/** Per-tool option overrides for the built-in shape/lasso tools.
|
|
5084
5694
|
* Each entry is a narrow subset of the underlying hook's options surface
|
|
@@ -5281,7 +5891,7 @@ interface SceneCanvasHit {
|
|
|
5281
5891
|
/** Props for `<SceneCanvas>`. Most are optional: a scene is the only thing it
|
|
5282
5892
|
* truly needs, and everything else — tools, layers, selection handling,
|
|
5283
5893
|
* layouts, animation — layers onto sensible defaults. */
|
|
5284
|
-
type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<Node$1<TData, TLayer, TPose>, TPose>, 'adapter' | 'moveOptions' | 'resizeOptions' | 'rotateOptions' | 'snap' | 'pickEvery' | 'boundsOf' | 'handleHitRadius' | 'selection' | 'selectionOptions' | 'tools' | '
|
|
5894
|
+
type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<Node$1<TData, TLayer, TPose>, TPose>, 'adapter' | 'moveOptions' | 'resizeOptions' | 'rotateOptions' | 'snap' | 'pickEvery' | 'boundsOf' | 'handleHitRadius' | 'selection' | 'selectionOptions' | 'tools' | 'layers' | 'onBackgroundClick' | 'getIsVisible' | 'contentVersion' | 'layerVisibility' | 'layerOrder'> & {
|
|
5285
5895
|
/** A `Scene` (typically from `useScene`) — or a `SerializedScene`
|
|
5286
5896
|
* JSON object, which SceneCanvas bakes into a Scene internally on
|
|
5287
5897
|
* first render. The serialized form is read once; subsequent
|
|
@@ -5309,6 +5919,12 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5309
5919
|
* to `sceneToAdapter` so `useMove`'s layout pass runs on configured
|
|
5310
5920
|
* containers (reflow on enter, reparent + reflow on commit). */
|
|
5311
5921
|
layouts?: SceneToAdapterOptions<TData, TLayer, TPose>['layouts'];
|
|
5922
|
+
/** How a child's stored pose folds into its parent's frame. Omit for the
|
|
5923
|
+
* absolute-pose model, where a container groups its children but imposes
|
|
5924
|
+
* no transform. Pass `RIGID_POSE_COMPOSITION` to make a container's pose
|
|
5925
|
+
* a frame, so rotating it rotates its contents and moving it carries them
|
|
5926
|
+
* without touching their poses. */
|
|
5927
|
+
poseComposition?: SceneToAdapterOptions<TData, TLayer, TPose>['poseComposition'];
|
|
5312
5928
|
/**
|
|
5313
5929
|
* Optional consumer seam for eager geometry sync: lets pose-transform
|
|
5314
5930
|
* actions (move, resize, nudge, flip — NOT rotate) also rewrite a node's
|
|
@@ -5345,6 +5961,10 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5345
5961
|
* it with extras is what needs the memo.)
|
|
5346
5962
|
*/
|
|
5347
5963
|
routing?: readonly NodeRoutingEntry[];
|
|
5964
|
+
/** How to read and rewrite this scene's poses. Every built-in action,
|
|
5965
|
+
* the selection chrome and picking read it. Default `AUTO_POSE_DESCRIPTOR`
|
|
5966
|
+
* (rect poses and `Path` poses). */
|
|
5967
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
5348
5968
|
geometry?: {
|
|
5349
5969
|
/** Hit-test override. Return the topmost id, the full back-to-front hit
|
|
5350
5970
|
* stack (`string[]`), or `null` for empty space. The stack form lets a
|
|
@@ -5628,9 +6248,9 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5628
6248
|
/**
|
|
5629
6249
|
* Optional animator to bind for per-frame redraws. When supplied,
|
|
5630
6250
|
* SceneCanvas subscribes to `animator.onTick` and requests a redraw on
|
|
5631
|
-
* every active animation frame
|
|
5632
|
-
*
|
|
5633
|
-
*
|
|
6251
|
+
* every active animation frame, and paints `animator.colorOverrides`
|
|
6252
|
+
* onto the scene's nodes: the kit's path and shape painters apply them,
|
|
6253
|
+
* and a custom `drawOne` receives them as `ctx.vertexColors`. Scene
|
|
5634
6254
|
* mutations trigger repaints automatically, but `colorOverrides` writes
|
|
5635
6255
|
* do not.
|
|
5636
6256
|
*
|
|
@@ -5753,6 +6373,25 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5753
6373
|
* Defaults to `() => 1` (no effect).
|
|
5754
6374
|
*/
|
|
5755
6375
|
alphaFor?: (id: string) => number;
|
|
6376
|
+
/**
|
|
6377
|
+
* Show or hide render layers in this canvas's own view, by id — the map
|
|
6378
|
+
* `<Canvas>` takes. Each scene layer paints as its own render layer, keyed
|
|
6379
|
+
* `scene:<layerId>`, so `{ 'scene:guides': false }` hides one scene layer
|
|
6380
|
+
* here and nowhere else.
|
|
6381
|
+
*
|
|
6382
|
+
* A layer hidden this way is gone from this view: it does not paint, and a
|
|
6383
|
+
* click, a marquee or Cmd+A here passes over it. Another view of the same
|
|
6384
|
+
* scene — a `<CanvasView>`, a second canvas, a minimap — still shows it and
|
|
6385
|
+
* can still take it. It applies on top of the scene's own
|
|
6386
|
+
* `LayerRecord.visible` and cannot show a layer the scene hides.
|
|
6387
|
+
*/
|
|
6388
|
+
layerVisibility?: Record<string, boolean>;
|
|
6389
|
+
/**
|
|
6390
|
+
* Draw order for this view, by render-layer id, bottom first. A listed
|
|
6391
|
+
* order is the whole list: a scene layer left out of it is neither painted
|
|
6392
|
+
* nor picked here. See `CanvasProps.layerOrder`.
|
|
6393
|
+
*/
|
|
6394
|
+
layerOrder?: string[];
|
|
5756
6395
|
/**
|
|
5757
6396
|
* Optional per-id pointer-interactivity predicate. When supplied, ids
|
|
5758
6397
|
* for which the predicate returns `false` are excluded from hit-test
|
|
@@ -6059,6 +6698,194 @@ declare const defaultNodeProperties: readonly NodePropertiesEntry[];
|
|
|
6059
6698
|
*/
|
|
6060
6699
|
declare const inferredNodeProperties: readonly NodePropertiesEntry[];
|
|
6061
6700
|
|
|
6701
|
+
/**
|
|
6702
|
+
* What an in-flight gesture is proposing, resolved against the committed scene.
|
|
6703
|
+
*
|
|
6704
|
+
* An ongoing action publishes interim poses on its handle rather than writing
|
|
6705
|
+
* them to the scene, and `<SceneCanvas>`'s ghost layer used to be the only
|
|
6706
|
+
* thing that knew how to read them: which ids are in flight, which of those are
|
|
6707
|
+
* roots, whose preview wins when two sources name the same id, and which are
|
|
6708
|
+
* merely displaced rather than dragged. None of that is about drawing, and a
|
|
6709
|
+
* consumer with its own renderer needs all of it.
|
|
6710
|
+
*/
|
|
6711
|
+
|
|
6712
|
+
interface PreviewNode<TData, TLayer extends string, TPose> {
|
|
6713
|
+
id: NodeId;
|
|
6714
|
+
/** The node as committed — the gesture has not touched the scene. */
|
|
6715
|
+
node: Node$1<TData, TLayer, TPose>;
|
|
6716
|
+
/** The interim pose, or the committed one when only data is in flight. */
|
|
6717
|
+
pose: TPose;
|
|
6718
|
+
/** The interim data, or the committed one when only the pose is in flight. */
|
|
6719
|
+
data: TData;
|
|
6720
|
+
/**
|
|
6721
|
+
* The gesture is not carrying this one under the pointer — a layout sibling
|
|
6722
|
+
* reflowing into its destination slot. It reads better painted settled.
|
|
6723
|
+
*/
|
|
6724
|
+
opaque: boolean;
|
|
6725
|
+
/** Previewed descendants, so a container's ghost brings its children. */
|
|
6726
|
+
children: PreviewNode<TData, TLayer, TPose>[];
|
|
6727
|
+
}
|
|
6728
|
+
/**
|
|
6729
|
+
* The previewing subtrees, as roots. A previewed node whose parent is also
|
|
6730
|
+
* previewing is a child of that parent's entry rather than a root of its own,
|
|
6731
|
+
* which is what lets a caller draw a container and its contents as one thing.
|
|
6732
|
+
*
|
|
6733
|
+
* An id with no node is skipped: an insert previews before the node it will
|
|
6734
|
+
* create exists. So is an id no source has a pose or data for.
|
|
6735
|
+
*/
|
|
6736
|
+
declare function resolvePreviews<TData, TLayer extends string, TPose>(sources: Iterable<GesturePreviewSource>, scene: Scene<TData, TLayer, TPose>): PreviewNode<TData, TLayer, TPose>[];
|
|
6737
|
+
/** Every entry in the forest, parents before their children. */
|
|
6738
|
+
declare function flattenPreviews<TData, TLayer extends string, TPose>(roots: readonly PreviewNode<TData, TLayer, TPose>[]): PreviewNode<TData, TLayer, TPose>[];
|
|
6739
|
+
|
|
6740
|
+
/**
|
|
6741
|
+
* The one answer to "how big is the thing this in-flight insert is making".
|
|
6742
|
+
*
|
|
6743
|
+
* A drag-to-insert has no scene node until commit, so three surfaces have to
|
|
6744
|
+
* size the nascent shape themselves: `useDispatcherOverlayLayer` (paints the
|
|
6745
|
+
* preview), `canvas/deps/insert` (poses the committed node) and
|
|
6746
|
+
* `dispatcherGestureBounds` (reports the gesture's world AABB to `<Canvas>`).
|
|
6747
|
+
* They all resolve it here.
|
|
6748
|
+
*
|
|
6749
|
+
* The drag AABB alone is NOT the answer. `insertAction` hands over an
|
|
6750
|
+
* `extras` payload that can carry richer geometry than the drag rect —
|
|
6751
|
+
* a polygon's center+radius, a pencil's sample trail, a line's endpoints —
|
|
6752
|
+
* and where it does, that geometry is the shape. A centered Alt-drag
|
|
6753
|
+
* produces a `d`-wide drag rect around a `d√2` circumradius; a pencil that
|
|
6754
|
+
* loops back to its start produces a zero-area drag rect around a trail that
|
|
6755
|
+
* swept the page.
|
|
6756
|
+
*/
|
|
6757
|
+
|
|
6758
|
+
type Point$2 = {
|
|
6759
|
+
x: number;
|
|
6760
|
+
y: number;
|
|
6761
|
+
};
|
|
6762
|
+
/** The fields of an `insertPreview` overlay this needs. `canvas/deps/insert`
|
|
6763
|
+
* passes the equivalent from its own `(bounds, extras)` commit arguments. */
|
|
6764
|
+
interface InsertPreviewLike {
|
|
6765
|
+
shape: string;
|
|
6766
|
+
bounds: {
|
|
6767
|
+
x: number;
|
|
6768
|
+
y: number;
|
|
6769
|
+
width: number;
|
|
6770
|
+
height: number;
|
|
6771
|
+
};
|
|
6772
|
+
extras: unknown;
|
|
6773
|
+
}
|
|
6774
|
+
/** Resolved preview geometry, in the terms the path builders take. */
|
|
6775
|
+
type InsertPreviewGeometry = {
|
|
6776
|
+
kind: 'box';
|
|
6777
|
+
} | {
|
|
6778
|
+
kind: 'line';
|
|
6779
|
+
a: Point$2;
|
|
6780
|
+
b: Point$2;
|
|
6781
|
+
} | {
|
|
6782
|
+
kind: 'polygon';
|
|
6783
|
+
center: Point$2;
|
|
6784
|
+
radius: number;
|
|
6785
|
+
sides: number;
|
|
6786
|
+
rotation: number;
|
|
6787
|
+
} | {
|
|
6788
|
+
kind: 'star';
|
|
6789
|
+
center: Point$2;
|
|
6790
|
+
outerRadius: number;
|
|
6791
|
+
innerRadius: number;
|
|
6792
|
+
points: number;
|
|
6793
|
+
rotation: number;
|
|
6794
|
+
} | {
|
|
6795
|
+
kind: 'pencil';
|
|
6796
|
+
samples: ReadonlyArray<Point$2>;
|
|
6797
|
+
};
|
|
6798
|
+
interface InsertPreviewExtent {
|
|
6799
|
+
/** The insert kind, verbatim from the caller. */
|
|
6800
|
+
shape: string;
|
|
6801
|
+
/** World-space AABB of `geometry` — the extent. */
|
|
6802
|
+
bounds: Bounds;
|
|
6803
|
+
geometry: InsertPreviewGeometry;
|
|
6804
|
+
}
|
|
6805
|
+
type InsertPreviewOverlay = Extract<OngoingOverlay, {
|
|
6806
|
+
kind: 'insertPreview';
|
|
6807
|
+
}>;
|
|
6808
|
+
declare function insertPreviewExtent(ov: InsertPreviewLike): InsertPreviewExtent;
|
|
6809
|
+
|
|
6810
|
+
/**
|
|
6811
|
+
* What an in-flight gesture is proposing to paint *beside* the scene, resolved
|
|
6812
|
+
* to geometry.
|
|
6813
|
+
*
|
|
6814
|
+
* The sibling of `resolvePreviews`: that one answers for the ghosts of scene
|
|
6815
|
+
* nodes a gesture is displacing, this one for the chrome a gesture draws that
|
|
6816
|
+
* is no node at all — a marquee rect, a lasso trail, the outline of a shape
|
|
6817
|
+
* being dragged out. `<SceneCanvas>`'s `useDispatcherOverlayLayer` used to be
|
|
6818
|
+
* the only thing that knew how to read an `OngoingOverlay`, and it read one
|
|
6819
|
+
* straight into `DrawCommand`s, so a consumer with its own renderer got
|
|
6820
|
+
* nothing. None of the normalizing is about drawing.
|
|
6821
|
+
*
|
|
6822
|
+
* What stays out, as in `resolvePreviews`: no view, no screen projection, no
|
|
6823
|
+
* `DrawCommand`, no style, no React, no dispatcher. World coordinates only.
|
|
6824
|
+
*/
|
|
6825
|
+
|
|
6826
|
+
type Point$1 = {
|
|
6827
|
+
x: number;
|
|
6828
|
+
y: number;
|
|
6829
|
+
};
|
|
6830
|
+
/**
|
|
6831
|
+
* The chrome-caps id a surface consults before painting each variant. The
|
|
6832
|
+
* gating itself is the painter's — two views of one surface may disagree about
|
|
6833
|
+
* whether to show an in-flight marquee — but the id is not something a caller
|
|
6834
|
+
* should have to guess.
|
|
6835
|
+
*/
|
|
6836
|
+
type OverlayVisibilityId = 'action.marquee' | 'action.lasso' | 'action.insert-preview' | 'action.polyline';
|
|
6837
|
+
/**
|
|
6838
|
+
* One in-flight overlay, in world coordinates.
|
|
6839
|
+
*
|
|
6840
|
+
* Every degenerate overlay is already gone: a marquee of zero size, a lasso
|
|
6841
|
+
* under two vertices, a zero-area insert of anything but a pencil, a pencil
|
|
6842
|
+
* under two samples, a run of fewer than two points. Whatever is in this list
|
|
6843
|
+
* is worth painting.
|
|
6844
|
+
*/
|
|
6845
|
+
type ResolvedOverlay = {
|
|
6846
|
+
kind: 'marquee';
|
|
6847
|
+
visibilityId: 'action.marquee';
|
|
6848
|
+
/** The drag normalized: `start`/`current` in either order, one AABB. */
|
|
6849
|
+
bounds: Bounds;
|
|
6850
|
+
/** Additive intent. Core's 2D layer paints the same rect either way. */
|
|
6851
|
+
shiftHeld: boolean;
|
|
6852
|
+
} | {
|
|
6853
|
+
kind: 'lasso';
|
|
6854
|
+
visibilityId: 'action.lasso';
|
|
6855
|
+
/** The trail so far, at least two long. The region it encloses is the
|
|
6856
|
+
* trail closed back to its first vertex. */
|
|
6857
|
+
vertices: ReadonlyArray<Point$1>;
|
|
6858
|
+
/** Live pointer position — the trail's last vertex until it advances. */
|
|
6859
|
+
current: Point$1;
|
|
6860
|
+
shiftHeld: boolean;
|
|
6861
|
+
} | {
|
|
6862
|
+
kind: 'insertPreview';
|
|
6863
|
+
visibilityId: 'action.insert-preview';
|
|
6864
|
+
shape: KitInsertShape;
|
|
6865
|
+
/** Extent of `geometry`, which for a radial or freehand shape is not the
|
|
6866
|
+
* drag rect. See `insertPreviewExtent`. */
|
|
6867
|
+
bounds: Bounds;
|
|
6868
|
+
geometry: InsertPreviewGeometry;
|
|
6869
|
+
/** The drag's anchor — a growth axis to mark. Absent for a pencil, which
|
|
6870
|
+
* has none. */
|
|
6871
|
+
anchorPoint?: Point$1;
|
|
6872
|
+
/** The action's per-shape payload, verbatim. Carries what geometry
|
|
6873
|
+
* cannot: an image insert's `src`, say. */
|
|
6874
|
+
extras: unknown;
|
|
6875
|
+
} | {
|
|
6876
|
+
kind: 'polyline';
|
|
6877
|
+
visibilityId: 'action.polyline';
|
|
6878
|
+
/** The run, at least two long, open — the last point does not join the
|
|
6879
|
+
* first. A closed sweep is a `lasso`. */
|
|
6880
|
+
points: ReadonlyArray<Point$1>;
|
|
6881
|
+
/** What the run is, for a painter choosing a style. Never defaulted
|
|
6882
|
+
* away: `'chrome'` when the action named none. A role the painter has
|
|
6883
|
+
* no style for is drawn as plain chrome, not dropped. */
|
|
6884
|
+
role: OverlayRole;
|
|
6885
|
+
};
|
|
6886
|
+
/** The overlays worth painting, in the order the handles published them. */
|
|
6887
|
+
declare function resolveOverlays(overlays: Iterable<OngoingOverlay>): ResolvedOverlay[];
|
|
6888
|
+
|
|
6062
6889
|
/**
|
|
6063
6890
|
* `renderSceneToCanvas` — substrate for detached, read-only scene views
|
|
6064
6891
|
* (`<SceneViewCanvas>` / `<MinimapCanvas>`). Given a `<canvas>`, a `Scene`,
|
|
@@ -6078,6 +6905,18 @@ declare const inferredNodeProperties: readonly NodePropertiesEntry[];
|
|
|
6078
6905
|
* in sync by hand where it matters (DPR handling, viewToMat3 wrap).
|
|
6079
6906
|
*/
|
|
6080
6907
|
|
|
6908
|
+
/**
|
|
6909
|
+
* Which scene layers a detached view paints, on top of each layer's own
|
|
6910
|
+
* `visible` flag. Keyed the way `<SceneCanvas>` keys its scene layers —
|
|
6911
|
+
* `scene:<layerId>` — so the map a main canvas takes serves its minimap too.
|
|
6912
|
+
*/
|
|
6913
|
+
interface SceneViewLayers {
|
|
6914
|
+
/** `false` hides that layer in this view. It cannot show one the scene hides. */
|
|
6915
|
+
layerVisibility?: Record<string, boolean>;
|
|
6916
|
+
/** Paint order, bottom first. A listed order is the whole list: a scene
|
|
6917
|
+
* layer left out of it is not painted. */
|
|
6918
|
+
layerOrder?: readonly string[];
|
|
6919
|
+
}
|
|
6081
6920
|
/** What to draw into an existing canvas: the scene, the view, and the same
|
|
6082
6921
|
* painting hooks `<SceneCanvas>` takes. */
|
|
6083
6922
|
interface RenderSceneToCanvasArgs<TData, TLayer extends string, TPose> {
|
|
@@ -6107,6 +6946,13 @@ interface RenderSceneToCanvasArgs<TData, TLayer extends string, TPose> {
|
|
|
6107
6946
|
* `alphaFor`. Pass the same function the main canvas uses to keep a
|
|
6108
6947
|
* scoping-dim treatment consistent across both. Defaults to `() => 1`. */
|
|
6109
6948
|
alphaFor?: (id: string) => number;
|
|
6949
|
+
/** Per-view layer visibility. See {@link SceneViewLayers}. */
|
|
6950
|
+
layerVisibility?: SceneViewLayers['layerVisibility'];
|
|
6951
|
+
/** Per-view layer order. See {@link SceneViewLayers}. */
|
|
6952
|
+
layerOrder?: SceneViewLayers['layerOrder'];
|
|
6953
|
+
/** Animated vertex colors to paint, typically an animator's
|
|
6954
|
+
* `colorOverrides` — see `NodePaintCtx.vertexColors`. */
|
|
6955
|
+
colorOverrides?: ColorOverrideRegistry;
|
|
6110
6956
|
/** Optional device-pixel ratio. Defaults to `window.devicePixelRatio || 1`
|
|
6111
6957
|
* when available, otherwise 1. Tests typically pin this to 1 or 2. */
|
|
6112
6958
|
dpr?: number;
|
|
@@ -6128,13 +6974,21 @@ interface RenderSceneToCanvasArgs<TData, TLayer extends string, TPose> {
|
|
|
6128
6974
|
* emit unrotated geometry and let the pose drive it.
|
|
6129
6975
|
*
|
|
6130
6976
|
* Output shape follows `buildSceneTree`: one group per **visible** layer, in
|
|
6131
|
-
* scene-layer order, each holding one group per node
|
|
6977
|
+
* scene-layer order (or `layers.layerOrder`), each holding one group per node
|
|
6978
|
+
* on that layer.
|
|
6132
6979
|
*
|
|
6133
6980
|
* Exported for tests and for callers that want to render into something
|
|
6134
6981
|
* other than a real `<canvas>` (e.g. an offscreen renderer or a
|
|
6135
6982
|
* snapshot fixture).
|
|
6136
6983
|
*/
|
|
6137
|
-
declare function buildSceneViewCommands<TData, TLayer extends string, TPose>(scene: Scene<TData, TLayer, TPose>, view: View, drawOne: SceneViewDrawOne<TData, TLayer, TPose>, extraCommands?: ReadonlyArray<DrawCommand>, alphaFor?: (id: string) => number
|
|
6984
|
+
declare function buildSceneViewCommands<TData, TLayer extends string, TPose>(scene: Scene<TData, TLayer, TPose>, view: View, drawOne: SceneViewDrawOne<TData, TLayer, TPose>, extraCommands?: ReadonlyArray<DrawCommand>, alphaFor?: (id: string) => number,
|
|
6985
|
+
/** How a child's stored pose folds into its parent's frame. Omit for the
|
|
6986
|
+
* absolute-pose model. */
|
|
6987
|
+
poseComposition?: PoseComposition<TPose>,
|
|
6988
|
+
/** This view's own layer visibility and order. */
|
|
6989
|
+
layers?: SceneViewLayers,
|
|
6990
|
+
/** Animated vertex colors to paint, typically an animator's `colorOverrides`. */
|
|
6991
|
+
colorOverrides?: ColorOverrideRegistry): DrawCommand[];
|
|
6138
6992
|
/**
|
|
6139
6993
|
* Render one frame of `scene` at `view` into `canvas`. See module docstring
|
|
6140
6994
|
* for the design context.
|
|
@@ -6178,6 +7032,15 @@ interface SceneViewCanvasProps<TData, TLayer extends string, TPose> {
|
|
|
6178
7032
|
* `alphaFor`. Pass the same function the main canvas uses to keep a
|
|
6179
7033
|
* scoping-dim treatment consistent across both. Defaults to `() => 1`. */
|
|
6180
7034
|
alphaFor?: (id: string) => number;
|
|
7035
|
+
/** Hide scene layers in this view only, keyed `scene:<layerId>` as on
|
|
7036
|
+
* `<SceneCanvas>` — pass the main canvas's map to keep the two in step. */
|
|
7037
|
+
layerVisibility?: SceneViewLayers['layerVisibility'];
|
|
7038
|
+
/** Paint order for this view, keyed as `layerVisibility`. */
|
|
7039
|
+
layerOrder?: SceneViewLayers['layerOrder'];
|
|
7040
|
+
/** Optional animator, as on `<SceneCanvas>`: the view repaints on its ticks
|
|
7041
|
+
* and paints its `colorOverrides`. Pass the main canvas's animator so both
|
|
7042
|
+
* show the same colors. */
|
|
7043
|
+
animator?: Animator;
|
|
6181
7044
|
/** Optional CSS class for sizing / positioning the `<canvas>`. The kit
|
|
6182
7045
|
* does not emit inline styles for layout — use a class. */
|
|
6183
7046
|
className?: string;
|
|
@@ -6211,7 +7074,7 @@ declare function sceneSelectionStore(scene: {
|
|
|
6211
7074
|
* registry passed in `options`. Throws on unknown version, unknown registry
|
|
6212
7075
|
* keys, or invalid scene shape (cross-layer subtrees, unknown layer ids).
|
|
6213
7076
|
* Loaded scenes start with empty history — undo/redo is NOT serialized. */
|
|
6214
|
-
declare function sceneFromJSON<TData, TLayer extends string, TPose>(json: SerializedScene<TData, TLayer, TPose>, options
|
|
7077
|
+
declare function sceneFromJSON<TData, TLayer extends string, TPose>(json: SerializedScene<TData, TLayer, TPose>, options?: {
|
|
6215
7078
|
registry?: SceneRegistry<TPose>;
|
|
6216
7079
|
historyLimit?: number;
|
|
6217
7080
|
coalesceWindowMs?: number;
|
|
@@ -6326,6 +7189,25 @@ declare function documentPose<TPose>(source: PoseSource<TPose>, node: PosedNode<
|
|
|
6326
7189
|
*/
|
|
6327
7190
|
declare function effectivePose<TPose>(source: PoseSource<TPose>, node: PosedNode<TPose>): TPose;
|
|
6328
7191
|
|
|
7192
|
+
/** A node and the pose a renderer should draw it at. `node.pose` beside it is
|
|
7193
|
+
* still the committed pose, so a host has both without a second channel. */
|
|
7194
|
+
interface FeedNode<TData, TLayer extends string, TPose> {
|
|
7195
|
+
node: Node$1<TData, TLayer, TPose>;
|
|
7196
|
+
pose: TPose;
|
|
7197
|
+
}
|
|
7198
|
+
interface FeedDelta<TData, TLayer extends string, TPose> {
|
|
7199
|
+
added: readonly FeedNode<TData, TLayer, TPose>[];
|
|
7200
|
+
removed: readonly NodeId[];
|
|
7201
|
+
changed: readonly FeedNode<TData, TLayer, TPose>[];
|
|
7202
|
+
/** Discard the object map and rebuild. */
|
|
7203
|
+
reset: boolean;
|
|
7204
|
+
}
|
|
7205
|
+
interface PoseFeed<TData, TLayer extends string, TPose> {
|
|
7206
|
+
subscribe(fn: () => void): () => void;
|
|
7207
|
+
read(): FeedDelta<TData, TLayer, TPose>;
|
|
7208
|
+
}
|
|
7209
|
+
declare function createPoseFeed<TData, TLayer extends string, TPose>(scene: Scene<TData, TLayer, TPose>): PoseFeed<TData, TLayer, TPose>;
|
|
7210
|
+
|
|
6329
7211
|
/** Registry key for {@link unionOfChildren}. */
|
|
6330
7212
|
declare const UNION_OF_CHILDREN = "kit:unionOfChildren";
|
|
6331
7213
|
/**
|
|
@@ -6337,6 +7219,13 @@ declare const UNION_OF_CHILDREN = "kit:unionOfChildren";
|
|
|
6337
7219
|
* Returns `null` for an emptied container, which falls back to its authored
|
|
6338
7220
|
* pose — the group stays where the last member left it rather than collapsing
|
|
6339
7221
|
* to a zero box at the origin.
|
|
7222
|
+
*
|
|
7223
|
+
* Reads members as rect poses, and only as rect poses: a scene whose poses are
|
|
7224
|
+
* shaped otherwise gets `null` here and its container keeps its authored pose,
|
|
7225
|
+
* because this entry is registered into every scene and the scene layer holds
|
|
7226
|
+
* no descriptor to read another shape with. To make such a container track its
|
|
7227
|
+
* members, register `unionOfChildrenVia(itsDescriptor)` under
|
|
7228
|
+
* {@link UNION_OF_CHILDREN} — the consumer's entry wins the collision.
|
|
6340
7229
|
*/
|
|
6341
7230
|
declare function unionOfChildren<TPose>(_node: unknown, deps: readonly ({
|
|
6342
7231
|
pose: TPose;
|
|
@@ -6350,7 +7239,7 @@ declare const FALLBACK_FIT_VIEW: View;
|
|
|
6350
7239
|
/**
|
|
6351
7240
|
* Fit policy for `<MinimapCanvas>` / `computeFitView`.
|
|
6352
7241
|
*
|
|
6353
|
-
* - `"scene"` — union of leaf-node pose AABBs (via
|
|
7242
|
+
* - `"scene"` — union of leaf-node pose AABBs (via the pose descriptor).
|
|
6354
7243
|
* - `{ kind: "world", rect }` — caller-supplied world rect.
|
|
6355
7244
|
* - `(scene, dims) => View` — caller derives the view directly.
|
|
6356
7245
|
*/
|
|
@@ -6378,7 +7267,7 @@ interface ComputeFitViewOptions {
|
|
|
6378
7267
|
* is centered with `padding` (default 8) on each side. The smaller-axis
|
|
6379
7268
|
* fit ratio wins, so the whole rect is visible.
|
|
6380
7269
|
*
|
|
6381
|
-
* - `fit === "scene"`: union AABB of leaf-node poses via `
|
|
7270
|
+
* - `fit === "scene"`: union AABB of leaf-node poses via `descriptor`.
|
|
6382
7271
|
* Empty scene → {@link FALLBACK_FIT_VIEW}.
|
|
6383
7272
|
* - `fit` is `{ kind: "world", rect }`: fit `rect`. A degenerate rect
|
|
6384
7273
|
* (zero or negative area) falls back to identity scale centered on the
|
|
@@ -6386,7 +7275,7 @@ interface ComputeFitViewOptions {
|
|
|
6386
7275
|
* - `fit` is a function: called with `(scene, dims)`; its return is
|
|
6387
7276
|
* passed through unchanged.
|
|
6388
7277
|
*/
|
|
6389
|
-
declare function computeFitView<TData, TLayer extends string, TPose>(scene: Scene<TData, TLayer, TPose>, dims: ViewportDims, fit: MinimapFit<TData, TLayer, TPose>,
|
|
7278
|
+
declare function computeFitView<TData, TLayer extends string, TPose>(scene: Scene<TData, TLayer, TPose>, dims: ViewportDims, fit: MinimapFit<TData, TLayer, TPose>, descriptor: PoseDescriptor<TPose>, opts?: ComputeFitViewOptions): View;
|
|
6390
7279
|
/**
|
|
6391
7280
|
* Build the visible-window indicator `DrawCommand` for the minimap.
|
|
6392
7281
|
*
|
|
@@ -6438,13 +7327,21 @@ interface MinimapCanvasProps<TData, TLayer extends string, TPose> {
|
|
|
6438
7327
|
* frame if it goes there, rather than making the whole minimap rescale on
|
|
6439
7328
|
* every frame of a drag or a settle. */
|
|
6440
7329
|
fit?: MinimapFit<TData, TLayer, TPose>;
|
|
6441
|
-
/**
|
|
6442
|
-
|
|
6443
|
-
poseBounds?: (pose: TPose) => Bounds;
|
|
7330
|
+
/** How to read poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
7331
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
6444
7332
|
/** Optional per-id alpha multiplier, mirroring `<SceneCanvas>`'s scene-slot
|
|
6445
7333
|
* `alphaFor`. Pass the same function the main canvas uses so a
|
|
6446
7334
|
* scoping-dim treatment shows up in the minimap too. */
|
|
6447
7335
|
alphaFor?: (id: string) => number;
|
|
7336
|
+
/** Hide scene layers in the minimap, keyed `scene:<layerId>` as on
|
|
7337
|
+
* `<SceneCanvas>` — pass the main canvas's map so both show the same set. */
|
|
7338
|
+
layerVisibility?: SceneViewLayers['layerVisibility'];
|
|
7339
|
+
/** Paint order for the minimap, keyed as `layerVisibility`. */
|
|
7340
|
+
layerOrder?: SceneViewLayers['layerOrder'];
|
|
7341
|
+
/** Optional animator: the minimap repaints on its ticks and paints its
|
|
7342
|
+
* `colorOverrides`. Pass the main canvas's animator so both show the same
|
|
7343
|
+
* colors. */
|
|
7344
|
+
animator?: Animator;
|
|
6448
7345
|
/** Visual tuning of the indicator stroke. */
|
|
6449
7346
|
indicatorStyle?: IndicatorStyle;
|
|
6450
7347
|
/** CSS class for sizing / positioning the canvas. */
|
|
@@ -6508,6 +7405,9 @@ interface RenderSceneToPixelsArgs<TData, TLayer extends string, TPose> {
|
|
|
6508
7405
|
* `alphaFor`. Pass the same function the on-screen canvas uses so an
|
|
6509
7406
|
* export matches what the user is looking at. Defaults to `() => 1`. */
|
|
6510
7407
|
alphaFor?: (id: string) => number;
|
|
7408
|
+
/** Animated vertex colors to paint, typically an animator's
|
|
7409
|
+
* `colorOverrides`, so an export shows the frame on screen. */
|
|
7410
|
+
colorOverrides?: ColorOverrideRegistry;
|
|
6511
7411
|
/** Background fill (any CSS color accepted by the renderer). Default:
|
|
6512
7412
|
* fully transparent. Passing a color is always valid. */
|
|
6513
7413
|
background?: string;
|
|
@@ -7016,9 +7916,9 @@ declare function renderLabel(ctx: CanvasRenderingContext2D, text: string, x: num
|
|
|
7016
7916
|
declare const defaultLabelTextRenderer: TextRenderer;
|
|
7017
7917
|
|
|
7018
7918
|
/**
|
|
7019
|
-
* Text RenderLayer
|
|
7020
|
-
*
|
|
7021
|
-
*
|
|
7919
|
+
* Text RenderLayer for text that is not in a scene: one `textCommandFromPose`
|
|
7920
|
+
* command per item, the same command the `kit:text` node painter emits, so an
|
|
7921
|
+
* item lays out — and wraps, or doesn't, per its style — as a node would.
|
|
7022
7922
|
*
|
|
7023
7923
|
* The GL renderer uses MSDF text. The resolved style's `fontFamily` must
|
|
7024
7924
|
* be registered via `registerFont(family, variant, metricsUrl, atlasUrl)`
|
|
@@ -7053,10 +7953,10 @@ declare function createTextLayer<T>(opts: CreateTextLayerOpts<T>): RenderLayer<u
|
|
|
7053
7953
|
*
|
|
7054
7954
|
* `caretIndexAt` does the finer test: given a world-space (x, y) inside the
|
|
7055
7955
|
* pose, returns the corresponding character offset so the consumer can place
|
|
7056
|
-
* the caret on click. It reads the caret stops off the
|
|
7057
|
-
*
|
|
7058
|
-
*
|
|
7059
|
-
*
|
|
7956
|
+
* the caret on click. It reads the caret stops off `layoutTextPose`, the
|
|
7957
|
+
* layout the painters draw and `textLineBoxes` picks against, so the caret
|
|
7958
|
+
* cannot land on a different line — or between different glyphs — than the
|
|
7959
|
+
* one under the pointer.
|
|
7060
7960
|
*/
|
|
7061
7961
|
|
|
7062
7962
|
/** Options for `pointInTextPose`. */
|
|
@@ -7066,19 +7966,6 @@ interface PointInTextPoseOpts {
|
|
|
7066
7966
|
}
|
|
7067
7967
|
/** Coarse pose-rect hit-test for a text node — suitable for click-to-edit dispatch. */
|
|
7068
7968
|
declare function pointInTextPose(x: number, y: number, pose: TextPose, opts?: PointInTextPoseOpts): boolean;
|
|
7069
|
-
/** Options for `caretIndexAt`. */
|
|
7070
|
-
interface CaretIndexAtOpts {
|
|
7071
|
-
/**
|
|
7072
|
-
* Wrap width. Default `pose.width`, which is what `createTextLayer` passes
|
|
7073
|
-
* and what `TextPose` means by its box.
|
|
7074
|
-
*
|
|
7075
|
-
* Pass `Infinity` for a node painted by the built-in `kit:text` painter:
|
|
7076
|
-
* that painter deliberately does not forward `maxWidth`, so its text does
|
|
7077
|
-
* not wrap, and a caret mapped through a finite width would answer for a
|
|
7078
|
-
* line break the paint never made. Mirrors `textLineBoxes`.
|
|
7079
|
-
*/
|
|
7080
|
-
maxWidth?: number;
|
|
7081
|
-
}
|
|
7082
7969
|
/**
|
|
7083
7970
|
* Map a world-space point inside `pose` to a character offset into the pose's
|
|
7084
7971
|
* text (0..length). Clicks above the first line clamp to 0; clicks below the
|
|
@@ -7090,7 +7977,7 @@ interface CaretIndexAtOpts {
|
|
|
7090
7977
|
* produced) and `pose.verticalAlign`. The offset is into the runs'
|
|
7091
7978
|
* concatenated text, which `TextPose` requires to equal `pose.text`.
|
|
7092
7979
|
*/
|
|
7093
|
-
declare function caretIndexAt(x: number, y: number, pose: TextPose
|
|
7980
|
+
declare function caretIndexAt(x: number, y: number, pose: TextPose): number;
|
|
7094
7981
|
|
|
7095
7982
|
/**
|
|
7096
7983
|
* Resize a text node's pose to fit its content. Pure helper — does not own
|
|
@@ -7100,8 +7987,9 @@ declare function caretIndexAt(x: number, y: number, pose: TextPose, opts?: Caret
|
|
|
7100
7987
|
* Two modes:
|
|
7101
7988
|
*
|
|
7102
7989
|
* - `axis: 'height'` (default): keep `pose.width`, recompute `height` as
|
|
7103
|
-
* the
|
|
7104
|
-
*
|
|
7990
|
+
* the block height plus optional vertical padding — wrapped at the width
|
|
7991
|
+
* inside the horizontal padding when the style declares `wrap`. The
|
|
7992
|
+
* common case for column-layout text — chat bubbles, sticky notes.
|
|
7105
7993
|
*
|
|
7106
7994
|
* - `axis: 'both'`: ignore wrapping; recompute both `width` (longest
|
|
7107
7995
|
* `\n`-split line) and `height` (line count × line height) plus padding.
|
|
@@ -7321,6 +8209,13 @@ interface TextEditScreenPose {
|
|
|
7321
8209
|
*/
|
|
7322
8210
|
zoom?: number;
|
|
7323
8211
|
}
|
|
8212
|
+
/** A box in CSS pixels relative to `useTextEdit`'s `container`. */
|
|
8213
|
+
interface TextEditClipRect {
|
|
8214
|
+
x: number;
|
|
8215
|
+
y: number;
|
|
8216
|
+
width: number;
|
|
8217
|
+
height: number;
|
|
8218
|
+
}
|
|
7324
8219
|
/** Options for `useTextEdit`. */
|
|
7325
8220
|
interface UseTextEditOptions {
|
|
7326
8221
|
/** Element the overlay is appended to. Must be `position: relative`/absolute. */
|
|
@@ -7347,6 +8242,15 @@ interface UseTextEditOptions {
|
|
|
7347
8242
|
setStyle?: (id: string, style: TextStyle) => void;
|
|
7348
8243
|
/** Read screen-space pose for `id`. Called per frame while editing. */
|
|
7349
8244
|
getScreenPose: (id: string) => TextEditScreenPose | null;
|
|
8245
|
+
/**
|
|
8246
|
+
* The box, in CSS pixels relative to `container`, the overlay is visible
|
|
8247
|
+
* within — where the canvas clips the glyphs the overlay stands in for.
|
|
8248
|
+
* Re-read every frame. Omit it, or return `null`, to clip nothing.
|
|
8249
|
+
*
|
|
8250
|
+
* The clip cannot scroll, so a caret moving past its edge leaves the page
|
|
8251
|
+
* where it is; a scrollable container would drag the canvas after the caret.
|
|
8252
|
+
*/
|
|
8253
|
+
getClipRect?: () => TextEditClipRect | null;
|
|
7350
8254
|
/** Commit text. Caller wraps in op/undo. */
|
|
7351
8255
|
setText: (id: string, text: string) => void;
|
|
7352
8256
|
/**
|
|
@@ -7509,9 +8413,9 @@ declare function unionAABB<TPose extends RectPose>(parts: Iterable<TPose | null
|
|
|
7509
8413
|
* (`getText` / `getStyle` / `getRuns` / `setText` / `setRuns` / `setStyle`).
|
|
7510
8414
|
*
|
|
7511
8415
|
* Pose component: the helper reads `(x, y, width, height)` straight off
|
|
7512
|
-
* the node's pose (typed `RectPose`)
|
|
7513
|
-
*
|
|
7514
|
-
*
|
|
8416
|
+
* the node's pose (typed `RectPose`) and projects that box through the view
|
|
8417
|
+
* of the weasel canvas mounted inside `container` — see the `view` option.
|
|
8418
|
+
* The overlay is clipped to that canvas's box, where its glyphs are clipped.
|
|
7515
8419
|
* Consumers with non-rect poses should drop down to raw `useTextEdit` and
|
|
7516
8420
|
* supply their own `getScreenPose`.
|
|
7517
8421
|
*/
|
|
@@ -7525,6 +8429,7 @@ interface DefaultTextData {
|
|
|
7525
8429
|
runs?: readonly StyledRun[];
|
|
7526
8430
|
fill?: FillStyle | null;
|
|
7527
8431
|
stroke?: Stroke | null;
|
|
8432
|
+
verticalAlign?: TextVerticalAlign;
|
|
7528
8433
|
}
|
|
7529
8434
|
/** All-optional projections + fontSize fallback. */
|
|
7530
8435
|
interface UseSceneTextEditOptions<TData> {
|
|
@@ -7536,6 +8441,8 @@ interface UseSceneTextEditOptions<TData> {
|
|
|
7536
8441
|
getPaint?: (data: TData) => TextPaint | undefined;
|
|
7537
8442
|
/** Read rich-text runs from `data`. Default: `data.runs`. */
|
|
7538
8443
|
getRuns?: (data: TData) => readonly StyledRun[] | undefined;
|
|
8444
|
+
/** Read the box vertical alignment from `data`. Default: `data.verticalAlign`. */
|
|
8445
|
+
getVerticalAlign?: (data: TData) => TextVerticalAlign | undefined;
|
|
7539
8446
|
/** Produce updated data with new text. Default: `{ ...data, text }`. */
|
|
7540
8447
|
setText?: (data: TData, text: string) => TData;
|
|
7541
8448
|
/** Produce updated data with new runs. Default: `{ ...data, runs }`. */
|
|
@@ -7551,21 +8458,24 @@ interface UseSceneTextEditOptions<TData> {
|
|
|
7551
8458
|
/** Fallback fontSize when `style.fontSize` is unset. Default `16`. */
|
|
7552
8459
|
defaultFontSize?: number;
|
|
7553
8460
|
/**
|
|
7554
|
-
*
|
|
7555
|
-
*
|
|
8461
|
+
* The view to project through. Omit it and the view is read live from the
|
|
8462
|
+
* weasel canvas mounted inside `container` (the one a double-click landed
|
|
8463
|
+
* on, when there are several) — which is all a canvas that pans or zooms
|
|
8464
|
+
* needs. With no canvas there, the node's world box is passed through as
|
|
8465
|
+
* screen pixels.
|
|
8466
|
+
*
|
|
8467
|
+
* The overlay is positioned at the node's projected origin and CSS-scaled
|
|
7556
8468
|
* by the view, so every typographic metric on it — including the
|
|
7557
8469
|
* `fontSize` / `letterSpacing` a *run* carries — stays in world units and
|
|
7558
|
-
* scales together.
|
|
7559
|
-
* screen pixels (correct at `{x: 0, y: 0, scale: 1}`).
|
|
8470
|
+
* scales together.
|
|
7560
8471
|
*
|
|
7561
8472
|
* The overlay takes a single scale factor, so a non-uniform view scale is
|
|
7562
8473
|
* represented by its `scale.x`; text under `scale.x !== scale.y` will not
|
|
7563
8474
|
* match the canvas.
|
|
7564
8475
|
*
|
|
7565
|
-
*
|
|
7566
|
-
*
|
|
7567
|
-
*
|
|
7568
|
-
* the render that supplied it, which is correct for a controlled consumer.
|
|
8476
|
+
* Pass one to project through a camera other than the canvas's own. A
|
|
8477
|
+
* thunk is re-read on every projection; a plain `View` is the value from
|
|
8478
|
+
* the render that supplied it.
|
|
7569
8479
|
*/
|
|
7570
8480
|
view?: View | (() => View);
|
|
7571
8481
|
/**
|
|
@@ -7591,8 +8501,10 @@ interface UseSceneTextEditReturn extends UseTextEditReturn {
|
|
|
7591
8501
|
declare function useSceneTextEdit<TData extends DefaultTextData, TLayer extends string, TPose extends RectPose = RectPose>(scene: Scene<TData, TLayer, TPose>, container: HTMLElement | null, options?: UseSceneTextEditOptions<TData>): UseSceneTextEditReturn;
|
|
7592
8502
|
|
|
7593
8503
|
/**
|
|
7594
|
-
* Build a `TextDrawCommand`. `
|
|
7595
|
-
*
|
|
8504
|
+
* Build a `TextDrawCommand`. `textCommandFromPose` is the command for a text
|
|
8505
|
+
* node — what `kit:text` and `createTextLayer` both emit. `textCommand` takes
|
|
8506
|
+
* a plain string and wraps it in one run; `textCommandFromRuns` takes the
|
|
8507
|
+
* styled runs directly, for text that has no pose. All three
|
|
7596
8508
|
* resolve through `resolveTextStyle` + `resolveRuns`, so every emitter of a
|
|
7597
8509
|
* text command derives `align` and per-run resolution the same way — a
|
|
7598
8510
|
* caller that assembles the command by hand is one field away from a
|
|
@@ -7602,11 +8514,18 @@ declare function useSceneTextEdit<TData extends DefaultTextData, TLayer extends
|
|
|
7602
8514
|
* a HUD widget, a debug overlay — states its color on the run instead.
|
|
7603
8515
|
*/
|
|
7604
8516
|
|
|
7605
|
-
declare function textCommandFromRuns(x: number, y: number, runs: readonly StyledRun[], style?: TextStyle, maxWidth?: number, height?: number, verticalAlign?: TextVerticalAlign, paint?: TextPaint): DrawCommand;
|
|
8517
|
+
declare function textCommandFromRuns(x: number, y: number, runs: readonly StyledRun[], style?: TextStyle, maxWidth?: number, height?: number, verticalAlign?: TextVerticalAlign, paint?: TextPaint, width?: number): DrawCommand;
|
|
7606
8518
|
/** Build a draw command for a single unstyled string. Text is laid out with
|
|
7607
|
-
* the registered font's metrics, wrapped at `maxWidth
|
|
7608
|
-
* `height` when
|
|
7609
|
-
|
|
8519
|
+
* the registered font's metrics, wrapped at `maxWidth`, aligned across
|
|
8520
|
+
* `width` (default `maxWidth`) and within `height` when `verticalAlign` is
|
|
8521
|
+
* given. */
|
|
8522
|
+
declare function textCommand(x: number, y: number, text: string, style?: TextStyle, maxWidth?: number, height?: number, verticalAlign?: TextVerticalAlign, paint?: TextPaint, width?: number): DrawCommand;
|
|
8523
|
+
/**
|
|
8524
|
+
* The draw command for a text pose. Its wrap width, alignment box and runs
|
|
8525
|
+
* come from `textPoseLayoutInput`, so the renderer lays it out into exactly
|
|
8526
|
+
* the lines `layoutTextPose` reports for the same pose.
|
|
8527
|
+
*/
|
|
8528
|
+
declare function textCommandFromPose(pose: TextPose): TextDrawCommand;
|
|
7610
8529
|
|
|
7611
8530
|
/**
|
|
7612
8531
|
* Pure DOM ↔ `StyledRun[]` serializers for the contenteditable overlay
|
|
@@ -8098,10 +9017,8 @@ interface NestedHitOpts<TNode extends {
|
|
|
8098
9017
|
/** Compose a child's local pose into world coords given its parent's world
|
|
8099
9018
|
* pose. Same shape as `composeRectPose` (the default expectation). */
|
|
8100
9019
|
composePose: (parent: TPose, child: TPose) => TPose;
|
|
8101
|
-
/**
|
|
8102
|
-
|
|
8103
|
-
* `RectPose`). Override for non-rect poses (e.g. paths). */
|
|
8104
|
-
poseBounds?: (pose: TPose) => Bounds;
|
|
9020
|
+
/** How to read world poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
9021
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
8105
9022
|
/** Predicate for "this object is a nesting parent body". The leaf scan
|
|
8106
9023
|
* skips objects for which this returns true so a click on a parent's
|
|
8107
9024
|
* painted body resolves to a child leaf, not the parent itself. Default:
|
|
@@ -8130,6 +9047,22 @@ declare function nestedHitTester<TNode extends {
|
|
|
8130
9047
|
id: string;
|
|
8131
9048
|
}, TPose>(adapter: HitAdapter<TNode, TPose>, opts: NestedHitOpts<TNode, TPose>): NestedHitTester;
|
|
8132
9049
|
|
|
9050
|
+
type DerivePose<TPose> = (node: {
|
|
9051
|
+
pose: TPose;
|
|
9052
|
+
}, deps: readonly ({
|
|
9053
|
+
pose: TPose;
|
|
9054
|
+
} | undefined)[]) => TPose | null;
|
|
9055
|
+
/**
|
|
9056
|
+
* A container's pose as the envelope of what it holds, read through
|
|
9057
|
+
* `descriptor` — a rotated member contributes the extent of its ink. Register
|
|
9058
|
+
* the result under `UNION_OF_CHILDREN` in `createScene`'s `registry` to teach
|
|
9059
|
+
* a scene how to size its groups around a pose shape the kit cannot read.
|
|
9060
|
+
*
|
|
9061
|
+
* Returns `null` for an emptied container, which falls back to its authored
|
|
9062
|
+
* pose rather than collapsing to a zero box at the origin.
|
|
9063
|
+
*/
|
|
9064
|
+
declare function unionOfChildrenVia<TPose>(descriptor: PoseDescriptor<TPose>): DerivePose<TPose>;
|
|
9065
|
+
|
|
8133
9066
|
/**
|
|
8134
9067
|
* Fluent builder for `PolygonPath`. Hides the `Uint8Array` / `Float32Array`
|
|
8135
9068
|
* encoding behind move/line/curve/close calls and a final `build()`. Use
|
|
@@ -8401,9 +9334,7 @@ declare function pointAlongPath(path: Path, t: number, opts?: PointAlongPathOpti
|
|
|
8401
9334
|
*
|
|
8402
9335
|
* `scalePathToBounds` is for the resize interaction: given the path's
|
|
8403
9336
|
* current AABB and the desired new AABB, scales every coordinate
|
|
8404
|
-
* proportionally.
|
|
8405
|
-
* the corresponding axis to the new origin — preferable to dividing by
|
|
8406
|
-
* zero or refusing to resize.
|
|
9337
|
+
* proportionally.
|
|
8407
9338
|
*/
|
|
8408
9339
|
|
|
8409
9340
|
/**
|
|
@@ -8422,9 +9353,9 @@ declare function translatePolygonInPlace(path: PolygonPath, dx: number, dy: numb
|
|
|
8422
9353
|
* Scale a path's coords so its current AABB maps to `target`. Resize
|
|
8423
9354
|
* interactions use this to make a polygon follow a corner-handle drag.
|
|
8424
9355
|
*
|
|
8425
|
-
*
|
|
8426
|
-
* `
|
|
8427
|
-
*
|
|
9356
|
+
* A degenerate source axis (zero width or height) has no ratio to scale by,
|
|
9357
|
+
* so `boxToBox` translates that axis instead — a zero scale is not
|
|
9358
|
+
* invertible and would discard what is left on it.
|
|
8428
9359
|
*/
|
|
8429
9360
|
declare function scalePathToBounds(path: Path, target: RectPath): Path;
|
|
8430
9361
|
|
|
@@ -8581,48 +9512,6 @@ interface CreatePathLayerOpts<T> {
|
|
|
8581
9512
|
/** Build a `RenderLayer` that fills/strokes `Path` instances enumerated from a node list. */
|
|
8582
9513
|
declare function createPathLayer<T>(opts: CreatePathLayerOpts<T>): RenderLayer<unknown>;
|
|
8583
9514
|
|
|
8584
|
-
/**
|
|
8585
|
-
* Bezier flattening — subdivide cubic and quadratic segments into polyline
|
|
8586
|
-
* approximations within a flatness tolerance. Used by hit-testing and
|
|
8587
|
-
* (eventually) any kernel that doesn't want to special-case curves.
|
|
8588
|
-
*
|
|
8589
|
-
* The flatness metric is the maximum perpendicular distance from any
|
|
8590
|
-
* control point to the chord between endpoints. When that distance falls
|
|
8591
|
-
* below `tolerance`, the segment is "flat enough" and emitted as a single
|
|
8592
|
-
* line segment.
|
|
8593
|
-
*
|
|
8594
|
-
* Tolerance is in world units. 0.5 is a sensible default for screen-rate
|
|
8595
|
-
* rendering at 1× zoom; consumers that zoom in heavily should pass a
|
|
8596
|
-
* tighter tolerance.
|
|
8597
|
-
*/
|
|
8598
|
-
declare const DEFAULT_FLATTEN_TOLERANCE = 0.5;
|
|
8599
|
-
/**
|
|
8600
|
-
* Recursively subdivide a cubic bezier (P0..P3) and append `lineTo`-style
|
|
8601
|
-
* vertices to `out` (interleaved x,y). The starting endpoint is *not*
|
|
8602
|
-
* appended — callers usually emitted it as the segment's previous vertex.
|
|
8603
|
-
*/
|
|
8604
|
-
declare function flattenCubic(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, tolerance: number, out: number[]): void;
|
|
8605
|
-
/** Recursively subdivide a quadratic bezier (P0, P1, P2). */
|
|
8606
|
-
declare function flattenQuadratic(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, tolerance: number, out: number[]): void;
|
|
8607
|
-
/**
|
|
8608
|
-
* Like `flattenCubic` but also appends, for each new flattened point, its
|
|
8609
|
-
* arc-length fraction `t` (relative to the polyline distance accumulated so
|
|
8610
|
-
* far inside this curve) to `arcOut`. Caller then post-processes the segment's
|
|
8611
|
-
* `arcOut` range by dividing each by the segment's total flattened arc length
|
|
8612
|
-
* to yield t ∈ (0, 1].
|
|
8613
|
-
*
|
|
8614
|
-
* The returned values are *cumulative distance from the segment start*, not
|
|
8615
|
-
* normalized fractions. Two-pass design (accumulate, then divide) keeps the
|
|
8616
|
-
* recursive splitter simple — it doesn't need to know the total length up
|
|
8617
|
-
* front.
|
|
8618
|
-
*/
|
|
8619
|
-
declare function flattenCubicWithArcLen(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, tolerance: number, out: number[], arcOut: number[]): number;
|
|
8620
|
-
/** Flatten a quadratic bezier into line segments within `tolerance`, appending
|
|
8621
|
-
* points to `out` and their cumulative arc lengths to `arcOut`. The arc
|
|
8622
|
-
* lengths are what lets per-anchor color and dash phase be interpolated
|
|
8623
|
-
* evenly along the curve rather than per segment. */
|
|
8624
|
-
declare function flattenQuadraticWithArcLen(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, tolerance: number, out: number[], arcOut: number[]): number;
|
|
8625
|
-
|
|
8626
9515
|
/**
|
|
8627
9516
|
* `pathFromD` — build a weasel `Path` from an **SVG path-data string** (the
|
|
8628
9517
|
* value of SVG's `d` attribute, e.g. `"M0 0 L100 0 Z"`).
|
|
@@ -8716,17 +9605,16 @@ declare function splitPathByLine(path: Path, a: Point, b: Point, opts?: SplitByL
|
|
|
8716
9605
|
declare function unionBoundsPath(paths: Iterable<Path>): RectPath | null;
|
|
8717
9606
|
|
|
8718
9607
|
/**
|
|
8719
|
-
* `
|
|
9608
|
+
* `PoseDescriptor` for `Path` poses — wires `useResize` to operate
|
|
8720
9609
|
* on `Path` directly. `getBounds` defers to the same `boundsOfPath` kernel
|
|
8721
|
-
* the rest of the kit uses
|
|
8722
|
-
* coord against `src`/`dst`. Degenerate axes (zero src extent) collapse to
|
|
8723
|
-
* the new origin so resize from a flat edge doesn't produce NaN.
|
|
9610
|
+
* the rest of the kit uses.
|
|
8724
9611
|
*
|
|
8725
|
-
*
|
|
8726
|
-
* knows the group's origin AABB and uses it for every leaf,
|
|
8727
|
-
* each leaf scaling against its own AABB (which would ignore
|
|
9612
|
+
* `remapBounds` mirrors `scalePathToBounds` but takes `src` explicitly: the
|
|
9613
|
+
* resize hook knows the group's origin AABB and uses it for every leaf,
|
|
9614
|
+
* instead of each leaf scaling against its own AABB (which would ignore
|
|
9615
|
+
* group context).
|
|
8728
9616
|
*/
|
|
8729
|
-
declare const pathPoseDescriptor:
|
|
9617
|
+
declare const pathPoseDescriptor: PoseDescriptor<Path>;
|
|
8730
9618
|
|
|
8731
9619
|
/**
|
|
8732
9620
|
* `OriginProjection` for `Path` poses. The "origin" is the top-left of the
|
|
@@ -8862,11 +9750,6 @@ declare function pathExclude(...paths: Path[]): PolygonPath;
|
|
|
8862
9750
|
* Fracture N paths along every intersection into the maximal set of
|
|
8863
9751
|
* non-overlapping regions. Returns one `PolygonPath` per region.
|
|
8864
9752
|
*
|
|
8865
|
-
* Algorithm: for every non-empty subset S ⊆ {A1..AN}, emit the region
|
|
8866
|
-
* `(∩ S) − (∪ complement)` — points covered by exactly the members of S
|
|
8867
|
-
* and no others. By construction the emitted regions are pairwise disjoint
|
|
8868
|
-
* and their union equals `pathUnion(A1..AN)`.
|
|
8869
|
-
*
|
|
8870
9753
|
* For N=2 this collapses to the three Illustrator "Divide" outputs
|
|
8871
9754
|
* (A−B, B−A, A∩B). For N=3 up to 7 regions are emitted. The 2^N − 1
|
|
8872
9755
|
* subset count limits this to small N in practice; passing more than ~8
|
|
@@ -9053,8 +9936,12 @@ interface PaintBindContext {
|
|
|
9053
9936
|
* from the paint's space to the frame the geometry arrives in. Paired with
|
|
9054
9937
|
* the vertex shader's `v_world` varying this is *the* paint-space
|
|
9055
9938
|
* convention; it is not gradient-specific.
|
|
9939
|
+
*
|
|
9940
|
+
* `null` when that space has no inverse — a transform or view that flattens
|
|
9941
|
+
* an axis. Nothing the paint draws there means anything, so `bind` should
|
|
9942
|
+
* return `null` and draw nothing.
|
|
9056
9943
|
*/
|
|
9057
|
-
spaceInverse(units: GradientUnits | undefined): Mat3$1;
|
|
9944
|
+
spaceInverse(units: GradientUnits | undefined): Mat3$1 | null;
|
|
9058
9945
|
/**
|
|
9059
9946
|
* Bake a stop ramp into the frame's ramp atlas, bind that atlas to a texture
|
|
9060
9947
|
* unit, and return the `v` the ramp's own row sits at — every ramp in a
|
|
@@ -9404,21 +10291,15 @@ interface ArrayAdapterConfig<TNode extends {
|
|
|
9404
10291
|
* Consumers own id generation and any palette/payload fields. Returning
|
|
9405
10292
|
* `null` aborts the insert. When omitted, `commitInsert` returns `null`. */
|
|
9406
10293
|
createDefault?: (bounds: Bounds) => TNode | null;
|
|
9407
|
-
/**
|
|
9408
|
-
*
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
* `pathPoseDescriptor.intersectsRect`). */
|
|
9413
|
-
intersectsRect?: (pose: TPose, rect: Bounds) => boolean;
|
|
10294
|
+
/** How to read and rewrite item poses. Default `RECT_POSE_DESCRIPTOR`,
|
|
10295
|
+
* which reads the pose as its own AABB — the canonical axis-aligned rect
|
|
10296
|
+
* pose. `AUTO_POSE_DESCRIPTOR` lives above `core/` and so cannot be the
|
|
10297
|
+
* default here; pass it for a scene whose poses may be Paths. */
|
|
10298
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
9414
10299
|
/** Factory for fresh node ids in `commitPaste`. Default: `crypto.randomUUID()`
|
|
9415
10300
|
* when available, otherwise a monotonic `paste-<n>` counter. Override
|
|
9416
10301
|
* when consumers want stable id schemes (e.g. `clip-${n++}`). */
|
|
9417
10302
|
nextId?: () => string;
|
|
9418
|
-
/** Translate a pose by `(dx, dy)`. Default: shallow-spread `{ x, y }`,
|
|
9419
|
-
* which matches the canonical axis-aligned rect pose. Override for
|
|
9420
|
-
* non-rect poses whose translation isn't a top-level `x`/`y` bump. */
|
|
9421
|
-
translatePose?: (pose: TPose, dx: number, dy: number) => TPose;
|
|
9422
10303
|
}
|
|
9423
10304
|
/**
|
|
9424
10305
|
* Combined adapter satisfying every narrow adapter the kit ships. Methods
|
|
@@ -9590,14 +10471,6 @@ interface GuidesLayerOpts {
|
|
|
9590
10471
|
* screen space, projected from world offsets via the active view. */
|
|
9591
10472
|
declare function createGuidesLayer(opts: GuidesLayerOpts): RenderLayer<unknown>;
|
|
9592
10473
|
|
|
9593
|
-
/** Axis-aligned bounding box. Alignment matches AABBs throughout; a rotated
|
|
9594
|
-
* pose enters as the AABB of its ink (see `AlignBoundsProjection.boundsOf`). */
|
|
9595
|
-
interface AlignBounds {
|
|
9596
|
-
x: number;
|
|
9597
|
-
y: number;
|
|
9598
|
-
width: number;
|
|
9599
|
-
height: number;
|
|
9600
|
-
}
|
|
9601
10474
|
/** Which feature of a box to test against candidates, per axis.
|
|
9602
10475
|
* 'min' = left/top edge, 'center' = centerline, 'max' = right/bottom edge. */
|
|
9603
10476
|
type AlignAnchor = 'min' | 'center' | 'max';
|
|
@@ -9610,31 +10483,18 @@ interface AlignMatchResult {
|
|
|
9610
10483
|
activeX: Guide | null;
|
|
9611
10484
|
activeY: Guide | null;
|
|
9612
10485
|
}
|
|
9613
|
-
/** Bounds analog of the gesture `OriginProjection`: reads an AABB from a pose
|
|
9614
|
-
* and translates a pose. The rect default handles `{x,y,width,height}` poses;
|
|
9615
|
-
* non-rect poses (Path, polygon) supply their own. */
|
|
9616
|
-
interface AlignBoundsProjection<TPose> {
|
|
9617
|
-
/** The pose's *visual* AABB — a rotated pose reports the extent of its ink,
|
|
9618
|
-
* not the box it was posed in. Guides and matching both read this, so an
|
|
9619
|
-
* implementation that returns the stored box makes a rotated shape snap to
|
|
9620
|
-
* lines nothing is drawn at. */
|
|
9621
|
-
boundsOf(pose: TPose): AlignBounds;
|
|
9622
|
-
/** Move the pose, preserving every other field it carries — nothing
|
|
9623
|
-
* downstream re-derives rotation or style from anywhere else. */
|
|
9624
|
-
translate(pose: TPose, dx: number, dy: number): TPose;
|
|
9625
|
-
}
|
|
9626
10486
|
/** Which candidate lines to derive from a set of poses — edges, centers, or
|
|
9627
10487
|
* both, and whether the page box contributes its own. */
|
|
9628
|
-
interface DeriveAlignmentGuidesOptions<TPose =
|
|
10488
|
+
interface DeriveAlignmentGuidesOptions<TPose = Bounds> {
|
|
9629
10489
|
/** Include the document/page box's edges + center as candidates. */
|
|
9630
|
-
page?:
|
|
10490
|
+
page?: Bounds;
|
|
9631
10491
|
/** Emit left/right (x) and top/bottom (y) edge guides. Default true. */
|
|
9632
10492
|
edges?: boolean;
|
|
9633
10493
|
/** Emit centerX (x) and centerY (y) guides. Default true. */
|
|
9634
10494
|
centers?: boolean;
|
|
9635
|
-
/**
|
|
9636
|
-
*
|
|
9637
|
-
|
|
10495
|
+
/** How to read each target. Pass the same descriptor `alignMoveBehavior`
|
|
10496
|
+
* gets, or the two sides disagree. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
10497
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
9638
10498
|
}
|
|
9639
10499
|
/** Common options shared by the three alignment behavior factories. */
|
|
9640
10500
|
interface AlignmentBehaviorBase {
|
|
@@ -9654,20 +10514,15 @@ interface AlignmentBehaviorBase {
|
|
|
9654
10514
|
/** Derive candidate alignment lines from a set of sibling poses plus an
|
|
9655
10515
|
* optional page box. Each box contributes up to 3 guides per axis: the two
|
|
9656
10516
|
* edges and the center. Overlapping offsets collapse to one candidate.
|
|
9657
|
-
* Poses go through the same
|
|
10517
|
+
* Poses go through the same descriptor `alignMoveBehavior` matches with, so
|
|
9658
10518
|
* a rotated sibling advertises its ink edges rather than its stored box. */
|
|
9659
|
-
declare function deriveAlignmentGuides<TPose =
|
|
10519
|
+
declare function deriveAlignmentGuides<TPose = Bounds>(targets: readonly TPose[], opts?: DeriveAlignmentGuidesOptions<TPose>): Guide[];
|
|
9660
10520
|
|
|
9661
10521
|
/** Move/insert test all three features per axis. */
|
|
9662
10522
|
declare const MOVE_ANCHORS: {
|
|
9663
10523
|
x: readonly AlignAnchor[];
|
|
9664
10524
|
y: readonly AlignAnchor[];
|
|
9665
10525
|
};
|
|
9666
|
-
/** Default projection for rect-shaped poses (`{x,y,width,height,rotation?}`).
|
|
9667
|
-
* A rotated pose reports the AABB of its ink, so guides derived from a
|
|
9668
|
-
* stationary sibling and the box a dragged selection matches with are the
|
|
9669
|
-
* same measurement. */
|
|
9670
|
-
declare const RECT_ALIGN_PROJECTION: AlignBoundsProjection<RectPose>;
|
|
9671
10526
|
/**
|
|
9672
10527
|
* Match a moving box's selected edge/center features against candidate guide
|
|
9673
10528
|
* lines. Returns the per-axis snap delta and the matched candidate line(s).
|
|
@@ -9679,7 +10534,7 @@ declare const RECT_ALIGN_PROJECTION: AlignBoundsProjection<RectPose>;
|
|
|
9679
10534
|
* distance along that axis alone, so there is an exact answer rather than an
|
|
9680
10535
|
* approximation. Pass the same number twice for a world-space tolerance.
|
|
9681
10536
|
*/
|
|
9682
|
-
declare function matchAlignment(bounds:
|
|
10537
|
+
declare function matchAlignment(bounds: Bounds, candidates: readonly Guide[], worldTolerance: {
|
|
9683
10538
|
x: number;
|
|
9684
10539
|
y: number;
|
|
9685
10540
|
}, anchors: {
|
|
@@ -9687,9 +10542,9 @@ declare function matchAlignment(bounds: AlignBounds, candidates: readonly Guide[
|
|
|
9687
10542
|
y: readonly AlignAnchor[];
|
|
9688
10543
|
}): AlignMatchResult;
|
|
9689
10544
|
|
|
9690
|
-
/** Options for move/insert — adds the
|
|
10545
|
+
/** Options for move/insert — adds the pose descriptor for non-rect poses. */
|
|
9691
10546
|
interface AlignMoveArgs<TPose> extends AlignmentBehaviorBase {
|
|
9692
|
-
|
|
10547
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
9693
10548
|
}
|
|
9694
10549
|
/** Move behavior: snap the dragged selection's union box (edges + center) to
|
|
9695
10550
|
* candidates, shaping the proposed translate. The gesture applies the
|
|
@@ -9702,10 +10557,10 @@ declare function alignMoveBehavior<TPose>(args: AlignMoveArgs<TPose>): MoveBehav
|
|
|
9702
10557
|
declare function alignInsertBehavior<TPose>(args: AlignmentBehaviorBase): InsertBehavior<TPose>;
|
|
9703
10558
|
/** Resize constraint: snap the moving edge(s) of the dragged rect to
|
|
9704
10559
|
* candidates. The pinned (anchor) edge stays fixed. Publishes the line(s). */
|
|
9705
|
-
declare function alignResizeBehavior<TPose extends
|
|
10560
|
+
declare function alignResizeBehavior<TPose extends Bounds>(args: AlignmentBehaviorBase): BoundsConstraint<TPose>;
|
|
9706
10561
|
|
|
9707
10562
|
/** AABB center of an unrotated rect — the canonical rotation pivot. */
|
|
9708
|
-
declare function aabbCenter(bounds:
|
|
10563
|
+
declare function aabbCenter(bounds: Bounds): {
|
|
9709
10564
|
x: number;
|
|
9710
10565
|
y: number;
|
|
9711
10566
|
};
|
|
@@ -9715,7 +10570,7 @@ declare function rotatePoint(px: number, py: number, cx: number, cy: number, ang
|
|
|
9715
10570
|
y: number;
|
|
9716
10571
|
};
|
|
9717
10572
|
/** Four corners of an unrotated rect, in TL/TR/BR/BL order. */
|
|
9718
|
-
declare function rectCorners(bounds:
|
|
10573
|
+
declare function rectCorners(bounds: Bounds): {
|
|
9719
10574
|
x: number;
|
|
9720
10575
|
y: number;
|
|
9721
10576
|
}[];
|
|
@@ -10000,65 +10855,6 @@ interface AnchorHit {
|
|
|
10000
10855
|
* are within `threshold` (controls are smaller and rendered on top). */
|
|
10001
10856
|
declare function hitAnchor(path: PolygonPath, worldX: number, worldY: number, threshold: number): AnchorHit | null;
|
|
10002
10857
|
|
|
10003
|
-
/**
|
|
10004
|
-
* Typed keys for the gesture/behavior scratch store.
|
|
10005
|
-
*
|
|
10006
|
-
* Gestures expose `ctx.scratch: Record<string, unknown>` as a per-gesture
|
|
10007
|
-
* mutable bag that behaviors use to stash state across `onDown` / `onMove`
|
|
10008
|
-
* / `onEnd` calls. The store is `unknown`-valued because behaviors are
|
|
10009
|
-
* tool-agnostic — a single behavior may run under different tools with
|
|
10010
|
-
* different scratch shapes. Without a typing convention every read site
|
|
10011
|
-
* has to `(ctx.scratch as <some shape>)[KEY]`, and a writer changing the
|
|
10012
|
-
* shape can silently break readers with no compile-time signal.
|
|
10013
|
-
*
|
|
10014
|
-
* `ScratchKey<T>` is a phantom-typed string that carries its payload type
|
|
10015
|
-
* via a branded interface. `getScratch` and `setScratch` use the brand to
|
|
10016
|
-
* narrow / constrain at the typing layer; at runtime the key is just its
|
|
10017
|
-
* underlying string and the store remains a plain `Record`.
|
|
10018
|
-
*
|
|
10019
|
-
* @example
|
|
10020
|
-
* ```ts
|
|
10021
|
-
* // Module-level (or behavior-level) constant, shared by writer + reader:
|
|
10022
|
-
* const LASSO_VERTICES = scratchKey<readonly { x: number; y: number }[]>('lasso.vertices');
|
|
10023
|
-
*
|
|
10024
|
-
* // Writer (a tool's onMove):
|
|
10025
|
-
* setScratch(ctx.scratch, LASSO_VERTICES, vertices);
|
|
10026
|
-
*
|
|
10027
|
-
* // Reader (a behavior's onEnd):
|
|
10028
|
-
* const vertices = getScratch(ctx.scratch, LASSO_VERTICES) ?? [];
|
|
10029
|
-
* // ^? readonly { x: number; y: number }[] | undefined
|
|
10030
|
-
* ```
|
|
10031
|
-
*/
|
|
10032
|
-
/** Phantom-typed key for a scratch slot. The `__scratchKeyPayload` phantom
|
|
10033
|
-
* field carries the value type without occupying any runtime memory. */
|
|
10034
|
-
interface ScratchKey<T> {
|
|
10035
|
-
readonly name: string;
|
|
10036
|
-
/** Phantom — never read at runtime. Only present so TypeScript can
|
|
10037
|
-
* recover `T` at use sites. */
|
|
10038
|
-
readonly __scratchKeyPayload?: (_: T) => T;
|
|
10039
|
-
}
|
|
10040
|
-
/** Compatible scratch store shape. The kit's gesture context's `scratch`
|
|
10041
|
-
* field already satisfies this; consumers don't need to construct one. */
|
|
10042
|
-
type ScratchStore = Record<string, unknown>;
|
|
10043
|
-
/**
|
|
10044
|
-
* Make a typed scratch key. Use module-level constants so the same key
|
|
10045
|
-
* is shared by writer and reader.
|
|
10046
|
-
*
|
|
10047
|
-
* Namespace the name by behavior or feature to avoid collisions
|
|
10048
|
-
* (`'behavior.field'` is a good convention). Two keys with the same
|
|
10049
|
-
* `name` refer to the same slot at runtime — the type parameter is a
|
|
10050
|
-
* compile-time contract, not a uniqueness guarantee.
|
|
10051
|
-
*/
|
|
10052
|
-
declare function scratchKey<T>(name: string): ScratchKey<T>;
|
|
10053
|
-
/** Read a typed slot from the scratch store. Returns `undefined` if
|
|
10054
|
-
* nothing has been written under the key. */
|
|
10055
|
-
declare function getScratch<T>(store: ScratchStore, key: ScratchKey<T>): T | undefined;
|
|
10056
|
-
/** Write a value to a typed slot. Overwrites whatever was there. */
|
|
10057
|
-
declare function setScratch<T>(store: ScratchStore, key: ScratchKey<T>, value: T): void;
|
|
10058
|
-
/** Remove a slot from the scratch store. Returns `true` if it was set,
|
|
10059
|
-
* `false` if it wasn't. */
|
|
10060
|
-
declare function deleteScratch<T>(store: ScratchStore, key: ScratchKey<T>): boolean;
|
|
10061
|
-
|
|
10062
10858
|
/** Options for `selectFromLasso`. */
|
|
10063
10859
|
interface SelectFromLassoOptions {
|
|
10064
10860
|
/** Hit mode for `hitTestLasso`. Default 'intersect'. */
|
|
@@ -10076,7 +10872,11 @@ type AlignEdge = 'left' | 'right' | 'top' | 'bottom' | 'center-x' | 'center-y';
|
|
|
10076
10872
|
/** Adapter for `useAlign`. */
|
|
10077
10873
|
interface AlignAdapter<TPose> {
|
|
10078
10874
|
getSelection(): NodeId[];
|
|
10875
|
+
/** The pose as stored — local to the node's parent. */
|
|
10079
10876
|
getPose(id: NodeId): TPose;
|
|
10877
|
+
/** The parent chain, for a scene whose container poses define a frame.
|
|
10878
|
+
* Omit it (or leave `composition` unset) for an absolute-pose scene. */
|
|
10879
|
+
getParent?(id: NodeId): NodeId | null;
|
|
10080
10880
|
applyOps?(ops: Op[], label?: string): void;
|
|
10081
10881
|
}
|
|
10082
10882
|
/** Options for `useAlign`. */
|
|
@@ -10084,38 +10884,30 @@ interface UseAlignOptions<TPose> {
|
|
|
10084
10884
|
/** Projection between `TPose` and bounds. Defaults to `RECT_POSE_DESCRIPTOR`
|
|
10085
10885
|
* for `{x,y,width,height}` poses. Pass `pathPoseDescriptor` for `Path`
|
|
10086
10886
|
* poses so polygon coords translate correctly. */
|
|
10087
|
-
geometry?:
|
|
10887
|
+
geometry?: PoseDescriptor<TPose>;
|
|
10088
10888
|
/** Label passed to applyOps. Default 'Align'. */
|
|
10089
10889
|
label?: string;
|
|
10890
|
+
/** How local poses fold up to world. Default IDENTITY, where the two are
|
|
10891
|
+
* the same value and the alignment runs entirely in stored coordinates. */
|
|
10892
|
+
composition?: PoseComposition<TPose>;
|
|
10090
10893
|
}
|
|
10091
10894
|
/** Return shape of `useAlign`. */
|
|
10092
10895
|
interface UseAlignReturn {
|
|
10093
10896
|
/** Imperative trigger. No-op when fewer than 2 items selected. */
|
|
10094
10897
|
align(edge: AlignEdge): void;
|
|
10095
10898
|
}
|
|
10096
|
-
/**
|
|
10097
|
-
* The pose's *visual* bounds: its descriptor bounds expanded to cover the
|
|
10098
|
-
* rotated rectangle, so a turned shape reports the extent of its ink rather
|
|
10099
|
-
* than the box it was posed in. Align, distribute and flip all fold these.
|
|
10100
|
-
*
|
|
10101
|
-
* Both ends of an align must use it — a visual union measured against
|
|
10102
|
-
* unrotated member boxes misplaces every rotated member. The expanded box
|
|
10103
|
-
* shares its centre with the stored one, so the delta stays a translation of
|
|
10104
|
-
* the stored pose and no re-posing is needed.
|
|
10105
|
-
*/
|
|
10106
|
-
declare function visualBoundsViaDescriptor<TPose>(pose: TPose, geometry: PoseProjection<TPose>): ResizePose;
|
|
10107
10899
|
/** Compute the (dx, dy) translation that moves AABB `b` so that the requested
|
|
10108
10900
|
* `edge`/center matches the corresponding feature of the union AABB `u`. */
|
|
10109
|
-
declare function alignDeltaFor(b:
|
|
10901
|
+
declare function alignDeltaFor(b: Bounds, u: Bounds, edge: AlignEdge): {
|
|
10110
10902
|
dx: number;
|
|
10111
10903
|
dy: number;
|
|
10112
10904
|
};
|
|
10113
|
-
/** Translate `pose` by `(dx, dy)` using `geometry.translate` if available,
|
|
10114
|
-
* otherwise via `remapBounds` with a translated `dst` rect. */
|
|
10115
|
-
declare function translatePoseViaDescriptor<TPose>(pose: TPose, dx: number, dy: number, geometry: PoseProjection<TPose>): TPose;
|
|
10116
10905
|
/** Align the current multi-selection to a shared edge or center of the
|
|
10117
10906
|
* selection's union AABB. No-op when fewer than 2 items selected.
|
|
10118
|
-
* Single batch — one undo step.
|
|
10907
|
+
* Single batch — one undo step.
|
|
10908
|
+
*
|
|
10909
|
+
* The edge is a world edge: bounds are measured and translated in world, and
|
|
10910
|
+
* each result is stored back in its own parent's frame. */
|
|
10119
10911
|
declare function useAlign<TPose>(adapter: AlignAdapter<TPose>, options?: UseAlignOptions<TPose>): UseAlignReturn;
|
|
10120
10912
|
|
|
10121
10913
|
/** Axis along which selection is distributed. `'x'` spreads horizontally. */
|
|
@@ -10127,18 +10919,25 @@ type DistributeMode = 'centers' | 'gaps';
|
|
|
10127
10919
|
/** Adapter for `useDistribute`. */
|
|
10128
10920
|
interface DistributeAdapter<TPose> {
|
|
10129
10921
|
getSelection(): NodeId[];
|
|
10922
|
+
/** The pose as stored — local to the node's parent. */
|
|
10130
10923
|
getPose(id: NodeId): TPose;
|
|
10924
|
+
/** The parent chain, for a scene whose container poses define a frame.
|
|
10925
|
+
* Omit it (or leave `composition` unset) for an absolute-pose scene. */
|
|
10926
|
+
getParent?(id: NodeId): NodeId | null;
|
|
10131
10927
|
applyOps?(ops: Op[], label?: string): void;
|
|
10132
10928
|
}
|
|
10133
10929
|
/** Options for `useDistribute`. */
|
|
10134
10930
|
interface UseDistributeOptions<TPose> {
|
|
10135
10931
|
/** Projection between `TPose` and bounds. Defaults to `RECT_POSE_DESCRIPTOR`
|
|
10136
10932
|
* for `{x,y,width,height}` poses. */
|
|
10137
|
-
geometry?:
|
|
10933
|
+
geometry?: PoseDescriptor<TPose>;
|
|
10138
10934
|
/** Default mode when `distribute(axis)` is called without one. Default 'centers'. */
|
|
10139
10935
|
defaultMode?: DistributeMode;
|
|
10140
10936
|
/** Label passed to applyOps. Default 'Distribute'. */
|
|
10141
10937
|
label?: string;
|
|
10938
|
+
/** How local poses fold up to world. Default IDENTITY, where the two are
|
|
10939
|
+
* the same value and the spread runs entirely in stored coordinates. */
|
|
10940
|
+
composition?: PoseComposition<TPose>;
|
|
10142
10941
|
}
|
|
10143
10942
|
/** Return shape of `useDistribute`. */
|
|
10144
10943
|
interface UseDistributeReturn {
|
|
@@ -10147,7 +10946,10 @@ interface UseDistributeReturn {
|
|
|
10147
10946
|
}
|
|
10148
10947
|
/** Distribute the current multi-selection along `axis`. Requires ≥3 items;
|
|
10149
10948
|
* no-op otherwise. Endpoints (min and max along the axis) stay put; the
|
|
10150
|
-
* remaining items are repositioned. Single batch — one undo step.
|
|
10949
|
+
* remaining items are repositioned. Single batch — one undo step.
|
|
10950
|
+
*
|
|
10951
|
+
* The span being divided is a world span: bounds are measured and translated
|
|
10952
|
+
* in world, and each result is stored back in its own parent's frame. */
|
|
10151
10953
|
declare function useDistribute<TPose>(adapter: DistributeAdapter<TPose>, options?: UseDistributeOptions<TPose>): UseDistributeReturn;
|
|
10152
10954
|
|
|
10153
10955
|
/** The six Boolean path operations, each acting on the current selection and
|
|
@@ -10279,7 +11081,7 @@ interface TweenPoseOptions<TPose> {
|
|
|
10279
11081
|
easing?: EasingSpec;
|
|
10280
11082
|
/** Pose descriptor with a `lerp(from, to, t)` method. Defaults to
|
|
10281
11083
|
* `RECT_POSE_DESCRIPTOR`, which interpolates x/y/width/height linearly. */
|
|
10282
|
-
geometry?:
|
|
11084
|
+
geometry?: PoseDescriptor<TPose>;
|
|
10283
11085
|
/** When true (default), emit a transform op before the tween so undo
|
|
10284
11086
|
* restores the pre-animation pose. */
|
|
10285
11087
|
recordOp?: boolean;
|
|
@@ -10295,7 +11097,7 @@ interface SpringPoseOptions<TPose> {
|
|
|
10295
11097
|
stiffness?: number;
|
|
10296
11098
|
damping?: number;
|
|
10297
11099
|
mass?: number;
|
|
10298
|
-
geometry?:
|
|
11100
|
+
geometry?: PoseDescriptor<TPose>;
|
|
10299
11101
|
recordOp?: boolean;
|
|
10300
11102
|
opLabel?: string;
|
|
10301
11103
|
onDone?: () => void;
|
|
@@ -10330,7 +11132,7 @@ interface AnimateOnSetPoseOptions<TPose> {
|
|
|
10330
11132
|
damping?: number;
|
|
10331
11133
|
mass?: number;
|
|
10332
11134
|
};
|
|
10333
|
-
geometry?:
|
|
11135
|
+
geometry?: PoseDescriptor<TPose>;
|
|
10334
11136
|
/** Predicate: return false to skip animation and write through immediately. */
|
|
10335
11137
|
shouldAnimate?: (id: string, from: TPose, to: TPose) => boolean;
|
|
10336
11138
|
/** Convenience: when true, auto-skip animation if the id is currently being
|
|
@@ -10371,7 +11173,7 @@ interface LifecycleAnimation<TPose> {
|
|
|
10371
11173
|
exitTo?: (current: TPose) => TPose;
|
|
10372
11174
|
ms?: number;
|
|
10373
11175
|
easing?: EasingSpec;
|
|
10374
|
-
geometry?:
|
|
11176
|
+
geometry?: PoseDescriptor<TPose>;
|
|
10375
11177
|
}
|
|
10376
11178
|
/** Wrap an adapter so inserts and removals animate — the scene-graph
|
|
10377
11179
|
* equivalent of CSS enter/leave transitions. */
|
|
@@ -10416,6 +11218,8 @@ interface MomentumOptions {
|
|
|
10416
11218
|
* decays the velocity). Default 'stop'.
|
|
10417
11219
|
*/
|
|
10418
11220
|
boundary?: 'stop' | 'continue';
|
|
11221
|
+
/** How to translate poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
11222
|
+
poseDescriptor?: PoseDescriptor<unknown>;
|
|
10419
11223
|
}
|
|
10420
11224
|
/**
|
|
10421
11225
|
* Move behavior that keeps a dragged node coasting after the pointer is
|
|
@@ -10887,43 +11691,6 @@ declare function CropIcon(): react_jsx_runtime.JSX.Element;
|
|
|
10887
11691
|
declare const PAINTED_CURSOR_LAYER_ID = "painted-cursor";
|
|
10888
11692
|
declare function createPaintedCursorLayer(state: PaintedCursorState): RenderLayer<unknown>;
|
|
10889
11693
|
|
|
10890
|
-
/** What the registry knows at dispatch time. */
|
|
10891
|
-
interface EligibilityState {
|
|
10892
|
-
focusedId: string | null;
|
|
10893
|
-
heldTriggers: ReadonlySet<string>;
|
|
10894
|
-
/** Ids the host reports as hotkey-engaged. A declared `offhand` registers
|
|
10895
|
-
* the binding, but `tool.offhand`'s invoker still reports engagement by
|
|
10896
|
-
* pushing an id — this retires only if that contract changes. */
|
|
10897
|
-
engagedIds?: ReadonlySet<string>;
|
|
10898
|
-
/** Whether the active mode allows these capability tags. Omitted → allow. */
|
|
10899
|
-
allows?: (tags: readonly CapabilityTag[]) => boolean;
|
|
10900
|
-
}
|
|
10901
|
-
/**
|
|
10902
|
-
* The scope tier an entry's bindings are live at, or null when none are.
|
|
10903
|
-
* Ordered hotkey > active > ambient to match the dispatcher's own walk.
|
|
10904
|
-
*/
|
|
10905
|
-
declare function liveScope(id: string, eligibility: Eligibility, state: EligibilityState): BindingScope | null;
|
|
10906
|
-
|
|
10907
|
-
/**
|
|
10908
|
-
* Every binding the entry set contributes right now, each tiered by the
|
|
10909
|
-
* entry's own declared eligibility. Entries with no live tier are omitted.
|
|
10910
|
-
*
|
|
10911
|
-
* Order is preserved: `matchSorted` sorts by specificity within a scope and
|
|
10912
|
-
* breaks ties by declaration order, so the caller's entry order decides which
|
|
10913
|
-
* of two same-specificity bindings in one tier wins.
|
|
10914
|
-
*/
|
|
10915
|
-
declare function scopeBindings(entries: Iterable<Contribution>, state: EligibilityState): ScopedBinding[];
|
|
10916
|
-
|
|
10917
|
-
/**
|
|
10918
|
-
* Concatenate contribution bundles into one registry, preserving order —
|
|
10919
|
-
* entry order decides which of two same-specificity bindings in one scope
|
|
10920
|
-
* tier wins, so it is part of the result, not an accident of it.
|
|
10921
|
-
*
|
|
10922
|
-
* Throws on a duplicate id rather than dropping one: a feature silently
|
|
10923
|
-
* losing its bindings is the failure this registry exists to make loud.
|
|
10924
|
-
*/
|
|
10925
|
-
declare function mergeContributions(...bundles: readonly Contribution[][]): Contribution[];
|
|
10926
|
-
|
|
10927
11694
|
/** Appearance of the dashed box drawn during a marquee or insert drag. */
|
|
10928
11695
|
interface InsertOverlayStyle {
|
|
10929
11696
|
fill?: string;
|
|
@@ -10932,4 +11699,4 @@ interface InsertOverlayStyle {
|
|
|
10932
11699
|
lineWidth?: number;
|
|
10933
11700
|
}
|
|
10934
11701
|
|
|
10935
|
-
export { ANCHOR_HIT_BASE_PX, Action, type ActionShortcut, ActionsProp, ActionsProviderIfRoot, ActionsRegistry, Affordance, AffordanceBinding, AffordanceHit, AffordanceRegion, type AffordanceRegionHit, type AlignAdapter, type AlignAnchor, type AlignBounds, type AlignBoundsProjection, type AlignEdge, type AlignMatchResult, type AlignMoveArgs, type AlignmentBehaviorBase, type AnchorHit, type AnchorScratch, type AnchorState, type AnimateOnSetPoseOptions, AnimationHandle, Animator, AnyTool, AreaSelectAdapter, type ArrayAdapter, type ArrayAdapterConfig, ArrowIcon, BUILTIN_MARKERS, BUNDLE_TOOLS, BindingScope, BooleansAdapter, Bounds, BoundsConstraint, type BuildChromeCtxArgs, BuiltinShapeToolId, type BuiltinToolId, type BuiltinToolOptions, COARSE_TARGET_SCALE, CURVE_REPS, type CanvasExtensionApi, type CanvasFocusReturn, type CanvasHelpers, type CanvasProps, type CanvasSelectionMode, type CanvasSize, type CanvasSizeSnapshot, type CanvasSurfaceHelpers, CanvasView, type CanvasViewHelpers, type CanvasViewProps, type CaretIndexAtOpts, type CellHighlightLayerOpts, ChromeCtx, ChromeId, ChromeState, type ClampBounds, ClipboardSnapshot, type CoalescedCtx, type ColorInterpolate, ColorOverrideRegistry, type ColorSpace, CommonAffordanceScratch, type ComposeSelectionPoseOpts, type ComputeFitViewOptions, Condition, ContentHandlerEntry, Contribution, type CornerResizeAffordanceOptions, type CornerResizeScratch, type CreateChildrenLayerOpts, type CreateParallaxLayerOpts, type CreatePathEditingOverlayLayerOptions, type CreatePathLayerOpts, type CreatePenPreviewLayerOptions, type CreateTextLayerOpts, type CreateViewResolverOpts, type CreateViewportLayerOpts, CropIcon, CursorCoordsHud, type CursorCoordsHudProps, type CurveRepKind, type CurveRepresentation, type CustomLayerEntry, type CycleHandle, type CycleVertexColorsOptions, DEFAULT_ALPHA_DECAY, DEFAULT_ALPHA_MIN, DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME, DEFAULT_DEVICE_PROFILE, DEFAULT_FILL_COLOR, DEFAULT_FLATTEN_TOLERANCE, DEFAULT_GUIDE_TOLERANCE_PX, DEFAULT_HANDLE_SIZE, DEFAULT_MAX_ZOOM, DEFAULT_MIN_ZOOM, DEFAULT_PALETTE, DEFAULT_ROTATION_HANDLE_DISTANCE, DEFAULT_SHAPE_FILL, DEFAULT_STROKE_COLOR, DEFAULT_VELOCITY_DECAY, DebugConfig, DebugSink, DebugSnapshot, DebugStrokes, DebugTheme, type DefaultTextData, DepRegistryProviderIfRoot, DepSchema, type DeriveAlignmentGuidesOptions, DerivedDep, DetectedDeviceFacts, DeviceProfile, DeviceProfileProvider, type DeviceProfileProviderProps, Dims, type Discriminator, Dispatcher, type DistributeAdapter, type DistributeAxis, type DistributeMode, DivideIcon, type DragGestureController, type DragGestureCtx, type DragGestureEndCtx, type DragGesturePhase, type DragGesturePoint, type DragHandleOptions, type DragPanParams, type DragPayload, type DragRadialController, type DragRadialCtx, type DragRadialEndCtx, type DragRadialPoint, type DragRadialState, type DragRectBounds, type DragRectController, type DragRectCtx, type DragRectEndCtx, type DragRectPoint, DrawCommand, type DropZoneOptions, EasingSpec, Eligibility, type EligibilityState, EllipseIcon, ExcludeIcon, EyedropperIcon, FALLBACK_FIT_VIEW, type FillPoseBox, type FitTextPoseOptions, type FlagKey, type FreeformOptions, GHOST_STROKE, type GateLayerOptions, GeometryProjection, type GesturePreviewSource, type GestureSource, type GridLayerOpts, type GridSlotConfig, Guide, type GuideSnapOptions, type GuidesLayerOpts, HANDLE_BASE_PX, HandIcon, InertiaConfig as HandToolInertiaConfig, type HandleDragEnd, type HandleDragPoint, type HeadlessCanvasLike, type HostAnchorAlign, type HostAnchorInput, type HostAnchorOffset, type HostAnchorStyle, HotkeyTrigger, IDENTITY_JOINT, type IconProps, ImageIcon, type ImageNodeData, type ImageStatus, type IndicatorStyle, InertiaConfig, InsertAdapter, InsertBehavior, InsertExtras, type InsertNodeFactory, type InsertOp, type InsertOverlayStyle, IntersectIcon, type Joint, type JointTransform, KIT_STANDARD_ACTION_IDS, type LabelOptions, LassoHitMode, LassoIcon, LassoSelectAdapter, LassoSelectBehavior, LayerEnumerableAdapter, LayerGroup, LayerHit, type LayerSlotValue, type LayersMap, LayoutSnap, LayoutStrategy, type LifecycleAnimation, LineIcon, type LinePoint, MIXED, MOVE_ANCHORS, type MarkerCtx, type MarkerEntry, type MarkerPaint, type MarkerSite, type MarkerSiteRequest, Mat3$1 as Mat3, MinimapCanvas, type MinimapCanvasProps, type MinimapFit, type Mixed, ModifierState, type MomentumOptions, MoveAdapter, MoveBehavior, type NestedHitOpts, type NestedHitTester, type NodeClientRect, NodeId, type NodeInk, type NodeInkCtx, type NodeOverlayFrame, type NodePaintCtx, type NodeProperties, type NodePropertiesEntry, type NodeRouting, type NodeRoutingEntry, type NodeShapeEntry, type NodeSilhouetteCtx, OngoingOverlay, type OpenFilePickerOptions, OrderedAdapter, OriginProjection, type OverlayPoint, OverlayPosition, PAINTED_CURSOR_LAYER_ID, PATH_ANCHOR_CHROME_ID, type PaintBindContext, type PaintKind, type PaintKindEditorProps, type PaintKindEntry, type PaintProgram, type PaintedCursor, type PaintedCursorFrame, type PaintedCursorState, PanBounds, type ParallaxOpts, Path, type PathAnchor, type PathAnchorAffordanceOptions, PathBuilder, PathDrawCommand, type PathEditingOverlayStyle, PathFillRule, type PathInWorldPose, type PathStation, type PenAnchor, PenIcon, type PenPreviewStyle, type PenScratch, type PenSubpath, PencilIcon, type PencilPoint, PickHud, type PickHudProps, type PickTopMostHitAdapter, type PinchZoomOptions, type PixelRenderPlan, type PointAlongPathOptions, type PointInPathOptions, type PointInTextPoseOpts, PointSnapBehavior, PointerProviderIfRoot, type PointerSample, type PointerSession, type PointerSessionCallbacks, type PointerSessionCancelReason, type PointerSessionOptions, type PointerStylusState, PolygonIcon, PolygonPath, type PolygonPoint, type Pose, PoseOverrides, PoseProjection, type PoseRotation, type PoseRun, type PoseRunCtx, type PoseRunStep, type PoseSource, type PosedNode, type PressureToWidthOptions, type Pt, RECT_ALIGN_PROJECTION, ROTATION_HANDLE_BASE_PX, type RangeStyle, type RasterImage, RectIcon, RectPath, RectPose, type RegisterNodeShapeOptions, RegisteredOp, RenderLayer, type RenderSceneToCanvasArgs, type RenderSceneToPixelsArgs, type ReorderDirection, ResizeAdapter, ResizeAnchor, ResizePose, type ResolvableView, RotateAdapter, RotateBehavior, type RotateGeometry, RotatedPose, type RotationAffordanceOptions, type RotationHandle, type RotationScratch, Rule, RuleCtx, type RunStylePatch, SampledTrack, type ScalarOrXY, Scene, SceneAdapter, type SceneAdapterSelection, SceneCanvas, type SceneCanvasAdapter, type SceneCanvasApi, type SceneCanvasHit, type SceneCanvasProps, Node$1 as SceneNode, type SceneNodeClientRectOpts, SceneRegistry, type SceneSlotConfig, type SceneToAdapterOptions, SceneViewCanvas, type SceneViewCanvasProps, type SceneViewDrawOne, ScopedBinding, type ScratchKey, type ScratchStore, type SelectAdapter, type SelectFromLassoOptions, SelectIcon, SelectionApi, SelectionContextProvider, SelectionContextProviderIfRoot, type SelectionContextValue, type SelectionHandleStyle, type SelectionHandlesLayerOpts, type SelectionOutlineLayerOpts, type SelectionOverlayLayerOpts, type SelectionOverlaySlotConfig, SerializedScene, type SetFlagResult, type SetPathFields, ShaderProgramHandle, type ShapeCoversPointOptions, type SharedAnchor, type Simulation, type SimulationCore, type SimulationForce, type SimulationNode, type SimulationOptions, type Skeleton, SliceDep, type SnapPattern, type SnapPointOptions, SnapStrategy, type SplitByLineOptions, type SpringPoseOptions, SpringPresetName, type SpringVertexColorsOptions, type StaggerVertexColorsOptions, type StandardSlotConfig, type StandardSlotName, StarIcon, type StarPoint, type StartEditOptions, type StyleKey, type StylusData, SubtractIcon, SvgIngestOptions, TOOL_PREF_KINDS, type TextEditScreenPose, type TextEditSelection, TextIcon, type ThresholdDragHandle, type ThresholdDragOptions, type TileGridOptions, type TilePatternOpts, Tool, type ToolBundle, ToolDef, ToolKeybinding, type ToolPref, type ToolPrefBoolean, type ToolPrefBooleanControl, type ToolPrefColor, type ToolPrefCustom, type ToolPrefEnum, type ToolPrefEnumControl, type ToolPrefEnumEncoding, type ToolPrefGroup, type ToolPrefKind, type ToolPrefLeaf, type ToolPrefNumber, type ToolPrefNumberControl, type ToolPrefNumberUnit, type ToolPrefObject, type ToolPrefPaint, type ToolPrefString, type ToolPrefStringControl, type ToolsApi, type TweenPoseOptions, type TweenVertexColorsOptions, UNION_OF_CHILDREN, UnionIcon, UnitSystem, UnitValue, UnknownIcon, type UseAlignOptions, type UseAlignReturn, UseAnimatorOptions, type UseArrayAdapterOptions, type UseBooleansOptions, type UseBooleansReturn, type UseCanvasFocusOptions, type UseDistributeOptions, type UseDistributeReturn, type UseDragGestureOptions, type UseDragRadialOptions, type UseDragRectOptions, type UseEyedropperToolOptions, type UseGestureDispatcherOptions, type UseGridCellHoverOptions, type UseGridCellHoverReturn, type UseGuidesReturn, type UseHandToolOptions, type UseHandleDragOptions, type UseHandleDragReturn, type UseHostAnchorOptions, type UseHoverTrackingArgs, type UseImageToolOptions, type UseKeybindingsOptions, type UseLassoSelectOptions, type UseLassoToolOptions, UseMoveOptions, type UseNodeOverlayFrameOptions, type UsePenToolOptions, type UsePointerStylusOptions, type UsePolygonToolOptions, type UsePoseRunOptions, UseResizeOptions, type UseResizePolicyOptions, type UseRotateOptions, type UseRotateToolOptions, UseSceneOptions, type UseSceneTextEditOptions, type UseSceneTextEditReturn, type UseSceneTrivialOptions, type UseSelectToolOptions, UseSelectionOptions, type UseSimulationOptions, type UseStandardActionsOptions, type UseStarToolOptions, type UseTextEditOptions, type UseTextEditReturn, type UseToolsOptions, VERSION, type Vec2, type VelocityTracker, VertexColorChannel, View, ViewAnimationOptions, type ViewRect, type ViewResolver, type ViewTarget, ViewTransform, ViewportDims, type ViewportLayer, ViewportToolDef, type ViewportZoomAnimateOptions, type ViewportZoomOptions, VisibilityRules, type VisibleRaf, type VisibleRafOptions, type VisibleRafTarget, WHEEL_ZOOM_STEP, WeaselProvider, type WheelInput, type WheelPanOptions, type WheelPanOpts, ZoomBound, type ZoomClampOpts, ZoomFactor, _resetMarkersForTests, _resetPaintKindsForTests, aabbCenter, actionIs, actionShortcuts, alignDeltaFor, alignInsertBehavior, alignMoveBehavior, alignResizeBehavior, always, and, animateLifecycle, animateOnSetPose, annulusSemiAxes, applyOpsTo, applyStyleToRange, areaSelectAction, arrayAdapter, asPaint, axisAlignedBounds, bezierCubic, bezierQuadratic, blendPoses, boundsOfPath, buildChromeCtx, buildSceneViewCommands, canBringForward, canHover, canSendBackward, capabilityAll, capabilityIn, capabilityIs, capabilityNot, caretIndexAt, cellAt, charOffsetToDomPosition, clampView, clearSelectionAction, clientToCanvas, cloneAction, coarsePointer, composeAffordanceLayer, composePath, composeSelectionPose, computeFitView, computeFitViewport, computeIndicatorCommand, computeWheelAction, cond, constrainTo45, containedThenNearest, countPathAnchors, createCellHighlightLayer, createChildrenLayer, createCornerResizeAffordance, createDebugOverlayLayer, createDebugSink, createDeleteOp, createGridLayer, createGuidesLayer, createHistory, createInsertOp, createMoveToIndexOp, createNodeProperties, createNodeRouting, createPaintedCursorLayer, createPaintedCursorState, createParallaxLayer, createPathAnchorAffordances, createPathEditingOverlayLayer, createPathLayer, createPenPreviewLayer, createPoseOverrides, createReorderOp, createReparentOp, createRotationAffordance, createScene, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, createSetDataOp, createSetLayerOp, createSetPathOp, createSetSelectionOp, createSetTextOp, createSimulation, createTextLayer, createTilePattern, createTransformOp, createVelocityTracker, createViewResolver, createViewportLayer, cycleVertexColors, decomposePath, defaultCommitAdapter, defaultDrawOne, defaultLabelTextRenderer, defaultNodeProperties, defaultNodeRouting, defaultVisibilityRules, defineTool, defineViewportTool, deleteScratch, deriveAlignmentGuides, deriveParallaxView, derivedDepOf, derivedPose, dispatchApplyBatch, dlog, documentPose, domPositionToCharOffset, domToRuns, dwarn, editAnchorsAction, effectivePose, ellipsePath, enumerateAnchors, fillInPoseFrame, fillToBoundsFrame, findNodeShape, findShapeInk, findShapeSilhouette, fitTextPose, fitToBounds, fitZoom, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, focused, forEachCoalesced, freeform, gateLayer, gesturing, getAlpha01, getImageBitmap, getMarker, getNodeShapes, getPaintKind, getScratch, getStylusData, gradientForBounds, gradientGeometry, guideSnapStrategy, hexToRgba, hitAffordanceRegions, hitAnchor, hitRotationHandle, hostAnchorCss, hostAnchorRect, hovering, hoveringSelected, imageStatus, inferredNodeProperties, inferredNodeRouting, insertAction, interpolateView, isBuiltinToolPref, isDebugEnabled, isEditableTarget, isGradientFill, isPatternSpec, keySpecShortcut, lassoSelectAction, lerpColorArray, lerpOklab, lerpOklch, linePath, listMarkers, listPaintKinds, liveScope, makePinchZoomAction, makeViewportWheelPanAction, makeViewportZoomAction, markerDrawCommands, markerInset, markerKeyOf, markerSites, matchAlignment, matchesKeyBinding, meanScale, mergeAlphaFromPrev, mergeContributions, modeIn, modeIs, modeNot, modifierHeld, momentum, moveAction, multiActive, nearest, nearestWithin, nestedHitTester, never, nodeHasFlag, none, normalizeHex, not, nurbs, oklabToOklch, oklabToSrgbU8, oklchToOklab, openFilePicker, openPointerSession, or, paintAlpha, paintKindOf, paintWithAlpha, paintWithColor, parseColor, parseColorToRgba255, parseDebugFlags, pathContainsPoint, pathContainsPolygon, pathContainsRect, pathDistanceToPoint, pathDivide, pathExclude, pathFromD, pathInPoseFrame, pathInWorld, pathIntersect, pathIntersectsPolygon, pathIntersectsRect, pathOriginProjection, pathPoseDescriptor, pathSubtract, pathToAnchors, pathUnion, pickTopMostHit, pinchZoomAction, planPixelRender, pointAlongPath, pointInPath, pointInRotatedRect, pointInTextPose, polygonFromPoints, polylineFromPoints, poseRotationOf, pressureToWidth, pxExtent, rainbowVertexColors, rebuildOp, rectCorners, rectPath, registerMarker, registerNodeShape, registerOpFactory, registerPaintKind, registeredOpNames, regularPolygonPath, renderLabel, renderSceneToCanvas, renderSceneToPixels, resizeAction, resolveColor, resolveDeviceProfile, resolveFillPattern, resolveMarkerSize, resolvePatternSpec, resolveSkeleton, resolveVisibility, rgbaToHex, rotateAction, rotateAroundAABBCenter, rotatePathAround, rotatePoint, rotatedRectCorners, rotationDegreesUnit, rotationHandle, roundToCell, runsToDom, sampleGradientStops, sampleTrack, scaleDelta, scalePathToBounds, sceneFromJSON, sceneNodeClientRect, sceneSelectionStore, sceneToAdapter, scopeBindings, scratchKey, selectFromLasso, selectionAtLeast, selectionEmpty, selectionIs, setFlagOverRange, setScratch, shapeCoversPoint, snap, snapPoint, solid, solidVertexColors, spiro, splitPathByLine, splitSubpaths, springPose, springVertexColors, srgbU8ToOklab, staggerVertexColors, starPath, startThresholdDrag, strokeInsets, strokeOf, strokeWith, styleAtRange, subscribeImageReady, textCommand, textCommandFromRuns, tileGrid, toHex8, transformPath, translatePath, translatePolygonInPlace, translatePoseViaDescriptor, trimPolyline, tweenPose, tweenVertexColors, unionAABB, unionBounds, unionBoundsPath, unionOfChildren, useAlign, useAnimator, useArrayAdapter, useAutoCenter, useBooleans, useBooleansAdapter, useCanvasFocus, useCanvasSize, useDeviceProfile, useDistribute, useDragGesture, useDragHandle, useDragRadial, useDragRect, useDropZone, useEllipseTool, useEyedropperTool, useGestureDispatcher, useGridCellHover, useGuides, useHandTool, useHandleDrag, useHostAnchor, useHoverTracking, useImageTool, useKeybindings, useLassoTool, useLineTool, useNodeOverlayFrame, usePenTool, usePencilTool, usePinchGesture, usePointerStylus, usePolygonTool, usePoseRun, usePublishSelection, useRectTool, useResizePolicy, useRotateTool, useScene, useSceneAdapter, useSceneTextEdit, useSelectTool, useSelectionContext, useSimulation, useSliceDep, useStandardActions, useStarTool, useTextEdit, useTextTool, useTools, useVelocityTracker, useVisibleRaf, viewportDragPanAction, viewportWheelPanAction, viewportZoomAction, viewportsAt, visualBoundsViaDescriptor, wheelPan, wheelZoom, wheelZoomFactor, when, withAlpha01, withCoord, withGradientKind, withinPxBox, withinPxRadius, worldEditToStorage, zoomAt, zoomAtLeast };
|
|
11702
|
+
export { ANCHOR_HIT_BASE_PX, type ActionShortcut, ActionsProviderIfRoot, type Affordance, type AffordanceBinding, type AffordanceRegion, type AffordanceRegionHit, type AlignAdapter, type AlignAnchor, type AlignEdge, type AlignMatchResult, type AlignMoveArgs, type AlignmentBehaviorBase, type AnchorHit, type AnchorScratch, type AnchorState, type AnimateOnSetPoseOptions, AnimationHandle, Animator, type AnyTool, AreaSelectAdapter, type ArrayAdapter, type ArrayAdapterConfig, ArrowIcon, BUILTIN_MARKERS, BUNDLE_TOOLS, BooleansAdapter, BoundsConstraint, type BuildChromeCtxArgs, type BuiltinShapeToolId, type BuiltinToolId, type BuiltinToolOptions, CURVE_REPS, type CanvasExtensionApi, type CanvasFocusReturn, type CanvasHelpers, type CanvasProps, type CanvasSelectionMode, type CanvasSize, type CanvasSizeSnapshot, type CanvasSurfaceHelpers, CanvasView, type CanvasViewHandle, type CanvasViewHelpers, type CanvasViewProps, type CellHighlightLayerOpts, type ChromeCtx, type ChromeId, type ChromeState, type ClampBounds, ClipboardSnapshot, type CoalescedCtx, type ColorInterpolate, ColorOverrideRegistry, type ColorSpace, type CommonAffordanceScratch, type ComposeSelectionPoseOpts, type ComputeFitViewOptions, type Condition, ContentHandlerEntry, type Contribution, type ContributionChrome, type CornerResizeAffordanceOptions, type CornerResizeScratch, type CreateChildrenLayerOpts, type CreateParallaxLayerOpts, type CreatePathEditingOverlayLayerOptions, type CreatePathLayerOpts, type CreatePenPreviewLayerOptions, type CreateTextLayerOpts, type CreateViewResolverOpts, type CreateViewportLayerOpts, CropIcon, CursorCoordsHud, type CursorCoordsHudProps, type CurveRepKind, type CurveRepresentation, type CustomLayerEntry, type CustomPaintContext, type CycleHandle, type CycleVertexColorsOptions, DEFAULT_ALPHA_DECAY, DEFAULT_ALPHA_MIN, DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME, DEFAULT_FILL_COLOR, DEFAULT_GUIDE_TOLERANCE_PX, DEFAULT_HANDLE_SIZE, DEFAULT_MAX_ZOOM, DEFAULT_MIN_ZOOM, DEFAULT_PALETTE, DEFAULT_ROTATION_HANDLE_DISTANCE, DEFAULT_SHAPE_FILL, DEFAULT_STROKE_COLOR, DEFAULT_VELOCITY_DECAY, type DebugConfig, type DebugFeature, type DebugSnapshot, type DebugStroke, type DebugStrokes, type DebugTheme, type DefaultTextData, DepRegistryProviderIfRoot, type DeriveAlignmentGuidesOptions, DerivedDep, DeviceProfileProvider, type DeviceProfileProviderProps, type Dims, type Discriminator, type DistributeAdapter, type DistributeAxis, type DistributeMode, DivideIcon, type DragGestureController, type DragGestureCtx, type DragGestureEndCtx, type DragGesturePhase, type DragGesturePoint, type DragHandleOptions, type DragPanParams, type DragPayload, type DragRadialController, type DragRadialCtx, type DragRadialEndCtx, type DragRadialPoint, type DragRadialState, type DragRectBounds, type DragRectController, type DragRectCtx, type DragRectEndCtx, type DragRectPoint, DrawCommand, type DropZoneOptions, EasingSpec, Effect, EllipseIcon, ExcludeIcon, EyedropperIcon, FALLBACK_FIT_VIEW, type FeedDelta, type FeedNode, type FillPoseBox, type FitTextPoseOptions, type FlagKey, type FreeformOptions, GHOST_STROKE, type GateLayerOptions, GeometryProjection, type GesturePreviewSource, type GestureSource, type GridLayerOpts, type GridSlotConfig, Guide, type GuideSnapOptions, type GuidesLayerOpts, HANDLE_BASE_PX, HandIcon, InertiaConfig as HandToolInertiaConfig, type HandleDragEnd, type HandleDragPoint, type HeadlessCanvasLike, type HostAnchorAlign, type HostAnchorInput, type HostAnchorOffset, type HostAnchorStyle, IDENTITY_JOINT, type IconProps, ImageIcon, type ImageNodeData, type ImageStatus, type IndicatorStyle, InertiaConfig, InsertAdapter, InsertBehavior, InsertExtras, type InsertNodeFactory, type InsertOp, type InsertOverlayStyle, type InsertPreviewExtent, type InsertPreviewGeometry, type InsertPreviewLike, type InsertPreviewOverlay, IntersectIcon, type Joint, type JointTransform, KIT_SHAPE_KINDS, KIT_STANDARD_ACTION_IDS, type LabelOptions, LassoHitMode, LassoIcon, LassoSelectAdapter, LassoSelectBehavior, type LayerCommandCache, type LayerDrawFailure, LayerEnumerableAdapter, type LayerGroup, type LayerHit, type LayerSlotValue, type LayersMap, LayoutSnap, LayoutStrategy, type LifecycleAnimation, LineIcon, type LinePoint, MIXED, MOVE_ANCHORS, type MarkerCtx, type MarkerEntry, type MarkerPaint, type MarkerSite, type MarkerSiteRequest, Mat3$1 as Mat3, MinimapCanvas, type MinimapCanvasProps, type MinimapFit, type Mixed, type MomentumOptions, MoveAdapter, MoveBehavior, type NestedHitOpts, type NestedHitTester, type NodeClientRect, type NodeInk, type NodeInkCtx, type NodeOverlayFrame, type NodePaintCtx, type NodeProperties, type NodePropertiesEntry, type NodeRouting, type NodeRoutingEntry, type NodeShapeEntry, type NodeSilhouetteCtx, type OpenFilePickerOptions, OrderedAdapter, OriginProjection, type OverlayPoint, type OverlayVisibilityId, PAINTED_CURSOR_LAYER_ID, PATH_ANCHOR_CHROME_ID, type PaintBindContext, type PaintKind, type PaintKindEditorProps, type PaintKindEntry, type PaintProgram, PanBounds, type ParallaxOpts, Path, type PathAnchor, type PathAnchorAffordanceOptions, PathBuilder, PathDrawCommand, type PathEditingOverlayStyle, PathFillRule, type PathInWorldPose, type PathStation, type PenAnchor, PenIcon, type PenPreviewStyle, type PenScratch, type PenSubpath, PencilIcon, type PencilPoint, PickHud, type PickHudProps, type PickTopMostHitAdapter, type PinchZoomOptions, type PixelRenderPlan, type PointAlongPathOptions, type PointInPathOptions, type PointInTextPoseOpts, PointSnapBehavior, PointerProviderIfRoot, type PointerSample, type PointerStylusState, PolygonIcon, PolygonPath, type PolygonPoint, type Pose, PoseComposition, PoseDescriptor, type PoseFeed, PoseOverrides, type PoseRotation, type PoseRun, type PoseRunCtx, type PoseRunStep, type PoseSource, type PosedNode, type PressureToWidthOptions, type PreviewNode, type Pt, ROTATION_HANDLE_BASE_PX, type RangeStyle, type RasterImage, type RecordedBounds, type RecordedHandle, type RecordedHitbox, type RecordedLayer, type RecordedOrigin, type RecordedSnap, RectIcon, RectPath, RectPose, type RegisterNodeShapeOptions, RegisteredOp, type RenderLayer, type RenderSceneToCanvasArgs, type RenderSceneToPixelsArgs, type ReorderDirection, ResizeAdapter, type ResolvableView, type ResolvedOverlay, RotateAdapter, RotateBehavior, RotatedPose, type RotationAffordanceOptions, type RotationHandle, type RotationScratch, type RunStylePatch, SampledTrack, type ScalarOrXY, Scene, SceneAdapter, type SceneAdapterSelection, SceneCanvas, type SceneCanvasAdapter, type SceneCanvasApi, type SceneCanvasHit, type SceneCanvasProps, Node$1 as SceneNode, type SceneNodeClientRectOpts, SceneRegistry, type SceneSlotConfig, type SceneToAdapterOptions, SceneViewCanvas, type SceneViewCanvasProps, type SceneViewDrawOne, type SceneViewLayers, type SelectAdapter, type SelectFromLassoOptions, SelectIcon, SelectionContextProvider, SelectionContextProviderIfRoot, type SelectionContextValue, type SelectionHandleStyle, type SelectionHandlesLayerOpts, type SelectionOutlineLayerOpts, type SelectionOverlayLayerOpts, type SelectionOverlaySlotConfig, SerializedScene, type SetFlagResult, type SetPathFields, ShaderProgramHandle, type ShapeCoversPointOptions, type SharedAnchor, type Simulation, type SimulationCore, type SimulationForce, type SimulationNode, type SimulationOptions, type Skeleton, SliceDep, type SnapPattern, type SnapPointOptions, SnapStrategy, type SplitByLineOptions, type SpringPoseOptions, SpringPresetName, type SpringVertexColorsOptions, type StaggerVertexColorsOptions, type StandardSlotConfig, type StandardSlotName, StarIcon, type StarPoint, type StartEditOptions, type StyleKey, type StylusData, SubtractIcon, SvgIngestOptions, TOOL_PREF_KINDS, TextDrawCommand, type TextEditClipRect, type TextEditScreenPose, type TextEditSelection, TextIcon, type ThresholdDragHandle, type ThresholdDragOptions, type TileGridOptions, type TilePatternOpts, type Tool, type ToolBundle, type ToolDef, type ToolPref, type ToolPrefBoolean, type ToolPrefBooleanControl, type ToolPrefColor, type ToolPrefCustom, type ToolPrefEnum, type ToolPrefEnumControl, type ToolPrefEnumEncoding, type ToolPrefGroup, type ToolPrefKind, type ToolPrefLeaf, type ToolPrefNumber, type ToolPrefNumberControl, type ToolPrefNumberFormat, type ToolPrefNumberUnit, type ToolPrefObject, type ToolPrefPaint, type ToolPrefString, type ToolPrefStringControl, type ToolsApi, type TweenPoseOptions, type TweenVertexColorsOptions, UNION_OF_CHILDREN, UnionIcon, Unit, UnitSystem, UnitValue, UnknownIcon, type UseAlignOptions, type UseAlignReturn, UseAnimatorOptions, type UseArrayAdapterOptions, type UseBooleansOptions, type UseBooleansReturn, type UseCanvasFocusOptions, type UseDistributeOptions, type UseDistributeReturn, type UseDragGestureOptions, type UseDragRadialOptions, type UseDragRectOptions, type UseEyedropperToolOptions, type UseGridCellHoverOptions, type UseGridCellHoverReturn, type UseGuidesReturn, type UseHandToolOptions, type UseHandleDragOptions, type UseHandleDragReturn, type UseHostAnchorOptions, type UseHoverTrackingArgs, type UseImageToolOptions, type UseKeybindingsOptions, type UseLassoSelectOptions, type UseLassoToolOptions, UseMoveOptions, type UseNodeOverlayFrameOptions, type UsePenToolOptions, type UsePointerStylusOptions, type UsePolygonToolOptions, type UsePoseRunOptions, UseResizeOptions, type UseResizePolicyOptions, type UseRotateOptions, type UseRotateToolOptions, UseSceneOptions, type UseSceneTextEditOptions, type UseSceneTextEditReturn, type UseSceneTrivialOptions, type UseSelectToolOptions, type UseSelectionOptions, type UseSimulationOptions, type UseStandardActionsOptions, type UseStarToolOptions, type UseTextEditOptions, type UseTextEditReturn, type UseToolsOptions, VERSION, type Vec2, type VelocityTracker, VertexColorChannel, ViewAnimationOptions, type ViewRect, type ViewResolver, type ViewTarget, type ViewTransform, ViewportDims, type ViewportLayer, type ViewportToolDef, type ViewportZoomAnimateOptions, type ViewportZoomOptions, type VisibilityRules, type VisibleRaf, type VisibleRafOptions, type VisibleRafTarget, WHEEL_ZOOM_STEP, WeaselProvider, type WheelInput, type WheelPanOptions, type WheelPanOpts, ZOOM_FLOOR, type ZoomBound, type ZoomClampOpts, type ZoomFactor, _resetMarkersForTests, _resetPaintKindsForTests, aabbCenter, actionIs, actionShortcuts, alignDeltaFor, alignInsertBehavior, alignMoveBehavior, alignResizeBehavior, always, and, animateLifecycle, animateOnSetPose, annulusSemiAxes, applyOpsTo, applyStyleToRange, areaSelectAction, arrayAdapter, asPaint, axisAlignedBounds, bezierCubic, bezierQuadratic, blendPoses, boundsOfPath, buildChromeCtx, buildSceneViewCommands, canBringForward, canHover, canSendBackward, capabilityAll, capabilityIn, capabilityIs, capabilityNot, caretIndexAt, cellAt, charOffsetToDomPosition, clampView, clearSelectionAction, clipboardCopyAction, clipboardCutAction, cloneAction, coarsePointer, composeAffordanceLayer, composePath, composeSelectionPose, computeFitView, computeFitViewport, computeIndicatorCommand, computeWheelAction, cond, constrainTo45, containedThenNearest, countPathAnchors, createCellHighlightLayer, createChildrenLayer, createCornerResizeAffordance, createDebugOverlayLayer, createDebugSink, createDeleteOp, createGridLayer, createGuidesLayer, createHistory, createInsertOp, createMoveToIndexOp, createNodeProperties, createNodeRouting, createPaintedCursorLayer, createParallaxLayer, createPathAnchorAffordances, createPathEditingOverlayLayer, createPathLayer, createPenPreviewLayer, createPoseFeed, createPoseOverrides, createReorderOp, createReparentOp, createRotationAffordance, createScene, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, createSetDataOp, createSetLayerOp, createSetPathOp, createSetSelectionOp, createSetTextOp, createSimulation, createTextLayer, createTilePattern, createTransformOp, createVelocityTracker, createViewResolver, createViewportLayer, cycleVertexColors, decomposePath, defaultCommitAdapter, defaultDrawOne, defaultLabelTextRenderer, defaultNodeProperties, defaultNodeRouting, defaultVisibilityRules, defineTool, defineViewportTool, deriveAlignmentGuides, deriveParallaxView, derivedDepOf, derivedPose, dispatchApplyBatch, dlog, documentPose, domPositionToCharOffset, domToRuns, drawLayers, drawOneLayer, dwarn, editAnchorsAction, effectivePose, ellipsePath, enterTextEditAction, enumerateAnchors, fillInPoseFrame, fillToBoundsFrame, findNodeShape, findShapeInk, findShapeSilhouette, fitTextPose, fitToBounds, fitZoom, flattenPreviews, focused, forEachCoalesced, freeform, gateLayer, gesturing, getAlpha01, getImageBitmap, getMarker, getNodeShapes, getPaintKind, getStylusData, gradientForBounds, gradientGeometry, guideSnapStrategy, hexToRgba, hitAffordanceRegions, hitAnchor, hitRotationHandle, hostAnchorCss, hostAnchorRect, hovering, hoveringSelected, imageStatus, inferredNodeProperties, inferredNodeRouting, insertAction, insertPreviewExtent, interpolateView, isBuiltinToolPref, isDebugEnabled, isGradientFill, isLayerPainted, isLayerVisible, isPatternSpec, keySpecShortcut, lassoSelectAction, lerpColorArray, lerpOklab, lerpOklch, linePath, listMarkers, listPaintKinds, makePinchZoomAction, makeViewportWheelPanAction, makeViewportZoomAction, markerDrawCommands, markerInset, markerKeyOf, markerSites, matchAlignment, meanScale, mergeAlphaFromPrev, modeIn, modeIs, modeNot, modifierHeld, momentum, moveAction, multiActive, nearest, nearestWithin, nestedHitTester, never, nodeHasFlag, none, normalizeHex, normalizeView, normalizeZoom, not, nurbs, oklabToOklch, oklabToSrgbU8, oklchToOklab, openFilePicker, or, paintAlpha, paintKindOf, paintWithAlpha, paintWithColor, parseColor, parseColorToRgba255, parseDebugFlags, pathContainsPoint, pathContainsPolygon, pathContainsRect, pathDistanceToPoint, pathDivide, pathExclude, pathFromD, pathInPoseFrame, pathInWorld, pathIntersect, pathIntersectsPolygon, pathIntersectsRect, pathOriginProjection, pathPoseDescriptor, pathSubtract, pathToAnchors, pathUnion, pickTopMostHit, pinchZoomAction, planPixelRender, pointAlongPath, pointInPath, pointInRotatedRect, pointInTextPose, polygonFromPoints, polylineFromPoints, poseRotationOf, prefUnit, pressureToWidth, pxExtent, rainbowVertexColors, rebuildOp, rectCorners, rectPath, registerMarker, registerNodeShape, registerOpFactory, registerPaintKind, registeredOpNames, regularPolygonPath, renderLabel, renderSceneToCanvas, renderSceneToPixels, resizeAction, resolveColor, resolveFillPattern, resolveMarkerSize, resolveOverlays, resolvePatternSpec, resolvePreviews, resolveSkeleton, resolveVisibility, rgbaToHex, rotateAction, rotateAroundAABBCenter, rotatePathAround, rotatePoint, rotatedRectCorners, rotationDegreesUnit, rotationHandle, roundToCell, runsToDom, sampleGradientStops, sampleTrack, scaleDelta, scalePathToBounds, sceneFromJSON, sceneNodeClientRect, sceneSelectionStore, sceneToAdapter, screenToWorld, selectFromLasso, selectionAtLeast, selectionEmpty, selectionIs, setFlagOverRange, shapeCoversPoint, sliceAction, snap, snapPoint, solid, solidVertexColors, spiro, splitPathByLine, splitSubpaths, springPose, springVertexColors, srgbU8ToOklab, staggerVertexColors, starPath, startThresholdDrag, strokeInsets, strokeOf, strokeWith, styleAtRange, subscribeImageReady, textCommand, textCommandFromPose, textCommandFromRuns, tileGrid, toHex8, transformPath, translatePath, translatePolygonInPlace, trimPolyline, tweenPose, tweenVertexColors, unionAABB, unionBounds, unionBoundsPath, unionOfChildren, unionOfChildrenVia, useAlign, useAnimator, useArrayAdapter, useAutoCenter, useBooleans, useBooleansAdapter, useCanvasFocus, useCanvasSize, useDeviceProfile, useDistribute, useDragGesture, useDragHandle, useDragRadial, useDragRect, useDropZone, useEllipseTool, useEyedropperTool, useGridCellHover, useGuides, useHandTool, useHandleDrag, useHostAnchor, useHoverTracking, useImageTool, useKeybindings, useLassoTool, useLineTool, useNodeOverlayFrame, usePenTool, usePencilTool, usePinchGesture, usePointerStylus, usePolygonTool, usePoseCompositionDepSource, usePoseDescriptorDepSource, usePoseRun, usePublishSelection, useRectTool, useResizePolicy, useRotateTool, useScene, useSceneAdapter, useSceneTextEdit, useSelectTool, useSelection, useSelectionContext, useSimulation, useSliceDep, useStandardActions, useStarTool, useTextEdit, useTextTool, useTools, useVelocityTracker, useVisibleRaf, viewToTransform, viewZoom, viewportDragPanAction, viewportWheelPanAction, viewportZoomAction, viewportsAt, wheelPan, wheelZoom, wheelZoomFactor, when, withAlpha01, withCoord, withGradientKind, withinPxBox, withinPxRadius, worldEditToStorage, worldToScreen, zoomAt, zoomAtLeast };
|