@weasel-js/core 1.4.3 → 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 +1299 -2197
- package/README.md +118 -75
- package/dist/{pointSnapToGrid-D1bRdq-j.d.ts → autoPoseDescriptor-CvjflWJK.d.ts} +35 -17
- package/dist/{chunk-ORZNKVXM.js → chunk-BDWAA634.js} +4 -22
- package/dist/chunk-BDWAA634.js.map +1 -0
- package/dist/{chunk-WYPSGIYS.js → chunk-MG7OXCAI.js} +4149 -5316
- package/dist/chunk-MG7OXCAI.js.map +1 -0
- package/dist/{chunk-BLJNRMKB.js → chunk-MQI4PIX3.js} +3 -3
- package/dist/chunk-MQI4PIX3.js.map +1 -0
- package/dist/{chunk-SBFC6J3C.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-Bw8cSde-.d.ts → grid-BrIa38gG.d.ts} +7 -23
- package/dist/index.d.ts +2134 -1210
- 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-DYfUlZxk.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 -11
- 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-BJqsTlXl.d.ts → types-DMyo7dnM.d.ts} +12 -41
- package/dist/{types-CoVTbo_y.d.ts → types-DtjCJA5r.d.ts} +10 -9
- package/package.json +13 -10
- package/dist/DrawCommand-CD-ug3d9.d.ts +0 -332
- package/dist/builtins-CtGORLCG.d.ts +0 -740
- package/dist/chunk-BLJNRMKB.js.map +0 -1
- package/dist/chunk-LEURURX3.js +0 -561
- package/dist/chunk-LEURURX3.js.map +0 -1
- package/dist/chunk-ORZNKVXM.js.map +0 -1
- package/dist/chunk-SBFC6J3C.js.map +0 -1
- package/dist/chunk-WYPSGIYS.js.map +0 -1
- package/dist/geometry-CHR36Ub_.d.ts +0 -114
- package/dist/path-JEV2c5If.d.ts +0 -48
- package/dist/registry-DnoTWGED.d.ts +0 -4003
- package/dist/types-BHK2dkMu.d.ts +0 -172
- package/dist/types-H7o6MaPo.d.ts +0 -512
- 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-DnoTWGED.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 {
|
|
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-CtGORLCG.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-CtGORLCG.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
|
|
|
@@ -484,23 +1014,9 @@ interface SimulationForce<TNode extends SimulationNode = SimulationNode> {
|
|
|
484
1014
|
(alpha: number): void;
|
|
485
1015
|
initialize?(nodes: TNode[], random?: () => number): void;
|
|
486
1016
|
}
|
|
487
|
-
/** Options for `useSimulation`:
|
|
488
|
-
*
|
|
489
|
-
interface UseSimulationOptions<TNode extends SimulationNode> {
|
|
490
|
-
/** Mutable array of nodes. Kit + forces mutate vx/vy/x/y in place. */
|
|
491
|
-
nodes: TNode[];
|
|
492
|
-
/** Forces applied per tick. Each may implement `initialize` for setup. */
|
|
493
|
-
forces?: SimulationForce<TNode>[];
|
|
494
|
-
/** Initial alpha. Default 1. */
|
|
495
|
-
alpha?: number;
|
|
496
|
-
/** Settle threshold. When alpha drops below and alphaTarget is 0, onEnd fires. Default 0.001. */
|
|
497
|
-
alphaMin?: number;
|
|
498
|
-
/** Per-tick decay rate toward alphaTarget. Default 1 - 0.001^(1/300) ≈ 0.0228. */
|
|
499
|
-
alphaDecay?: number;
|
|
500
|
-
/** Target alpha. Set above alphaMin to keep sim warm (e.g. during drag). Default 0. */
|
|
501
|
-
alphaTarget?: number;
|
|
502
|
-
/** Friction multiplier on velocity per tick: vx *= (1 - velocityDecay). Default 0.4. */
|
|
503
|
-
velocityDecay?: number;
|
|
1017
|
+
/** Options for `useSimulation`: everything {@link SimulationOptions} carries,
|
|
1018
|
+
* plus the loop's own callbacks and clock. */
|
|
1019
|
+
interface UseSimulationOptions<TNode extends SimulationNode> extends SimulationOptions<TNode> {
|
|
504
1020
|
/** Fired after each integration step. */
|
|
505
1021
|
onTick?: (nodes: TNode[]) => void;
|
|
506
1022
|
/** Fired once when the sim settles (alpha < alphaMin && alphaTarget === 0). */
|
|
@@ -510,7 +1026,7 @@ interface UseSimulationOptions<TNode extends SimulationNode> {
|
|
|
510
1026
|
cancelFrame?: (handle: number) => void;
|
|
511
1027
|
}
|
|
512
1028
|
/**
|
|
513
|
-
* A
|
|
1029
|
+
* A force simulation over a set of nodes, with no clock of its own.
|
|
514
1030
|
*
|
|
515
1031
|
* Each tick applies every force and then integrates velocities, scaled by
|
|
516
1032
|
* `alpha` — a temperature that decays toward `alphaTarget` so the layout
|
|
@@ -518,8 +1034,12 @@ interface UseSimulationOptions<TNode extends SimulationNode> {
|
|
|
518
1034
|
* which is what a drag does.
|
|
519
1035
|
*
|
|
520
1036
|
* Nodes are mutated in place; the simulation holds the array, not a copy.
|
|
1037
|
+
*
|
|
1038
|
+
* Nothing here advances time. {@link Simulation} adds the frame loop; a caller
|
|
1039
|
+
* that wants the whole relaxation at once — a layout pass, a pre-warm, a test
|
|
1040
|
+
* — drives {@link SimulationCore.tick} itself.
|
|
521
1041
|
*/
|
|
522
|
-
interface
|
|
1042
|
+
interface SimulationCore<TNode extends SimulationNode> {
|
|
523
1043
|
readonly nodes: TNode[];
|
|
524
1044
|
setNodes(nodes: TNode[]): this;
|
|
525
1045
|
setForces(forces: SimulationForce<TNode>[]): this;
|
|
@@ -533,10 +1053,6 @@ interface Simulation<TNode extends SimulationNode> {
|
|
|
533
1053
|
alphaMin(value: number): this;
|
|
534
1054
|
velocityDecay(): number;
|
|
535
1055
|
velocityDecay(value: number): this;
|
|
536
|
-
/** Resume the RAF loop. If alpha < alphaMin, reset alpha to 1. */
|
|
537
|
-
restart(): this;
|
|
538
|
-
/** Cancel the RAF loop. Does not change alpha. */
|
|
539
|
-
stop(): this;
|
|
540
1056
|
/**
|
|
541
1057
|
* Run the tick body synchronously `iterations` times. Does NOT fire
|
|
542
1058
|
* onTick or onEnd (matches d3-force). Used for offscreen pre-warm and tests.
|
|
@@ -544,6 +1060,34 @@ interface Simulation<TNode extends SimulationNode> {
|
|
|
544
1060
|
tick(iterations?: number): this;
|
|
545
1061
|
isSettled(): boolean;
|
|
546
1062
|
}
|
|
1063
|
+
/** A {@link SimulationCore} running on a frame loop. */
|
|
1064
|
+
interface Simulation<TNode extends SimulationNode> extends SimulationCore<TNode> {
|
|
1065
|
+
/** Resume the RAF loop. If alpha < alphaMin, reset alpha to 1. */
|
|
1066
|
+
restart(): this;
|
|
1067
|
+
/** Cancel the RAF loop. Does not change alpha. */
|
|
1068
|
+
stop(): this;
|
|
1069
|
+
}
|
|
1070
|
+
/** What {@link SimulationCore} needs: the nodes, the forces acting on them,
|
|
1071
|
+
* and the cooling schedule. {@link UseSimulationOptions} adds the loop's. */
|
|
1072
|
+
interface SimulationOptions<TNode extends SimulationNode> {
|
|
1073
|
+
/** Mutable array of nodes. Kit + forces mutate vx/vy/x/y in place. */
|
|
1074
|
+
nodes: TNode[];
|
|
1075
|
+
/** Forces applied per tick. Each may implement `initialize` for setup. */
|
|
1076
|
+
forces?: SimulationForce<TNode>[];
|
|
1077
|
+
/** Initial alpha. Default 1. */
|
|
1078
|
+
alpha?: number;
|
|
1079
|
+
/** Settle threshold. When alpha drops below and alphaTarget is 0, onEnd fires. Default 0.001. */
|
|
1080
|
+
alphaMin?: number;
|
|
1081
|
+
/** Per-tick decay rate toward alphaTarget. Default 1 - 0.001^(1/300) ≈ 0.0228. */
|
|
1082
|
+
alphaDecay?: number;
|
|
1083
|
+
/** Target alpha. Set above alphaMin to keep sim warm (e.g. during drag). Default 0. */
|
|
1084
|
+
alphaTarget?: number;
|
|
1085
|
+
/** Friction multiplier on velocity per tick: vx *= (1 - velocityDecay). Default 0.4. */
|
|
1086
|
+
velocityDecay?: number;
|
|
1087
|
+
/** Handed to each force's `initialize`. Default `Math.random`; pass a seeded
|
|
1088
|
+
* source to make a run reproducible. */
|
|
1089
|
+
random?: () => number;
|
|
1090
|
+
}
|
|
547
1091
|
/** Default alpha decay: such that alpha drops from 1 to alphaMin (0.001) in 300 ticks. */
|
|
548
1092
|
declare const DEFAULT_ALPHA_DECAY: number;
|
|
549
1093
|
/** Alpha below which a cooling simulation is considered settled. */
|
|
@@ -553,9 +1097,24 @@ declare const DEFAULT_ALPHA_MIN = 0.001;
|
|
|
553
1097
|
declare const DEFAULT_VELOCITY_DECAY = 0.4;
|
|
554
1098
|
|
|
555
1099
|
/**
|
|
556
|
-
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
1100
|
+
* The integrator, with no clock attached.
|
|
1101
|
+
*
|
|
1102
|
+
* Velocity-Verlet over a pluggable force list, contract-compatible with
|
|
1103
|
+
* d3-force so d3's own bundled forces drop in untranslated. Nothing here
|
|
1104
|
+
* advances time: `tick()` is the only thing that moves a node, and the caller
|
|
1105
|
+
* decides how often to call it. `useSimulation` calls it once a frame; a
|
|
1106
|
+
* layout pass calls it a few hundred times in one go and reads the result.
|
|
1107
|
+
*
|
|
1108
|
+
* Splitting it out is what lets a *pure* function run a relaxation — a React
|
|
1109
|
+
* hook cannot, and the alternative was a second integrator drifting away from
|
|
1110
|
+
* this one.
|
|
1111
|
+
*/
|
|
1112
|
+
|
|
1113
|
+
declare function createSimulation<TNode extends SimulationNode>(opts: SimulationOptions<TNode>): SimulationCore<TNode>;
|
|
1114
|
+
|
|
1115
|
+
/**
|
|
1116
|
+
* Continuous N-body simulation primitive: `createSimulation`'s integrator on a
|
|
1117
|
+
* frame loop.
|
|
559
1118
|
*
|
|
560
1119
|
* The kit is adapter-agnostic — `onTick(nodes)` fires after each integration
|
|
561
1120
|
* step and the consumer decides how (and whether) to write through to scene
|
|
@@ -564,6 +1123,47 @@ declare const DEFAULT_VELOCITY_DECAY = 0.4;
|
|
|
564
1123
|
*/
|
|
565
1124
|
declare function useSimulation<TNode extends SimulationNode>(opts: UseSimulationOptions<TNode>): Simulation<TNode>;
|
|
566
1125
|
|
|
1126
|
+
/** What a producer is told before it is asked for a frame. */
|
|
1127
|
+
interface PoseRunCtx<TPose> {
|
|
1128
|
+
/** Nodes another gesture is moving, and the pose each is drawn at. The run
|
|
1129
|
+
* will not write these, so a producer holds them fixed. */
|
|
1130
|
+
pinned: ReadonlyMap<NodeId, TPose>;
|
|
1131
|
+
/** Frames this run has produced, starting at 0. */
|
|
1132
|
+
frame: number;
|
|
1133
|
+
}
|
|
1134
|
+
/** One frame of a run. */
|
|
1135
|
+
interface PoseRunStep<TPose> {
|
|
1136
|
+
/** Where the nodes it drives are this frame — the whole picture, not a
|
|
1137
|
+
* delta. An id the frame omits stops being published, which is how a node
|
|
1138
|
+
* leaves the run's hands: a producer that drops a grabbed box and its rows
|
|
1139
|
+
* from one frame has released them by the next. */
|
|
1140
|
+
poses: Iterable<readonly [NodeId, TPose]>;
|
|
1141
|
+
/** Whether the run is finished. The frame is published either way, and a
|
|
1142
|
+
* finished run commits. */
|
|
1143
|
+
done: boolean;
|
|
1144
|
+
}
|
|
1145
|
+
interface UsePoseRunOptions<TPose> {
|
|
1146
|
+
scene: Scene<unknown, string, TPose>;
|
|
1147
|
+
step: (ctx: PoseRunCtx<TPose>) => PoseRunStep<TPose>;
|
|
1148
|
+
/** The undo entry's name. Default `'Layout'`. */
|
|
1149
|
+
label?: string;
|
|
1150
|
+
/** How many nodes the commit wrote. Fires after the ops land. */
|
|
1151
|
+
onCommit?: (moved: number) => void;
|
|
1152
|
+
/** Clock injection, for tests. Defaults to `requestAnimationFrame`. */
|
|
1153
|
+
requestFrame?: (cb: (t: number) => void) => number;
|
|
1154
|
+
cancelFrame?: (handle: number) => void;
|
|
1155
|
+
}
|
|
1156
|
+
interface PoseRun {
|
|
1157
|
+
/** Begin, or continue where a `stop` left off. Idempotent while running. */
|
|
1158
|
+
start(): void;
|
|
1159
|
+
/** Finish now: commit what is published, then drop the overrides. */
|
|
1160
|
+
stop(): void;
|
|
1161
|
+
/** Abandon: drop the overrides and write nothing, like a canceled drag. */
|
|
1162
|
+
cancel(): void;
|
|
1163
|
+
isRunning(): boolean;
|
|
1164
|
+
}
|
|
1165
|
+
declare function usePoseRun<TPose>(opts: UsePoseRunOptions<TPose>): PoseRun;
|
|
1166
|
+
|
|
567
1167
|
/**
|
|
568
1168
|
* `useNodeOverlayFrame` — the coordinate frame a DOM overlay pinned to one
|
|
569
1169
|
* scene node needs: the node's world box, the projection from that box's
|
|
@@ -600,7 +1200,8 @@ interface NodeOverlayFrame {
|
|
|
600
1200
|
};
|
|
601
1201
|
/** Node box frame → overlay pixels, rotation and view included. */
|
|
602
1202
|
toScreen: (p: OverlayPoint) => OverlayPoint;
|
|
603
|
-
/** 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. */
|
|
604
1205
|
toLocal: (p: OverlayPoint) => OverlayPoint;
|
|
605
1206
|
/** The container's size in CSS pixels — the overlay's own box. */
|
|
606
1207
|
width: number;
|
|
@@ -820,7 +1421,8 @@ interface Scale2 {
|
|
|
820
1421
|
x: number;
|
|
821
1422
|
y: number;
|
|
822
1423
|
}
|
|
823
|
-
/** 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`). */
|
|
824
1426
|
declare function pxExtent(px: number, scale: Scale2): {
|
|
825
1427
|
x: number;
|
|
826
1428
|
y: number;
|
|
@@ -843,59 +1445,6 @@ declare function withinPxBox(dx: number, dy: number, px: number, scale: Scale2):
|
|
|
843
1445
|
/** Is a world-space delta inside a screen-space circle of radius `px`? */
|
|
844
1446
|
declare function withinPxRadius(dx: number, dy: number, px: number, scale: Scale2): boolean;
|
|
845
1447
|
|
|
846
|
-
/**
|
|
847
|
-
* The DOM half of a drag: one pointer, held down, from press to release.
|
|
848
|
-
*
|
|
849
|
-
* Every pointerdown-to-pointerup lifecycle in the kit used to answer capture,
|
|
850
|
-
* pointer identity, teardown and lost-pointer recovery for itself, and each
|
|
851
|
-
* answered them differently. This is the one place those are decided; anything
|
|
852
|
-
* above it — thresholds, coordinate spaces, what the drag *means* — belongs to
|
|
853
|
-
* its caller.
|
|
854
|
-
*/
|
|
855
|
-
/** Why a session ended without the pointer being released. */
|
|
856
|
-
type PointerSessionCancelReason =
|
|
857
|
-
/** The browser cancelled the pointer (touch interrupted, palm rejection). */
|
|
858
|
-
'pointercancel'
|
|
859
|
-
/** The origin left the document mid-gesture, taking capture with it. */
|
|
860
|
-
| 'lostcapture'
|
|
861
|
-
/** `cancel()` — an unmount, a window blur, Escape, a consumer's own rule. */
|
|
862
|
-
| 'aborted'
|
|
863
|
-
/** A new press arrived on this pointer, so the tracked one had ended. */
|
|
864
|
-
| 'superseded';
|
|
865
|
-
interface PointerSessionCallbacks {
|
|
866
|
-
/** Every move belonging to this pointer, while it is still held. */
|
|
867
|
-
onMove?: (e: PointerEvent) => void;
|
|
868
|
-
/** The pointer was released. Fires once, before teardown completes. */
|
|
869
|
-
onEnd?: (e: PointerEvent) => void;
|
|
870
|
-
/** The session ended without a release. Fires once. */
|
|
871
|
-
onCancel?: (reason: PointerSessionCancelReason) => void;
|
|
872
|
-
}
|
|
873
|
-
interface PointerSessionOptions {
|
|
874
|
-
/** Ask the origin element to capture the pointer. Default `true`. Capture
|
|
875
|
-
* keeps hover and click off everything the drag passes over; the session
|
|
876
|
-
* does not depend on it to keep receiving events. */
|
|
877
|
-
capture?: boolean;
|
|
878
|
-
}
|
|
879
|
-
interface PointerSession {
|
|
880
|
-
readonly pointerId: number;
|
|
881
|
-
/** False once the session has ended, by any route. */
|
|
882
|
-
readonly active: boolean;
|
|
883
|
-
/** End the session now, reporting `'aborted'`. Idempotent. */
|
|
884
|
-
cancel: () => void;
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* Open a session for the pointer that `down` belongs to.
|
|
888
|
-
*
|
|
889
|
-
* Listens on the origin's document rather than on the element: a captured
|
|
890
|
-
* element that is removed mid-drag stops receiving events, and every listener
|
|
891
|
-
* hung on it goes with it. Three recovery rules close the gaps a plain
|
|
892
|
-
* pointerup/pointercancel pair leaves — losing capture cancels only once the
|
|
893
|
-
* origin has left the document, a move reporting no held button is read as
|
|
894
|
-
* the release that never arrived, and a fresh press on the same pointer says
|
|
895
|
-
* the tracked one had already ended.
|
|
896
|
-
*/
|
|
897
|
-
declare function openPointerSession(origin: Element, down: PointerEvent | React.PointerEvent, cb: PointerSessionCallbacks, opts?: PointerSessionOptions): PointerSession;
|
|
898
|
-
|
|
899
1448
|
/** A 2D point in the rect element's local coordinate space. */
|
|
900
1449
|
interface HandleDragPoint {
|
|
901
1450
|
x: number;
|
|
@@ -1049,33 +1598,6 @@ interface CanvasSizeSnapshot extends CanvasSize {
|
|
|
1049
1598
|
* query instead. */
|
|
1050
1599
|
declare function useCanvasSize(containerRef: RefObject<HTMLElement | null>): CanvasSizeSnapshot;
|
|
1051
1600
|
|
|
1052
|
-
/**
|
|
1053
|
-
* Handle/hit multiplier applied on a coarse pointer.
|
|
1054
|
-
*
|
|
1055
|
-
* 8px handle → 14px; 24px rotation distance → 42px. Counting the
|
|
1056
|
-
* surrounding grab zone, that lands in the Apple HIG 44pt / Material 48dp
|
|
1057
|
-
* minimum-touch-target band. One constant so it is tunable in one place.
|
|
1058
|
-
*/
|
|
1059
|
-
declare const COARSE_TARGET_SCALE = 1.75;
|
|
1060
|
-
/**
|
|
1061
|
-
* Fold consumer overrides over detected facts and derive `targetScale`.
|
|
1062
|
-
*
|
|
1063
|
-
* `targetScale` is re-derived AFTER the merge, so an override of
|
|
1064
|
-
* `coarsePointer` alone scales the chrome as expected. An explicit
|
|
1065
|
-
* `targetScale` override wins over the derivation.
|
|
1066
|
-
*/
|
|
1067
|
-
declare function resolveDeviceProfile(detected: DetectedDeviceFacts, overrides?: Partial<DeviceProfile>): DeviceProfile;
|
|
1068
|
-
/**
|
|
1069
|
-
* Assumed when `matchMedia` is unavailable (SSR, jsdom) and used as the
|
|
1070
|
-
* absent-means value for `RuleCtx.device`.
|
|
1071
|
-
*
|
|
1072
|
-
* Derived from `resolveDeviceProfile` rather than hand-written, so it can
|
|
1073
|
-
* never drift from what the function would compute for the same facts. A
|
|
1074
|
-
* mouse-like device is the safe default: it is what the kit has always
|
|
1075
|
-
* assumed, so an absent profile changes nothing for existing consumers.
|
|
1076
|
-
*/
|
|
1077
|
-
declare const DEFAULT_DEVICE_PROFILE: DeviceProfile;
|
|
1078
|
-
|
|
1079
1601
|
/**
|
|
1080
1602
|
* Base sizes for grabbable chrome, in CSS pixels at `targetScale = 1`, and the
|
|
1081
1603
|
* one accessor that resolves them for a live pointer type.
|
|
@@ -1149,7 +1671,7 @@ interface ZoomClampOpts {
|
|
|
1149
1671
|
min?: ZoomBound;
|
|
1150
1672
|
max?: ZoomBound;
|
|
1151
1673
|
}
|
|
1152
|
-
declare function zoomAt(
|
|
1674
|
+
declare function zoomAt(input: View, anchor: {
|
|
1153
1675
|
x: number;
|
|
1154
1676
|
y: number;
|
|
1155
1677
|
}, factor: ZoomFactor, opts?: ZoomClampOpts): View;
|
|
@@ -1165,6 +1687,23 @@ declare function zoomAt(view: View, anchor: {
|
|
|
1165
1687
|
*/
|
|
1166
1688
|
declare const DEFAULT_MIN_ZOOM = 0.1;
|
|
1167
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;
|
|
1168
1707
|
|
|
1169
1708
|
/** Options for {@link sceneNodeClientRect}. */
|
|
1170
1709
|
interface SceneNodeClientRectOpts {
|
|
@@ -1215,258 +1754,24 @@ declare function computeFitViewport(viewportW: number, viewportH: number, conten
|
|
|
1215
1754
|
declare function useAutoCenter(width: number, height: number, contentW: number, contentH: number, setZoom: (z: number) => void, setPan: (x: number, y: number) => void): void;
|
|
1216
1755
|
|
|
1217
1756
|
/**
|
|
1218
|
-
*
|
|
1219
|
-
* (`
|
|
1220
|
-
*
|
|
1221
|
-
*
|
|
1222
|
-
* Extracted from the deleted singular `useKeybinding` hook so the remaining
|
|
1223
|
-
* consumers don't depend on its disappearance.
|
|
1224
|
-
*/
|
|
1225
|
-
/**
|
|
1226
|
-
* @internal — runtime shape consumed by `matchesKeyBinding`. Public tool authors
|
|
1227
|
-
* should use `ToolKeybinding` from `@weasel-js/core` for declaring
|
|
1228
|
-
* configurable activation keys.
|
|
1229
|
-
*/
|
|
1230
|
-
interface KeyBinding {
|
|
1231
|
-
/**
|
|
1232
|
-
* Key or list of keys to match. Compared case-insensitively against
|
|
1233
|
-
* `event.key`, so `'a'` matches both `'a'` and `'A'`.
|
|
1234
|
-
*/
|
|
1235
|
-
key: string | readonly string[];
|
|
1236
|
-
/**
|
|
1237
|
-
* Require Cmd (mac) or Ctrl (others). When `true`, exactly one of
|
|
1238
|
-
* `metaKey`/`ctrlKey` must be held. Default `false` (both forbidden).
|
|
1239
|
-
*/
|
|
1240
|
-
mod?: boolean;
|
|
1241
|
-
/** Require Alt. Default `false` (forbidden). */
|
|
1242
|
-
alt?: boolean;
|
|
1243
|
-
/**
|
|
1244
|
-
* Shift policy. `undefined`/`false` forbids shift, `true` requires
|
|
1245
|
-
* shift, `'optional'` allows either. Default `undefined`.
|
|
1246
|
-
*/
|
|
1247
|
-
shift?: boolean | 'optional';
|
|
1248
|
-
/** Skip when focus is in an editable element. Default `true`. */
|
|
1249
|
-
skipInEditable?: boolean;
|
|
1250
|
-
/** When `false`, the listener is not attached. Default `true`. */
|
|
1251
|
-
enabled?: boolean;
|
|
1252
|
-
/** Call `preventDefault` before the handler. Default `true`. */
|
|
1253
|
-
preventDefault?: boolean;
|
|
1254
|
-
}
|
|
1255
|
-
/** Returns true when the target is an input, textarea, or contenteditable element. */
|
|
1256
|
-
declare function isEditableTarget(target: EventTarget | null): boolean;
|
|
1257
|
-
/**
|
|
1258
|
-
* Pure matcher for `KeyBinding` against a `KeyboardEvent`. Only checks key +
|
|
1259
|
-
* modifier policy — does NOT apply the editable-target skip or
|
|
1260
|
-
* `preventDefault`. Shared by the tool dispatcher (`useKeybindings`) and the
|
|
1261
|
-
* gesture dispatcher so the rules can't drift.
|
|
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.
|
|
1262
1761
|
*/
|
|
1263
|
-
declare function matchesKeyBinding(e: KeyboardEvent, b: KeyBinding): boolean;
|
|
1264
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
|
+
}
|
|
1265
1772
|
/**
|
|
1266
|
-
*
|
|
1267
|
-
*
|
|
1268
|
-
* wrapping `all`/`any`/`not` nodes.
|
|
1269
|
-
*
|
|
1270
|
-
* **Chain semantics: strict left-to-right.** No boolean precedence.
|
|
1271
|
-
* `focused.or(hovering).and(selectionIs(1))` evaluates
|
|
1272
|
-
* `((focused || hovering) && selectionIs(1))` — NOT
|
|
1273
|
-
* `(focused || (hovering && selectionIs(1)))` as standard precedence
|
|
1274
|
-
* would give. For grouped disjunction, use the top-level `or` / `and` /
|
|
1275
|
-
* `not` helpers or name intermediates.
|
|
1276
|
-
*
|
|
1277
|
-
* Combinators flatten same-kind nesting on construction so `a.and(b).and(c)`
|
|
1278
|
-
* produces `{ all: [a, b, c] }` rather than `{ all: [{ all: [a, b] }, c] }`.
|
|
1279
|
-
* Canonical form simplifies downstream introspection.
|
|
1280
|
-
*
|
|
1281
|
-
* Use {@link when} for the inline-lambda escape hatch.
|
|
1282
|
-
*/
|
|
1283
|
-
declare function cond(rule: Rule): Condition;
|
|
1284
|
-
/** Inline-lambda escape hatch. Wraps the closure as a `when` rule node. */
|
|
1285
|
-
declare function when(fn: (ctx: RuleCtx) => boolean): Condition;
|
|
1286
|
-
/** `(a && b && c && ...)` — useful when chain mixing makes left-to-right
|
|
1287
|
-
* semantics ambiguous. */
|
|
1288
|
-
declare function and(...cs: (Condition | Rule)[]): Condition;
|
|
1289
|
-
/** `(a || b || c || ...)` — preferred over `.or` chains when mixed with
|
|
1290
|
-
* `.and` to make grouping explicit. */
|
|
1291
|
-
declare function or(...cs: (Condition | Rule)[]): Condition;
|
|
1292
|
-
/** `!c` — top-level negation. Most rules use `.andNot()` / `.orNot()`
|
|
1293
|
-
* instead; this is for the lead-with-negation case. */
|
|
1294
|
-
declare function not(c: Condition | Rule): Condition;
|
|
1295
|
-
/** Always true. The fallback for any chrome id without a registered rule. */
|
|
1296
|
-
declare const always: Condition;
|
|
1297
|
-
/** Always false. Useful for "turn this chrome off entirely":
|
|
1298
|
-
* `chromeVisibility={{ 'snap.guides': never }}`. */
|
|
1299
|
-
declare const never: Condition;
|
|
1300
|
-
/** Canvas surface currently focused. */
|
|
1301
|
-
declare const focused: Condition;
|
|
1302
|
-
/** Any action currently in flight (read: user is gesturing). */
|
|
1303
|
-
declare const gesturing: Condition;
|
|
1304
|
-
/** Active action's kind matches `kind` (e.g. `actionIs('move')`). */
|
|
1305
|
-
declare const actionIs: (kind: string) => Condition;
|
|
1306
|
-
/** Nothing selected. */
|
|
1307
|
-
declare const selectionEmpty: Condition;
|
|
1308
|
-
/** Exactly `n` items selected. */
|
|
1309
|
-
declare const selectionIs: (n: number) => Condition;
|
|
1310
|
-
/** At least `n` items selected. `selectionAtLeast(1)` is the common
|
|
1311
|
-
* "something is selected" check. */
|
|
1312
|
-
declare const selectionAtLeast: (n: number) => Condition;
|
|
1313
|
-
/** Multi-mode handle behavior active (single shared union-bounds
|
|
1314
|
-
* handle vs per-item handles). Implemented as a `when` because
|
|
1315
|
-
* `multiActive` is a derived single-call read on RuleCtx, not a
|
|
1316
|
-
* selector-table key. Stable; safe to introspect. */
|
|
1317
|
-
declare const multiActive: Condition;
|
|
1318
|
-
/** Pointer is hovering some node. */
|
|
1319
|
-
declare const hovering: Condition;
|
|
1320
|
-
/** Pointer is hovering a node that is currently selected. */
|
|
1321
|
-
declare const hoveringSelected: Condition;
|
|
1322
|
-
/** Named modifier key currently held. */
|
|
1323
|
-
declare const modifierHeld: (m: keyof ModifierState) => Condition;
|
|
1324
|
-
/** View scale (uniform or geometric mean for non-uniform) is at least
|
|
1325
|
-
* `z`. Useful for "hide hairline chrome at low zoom" rules. */
|
|
1326
|
-
declare const zoomAtLeast: (z: number) => Condition;
|
|
1327
|
-
/** Active mode equals `m`. */
|
|
1328
|
-
declare const modeIs: (m: string) => Condition;
|
|
1329
|
-
/** Active mode is one of `modes`. */
|
|
1330
|
-
declare const modeIn: (modes: readonly string[]) => Condition;
|
|
1331
|
-
/** Active mode is NOT `m`. */
|
|
1332
|
-
declare const modeNot: (m: string) => Condition;
|
|
1333
|
-
/** Active mode's `allows` includes capability `cap`. */
|
|
1334
|
-
declare const capabilityIs: (cap: string) => Condition;
|
|
1335
|
-
/** Active mode's `allows` includes ANY of `caps` (OR). */
|
|
1336
|
-
declare const capabilityIn: (caps: readonly string[]) => Condition;
|
|
1337
|
-
/** Active mode's `allows` includes ALL of `caps` (AND). */
|
|
1338
|
-
declare const capabilityAll: (caps: readonly string[]) => Condition;
|
|
1339
|
-
/** Active mode's `allows` does NOT include capability `cap`. */
|
|
1340
|
-
declare const capabilityNot: (cap: string) => Condition;
|
|
1341
|
-
/** Primary pointer is imprecise (touch, most styluses). Absent device
|
|
1342
|
-
* profile → false, so a rule written with this atom is inert on the
|
|
1343
|
-
* mouse-shaped default rather than silently flipping. */
|
|
1344
|
-
declare const coarsePointer: Condition;
|
|
1345
|
-
/** Primary pointer can hover. Absent device profile → true. Pair with
|
|
1346
|
-
* `not(...)` to gate chrome that only makes sense with a hovering
|
|
1347
|
-
* pointer: `not(canHover)` is "this device cannot hover". */
|
|
1348
|
-
declare const canHover: Condition;
|
|
1349
|
-
|
|
1350
|
-
/**
|
|
1351
|
-
* Kit-shipped defaults. Merged with the consumer's `chromeVisibility` map
|
|
1352
|
-
* at resolve time; consumer entries take precedence per id.
|
|
1353
|
-
*
|
|
1354
|
-
* Written as literal Rule trees rather than fluent chains so the inputs
|
|
1355
|
-
* each rule depends on are immediately visible. The fluent atoms compile
|
|
1356
|
-
* to the same trees; either form is valid in a VisibilityRules entry.
|
|
1357
|
-
*
|
|
1358
|
-
* Gating is written in terms of **capabilities, not mode ids**. A
|
|
1359
|
-
* capability rule keeps holding when a new mode is added that permits the
|
|
1360
|
-
* same thing; a mode rule has to be found and edited every time. There is
|
|
1361
|
-
* no `mode:` rule left in this table — the `path-edit.*` chrome used to be
|
|
1362
|
-
* the exception, on the theory that it's the visual signature of one mode;
|
|
1363
|
-
* see the comment on those rules below for why that was wrong in both
|
|
1364
|
-
* directions and what replaced it.
|
|
1365
|
-
*
|
|
1366
|
-
* Chrome that gates on the *absence* of a capability (the selection
|
|
1367
|
-
* outline, suppressed while an anchor-editing overlay owns the visuals)
|
|
1368
|
-
* uses `capability: { not: … }` for the same reason.
|
|
1369
|
-
*/
|
|
1370
|
-
declare const defaultVisibilityRules: VisibilityRules;
|
|
1371
|
-
|
|
1372
|
-
/**
|
|
1373
|
-
* Build the per-frame visibility check. Merges consumer rules on top
|
|
1374
|
-
* of the kit defaults, then closes over `ctx` so each chrome-id
|
|
1375
|
-
* lookup runs its rule against the current state.
|
|
1376
|
-
*
|
|
1377
|
-
* `VisibilityRules` entries may be either fluent `Condition` values
|
|
1378
|
-
* (callable) or raw `Rule` trees — we normalize at lookup time.
|
|
1379
|
-
*
|
|
1380
|
-
* Predicates are O(1) and run once per chrome id per frame; no
|
|
1381
|
-
* memoization in v1 — profile before adding any.
|
|
1382
|
-
*
|
|
1383
|
-
* `ChromeCtx` is the legacy shape; surfaces still on it get `mode='normal'`
|
|
1384
|
-
* and `DEFAULT_ALLOWED_CAPABILITIES` filled in here, so a caller that never
|
|
1385
|
-
* opted into modality behaves exactly like one sitting in normal mode.
|
|
1386
|
-
*/
|
|
1387
|
-
declare function resolveVisibility(consumer: VisibilityRules | undefined, ctx: ChromeCtx | RuleCtx): (id: ChromeId) => boolean;
|
|
1388
|
-
|
|
1389
|
-
/**
|
|
1390
|
-
* Pure assembler for {@link ChromeCtx}.
|
|
1391
|
-
*
|
|
1392
|
-
* Called once per frame on the rendering side from whichever surface
|
|
1393
|
-
* needs to evaluate visibility rules — `composeAffordanceLayer`,
|
|
1394
|
-
* `createSelectionOverlayLayer`, the dispatcher overlay layer, etc.
|
|
1395
|
-
*
|
|
1396
|
-
* Sources are passed as plain getters / values rather than the live
|
|
1397
|
-
* objects they come from. This keeps `chrome-caps` from depending on
|
|
1398
|
-
* React, the dispatcher's concrete type, or `ChromeState`'s bounds
|
|
1399
|
-
* machinery — the same builder works from a test harness, a Storybook
|
|
1400
|
-
* fixture, or `<SceneCanvas>`.
|
|
1401
|
-
*/
|
|
1402
|
-
|
|
1403
|
-
/** The pieces of live canvas state a `ChromeCtx` is assembled from. */
|
|
1404
|
-
interface BuildChromeCtxArgs {
|
|
1405
|
-
focused: boolean;
|
|
1406
|
-
selection: readonly NodeId[];
|
|
1407
|
-
multiActive: boolean;
|
|
1408
|
-
modifiers: ModifierState;
|
|
1409
|
-
action: {
|
|
1410
|
-
kind: string | null;
|
|
1411
|
-
id: string | null;
|
|
1412
|
-
};
|
|
1413
|
-
hover: NodeId | null;
|
|
1414
|
-
view: View;
|
|
1415
|
-
}
|
|
1416
|
-
/** Gather the current canvas state into the context that chrome-visibility
|
|
1417
|
-
* rules are evaluated against. Rebuilt per frame. */
|
|
1418
|
-
declare function buildChromeCtx(args: BuildChromeCtxArgs): ChromeCtx;
|
|
1419
|
-
|
|
1420
|
-
/**
|
|
1421
|
-
* useHoverTracking — last-hovered NodeId for chrome-caps rules.
|
|
1422
|
-
*
|
|
1423
|
-
* Attaches a `pointermove` listener to the supplied canvas; on each move it
|
|
1424
|
-
* runs the supplied `nodeAtClientPoint` and caches the resulting id on a ref.
|
|
1425
|
-
* Cleared on `pointerleave` (pointer left the canvas → nothing is hovered).
|
|
1426
|
-
*
|
|
1427
|
-
* Returns a stable getter — call once per frame from `buildChromeCtx`.
|
|
1428
|
-
*
|
|
1429
|
-
* No re-render: the ref updates silently, and the next render that
|
|
1430
|
-
* reads it picks up the fresh value. Chrome-caps rules are evaluated
|
|
1431
|
-
* during paint, so the hover state is always read fresh.
|
|
1432
|
-
*/
|
|
1433
|
-
|
|
1434
|
-
/** Options for `useHoverTracking`. */
|
|
1435
|
-
interface UseHoverTrackingArgs {
|
|
1436
|
-
canvasRef: RefObject<HTMLElement | null>;
|
|
1437
|
-
/** Topmost id under a client point, or null. One lookup rather than a
|
|
1438
|
-
* client→world thunk beside a world-space picker: a screen-pixel pick
|
|
1439
|
-
* tolerance converts against the camera the point resolved to, and two
|
|
1440
|
-
* thunks are two chances to disagree about which view that is. */
|
|
1441
|
-
nodeAtClientPoint: (clientX: number, clientY: number) => {
|
|
1442
|
-
id: NodeId;
|
|
1443
|
-
} | null;
|
|
1444
|
-
enabled?: boolean;
|
|
1445
|
-
}
|
|
1446
|
-
/** Track which node the pointer is over. Returns a getter rather than state,
|
|
1447
|
-
* so per-frame code can read the current value without the hover re-rendering
|
|
1448
|
-
* the component on every pointer move. */
|
|
1449
|
-
declare function useHoverTracking(args: UseHoverTrackingArgs): () => NodeId | null;
|
|
1450
|
-
|
|
1451
|
-
/**
|
|
1452
|
-
* Project an action's keyboard bindings into the shape a shortcut chip
|
|
1453
|
-
* renders from (`formatShortcut` / `formatShortcutParts` in
|
|
1454
|
-
* `@weasel-js/ui`). Palette and menu surfaces show what an action answers
|
|
1455
|
-
* to; the dispatcher reads the specs themselves.
|
|
1456
|
-
*/
|
|
1457
|
-
|
|
1458
|
-
/** One keyboard shortcut, flattened for display. Structurally the
|
|
1459
|
-
* `ShortcutInput` weasel-ui formats — kept local so core doesn't depend on
|
|
1460
|
-
* the UI package. */
|
|
1461
|
-
interface ActionShortcut {
|
|
1462
|
-
key: string;
|
|
1463
|
-
mod: boolean;
|
|
1464
|
-
alt: boolean;
|
|
1465
|
-
shift: boolean;
|
|
1466
|
-
}
|
|
1467
|
-
/**
|
|
1468
|
-
* The chip form of a single gesture spec, or `undefined` when the spec has
|
|
1469
|
-
* none.
|
|
1773
|
+
* The chip form of a single gesture spec, or `undefined` when the spec has
|
|
1774
|
+
* none.
|
|
1470
1775
|
*
|
|
1471
1776
|
* Two kinds of collapsing, both because a binding list is written for a
|
|
1472
1777
|
* matcher rather than for a reader:
|
|
@@ -1513,7 +1818,7 @@ declare function actionShortcuts(action: Action): readonly ActionShortcut[];
|
|
|
1513
1818
|
*
|
|
1514
1819
|
* The per-frame poses still go *somewhere* the scene can see: the ephemeral
|
|
1515
1820
|
* override table, which bypasses history entirely. That is what lets a node
|
|
1516
|
-
* deriving its geometry from a dragged one follow the drag — `
|
|
1821
|
+
* deriving its geometry from a dragged one follow the drag — `sceneDepLookup`
|
|
1517
1822
|
* and the pick source both read overrides, and neither can see this action's
|
|
1518
1823
|
* scratch. Keeping the frame in scratch alone is why the edge used to stay
|
|
1519
1824
|
* anchored to the old endpoint and jump on drop.
|
|
@@ -1527,11 +1832,8 @@ declare function actionShortcuts(action: Action): readonly ActionShortcut[];
|
|
|
1527
1832
|
*
|
|
1528
1833
|
* ## Pose generics
|
|
1529
1834
|
*
|
|
1530
|
-
* `
|
|
1531
|
-
*
|
|
1532
|
-
* delegates to `RECT_POSE_DESCRIPTOR.translate` which treats any pose as
|
|
1533
|
-
* `{x, y, ...}`. Consumers with non-rect poses should register a custom
|
|
1534
|
-
* action with a typed translatePose.
|
|
1835
|
+
* Poses are `unknown`; every read and write goes through the `poseDescriptor`
|
|
1836
|
+
* dep (`AUTO_POSE_DESCRIPTOR` when unsourced).
|
|
1535
1837
|
*/
|
|
1536
1838
|
|
|
1537
1839
|
/**
|
|
@@ -1559,17 +1861,14 @@ declare const moveAction: Action & {
|
|
|
1559
1861
|
* start poses, applies per-frame bounds remapping, and commits a single
|
|
1560
1862
|
* `scene.batch` entry on end.
|
|
1561
1863
|
*
|
|
1562
|
-
* ## Behaviors / point-snap / expandIds
|
|
1864
|
+
* ## Behaviors / point-snap / expandIds — via the `resizePolicy` dep
|
|
1563
1865
|
*
|
|
1564
|
-
* The
|
|
1565
|
-
*
|
|
1566
|
-
*
|
|
1567
|
-
* 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:
|
|
1568
1869
|
*
|
|
1569
1870
|
* - Calls `expandIds([id])` at start. When the result expands beyond the
|
|
1570
1871
|
* starting id, takes the group path (union-AABB origin, per-leaf remap).
|
|
1571
|
-
* - Projects poses through the supplied `geometry: PoseProjection<TPose>`
|
|
1572
|
-
* instead of the rect-shaped `RECT_POSE_DESCRIPTOR` default.
|
|
1573
1872
|
* - Runs `behaviors[]` after the raw anchor-math bounds are computed.
|
|
1574
1873
|
* Behaviors return `{ pose? }` and rewrite the proposed bounds before
|
|
1575
1874
|
* they're projected back into pose space.
|
|
@@ -1578,12 +1877,17 @@ declare const moveAction: Action & {
|
|
|
1578
1877
|
* frame's world point lands on the snap target.
|
|
1579
1878
|
*
|
|
1580
1879
|
* When the dep is absent the invoker falls back to identity defaults
|
|
1581
|
-
* (no behaviors, no snap, `ids => ids` expansion
|
|
1582
|
-
*
|
|
1583
|
-
*
|
|
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.
|
|
1584
1888
|
*
|
|
1585
1889
|
* @see useResize — the React hook this descriptor mirrors.
|
|
1586
|
-
* @see src/interactions/actions/resize/geometry.ts — `
|
|
1890
|
+
* @see src/interactions/actions/resize/geometry.ts — `PoseDescriptor`.
|
|
1587
1891
|
*/
|
|
1588
1892
|
|
|
1589
1893
|
/**
|
|
@@ -1603,7 +1907,7 @@ declare const resizeAction: Action & {
|
|
|
1603
1907
|
*
|
|
1604
1908
|
* ## Status: REAL (unrotated-pivot path)
|
|
1605
1909
|
*
|
|
1606
|
-
* Implements the core rotation math from `useRotate
|
|
1910
|
+
* Implements the core rotation math from `useRotate`:
|
|
1607
1911
|
* - `start`: captures origin poses + AABB centers; computes start pointer
|
|
1608
1912
|
* angle around the union center of selected nodes.
|
|
1609
1913
|
* - `onMove`: derives pointer angle delta from start, applies to each node's
|
|
@@ -1618,8 +1922,9 @@ declare const resizeAction: Action & {
|
|
|
1618
1922
|
*
|
|
1619
1923
|
* ## Constraints vs `useRotate`
|
|
1620
1924
|
*
|
|
1621
|
-
* -
|
|
1622
|
-
*
|
|
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.
|
|
1623
1928
|
* - No behavior pipeline (snap, etc.). Behaviors wait for a later phase.
|
|
1624
1929
|
* - No overlay rendering — deferred to Phase 7 overlay surface.
|
|
1625
1930
|
* - Shift-snap (15° quantum) is NOT wired in this phase — omitted deliberately
|
|
@@ -1633,9 +1938,7 @@ declare const resizeAction: Action & {
|
|
|
1633
1938
|
*
|
|
1634
1939
|
* Requires dep-schema entries: `selection`, `scene`.
|
|
1635
1940
|
*
|
|
1636
|
-
* Implements the unrotated-pivot rotation path from `useRotate
|
|
1637
|
-
* shaped poses. Non-rect or behavior-rich consumers should register a custom
|
|
1638
|
-
* `rotateAction` with a typed `RotateGeometry` dep.
|
|
1941
|
+
* Implements the unrotated-pivot rotation path from `useRotate`.
|
|
1639
1942
|
*
|
|
1640
1943
|
* @see useRotate — the React hook this descriptor mirrors for the rect case.
|
|
1641
1944
|
*/
|
|
@@ -1850,9 +2153,7 @@ declare const clearSelectionAction: Action & {
|
|
|
1850
2153
|
*
|
|
1851
2154
|
* ## Pose generics
|
|
1852
2155
|
*
|
|
1853
|
-
* Poses are translated
|
|
1854
|
-
* `moveAction`. Non-rect poses with custom layout (e.g. paths) should register
|
|
1855
|
-
* a custom clone action with a typed geometry dep.
|
|
2156
|
+
* Poses are translated through the `poseDescriptor` dep, as `moveAction` does.
|
|
1856
2157
|
*/
|
|
1857
2158
|
|
|
1858
2159
|
/**
|
|
@@ -2154,6 +2455,19 @@ declare const lassoSelectAction: Action & {
|
|
|
2154
2455
|
requires: string[];
|
|
2155
2456
|
};
|
|
2156
2457
|
|
|
2458
|
+
/**
|
|
2459
|
+
* @experimental
|
|
2460
|
+
* Static descriptor for the `slice` Action.
|
|
2461
|
+
*
|
|
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
|
+
|
|
2157
2471
|
/**
|
|
2158
2472
|
* `pinchZoomAction` — ongoing Action descriptor for two-finger pinch zoom
|
|
2159
2473
|
* and pan. The id and label stay `pinchZoom` / `Pinch Zoom`.
|
|
@@ -2217,6 +2531,143 @@ declare const pinchZoomAction: Action & {
|
|
|
2217
2531
|
requires: string[];
|
|
2218
2532
|
};
|
|
2219
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
|
+
|
|
2220
2671
|
/** @experimental */
|
|
2221
2672
|
interface UseStandardActionsOptions {
|
|
2222
2673
|
/** Kit selection state — ids of currently selected nodes. */
|
|
@@ -2257,25 +2708,6 @@ declare const KIT_STANDARD_ACTION_IDS: readonly string[];
|
|
|
2257
2708
|
*/
|
|
2258
2709
|
declare function useStandardActions(opts: UseStandardActionsOptions): void;
|
|
2259
2710
|
|
|
2260
|
-
/**
|
|
2261
|
-
* Shared scene-backed commit adapter for default actions.
|
|
2262
|
-
*
|
|
2263
|
-
* Default actions route data/layer/pose/parent mutations through the
|
|
2264
|
-
* consumer's `applyOps` commit hook when one is present; when it isn't, they
|
|
2265
|
-
* fall back to applying the committed ops directly against the scene through
|
|
2266
|
-
* this adapter. It carries the scene-backed op-apply methods (`setPose` /
|
|
2267
|
-
* `setParent` / `setData` / `setLayer` / `removeNode` / `insertNode` /
|
|
2268
|
-
* `setChildOrder`) plus the read-side queries (`getNode` / `getNodes` /
|
|
2269
|
-
* `getPose` / `getParent` / `getChildren` / `getSelection`) and
|
|
2270
|
-
* `setSelection`. Known exclusions from the op factory roster — surfaces the
|
|
2271
|
-
* scene doesn't own: `setPath` and `setText`.
|
|
2272
|
-
*
|
|
2273
|
-
* Lives in `interactions/actions/` (not `canvas/sceneAdapter.ts`) so default
|
|
2274
|
-
* actions never import from `canvas/` — that back-edge would create an
|
|
2275
|
-
* `interactions → canvas → interactions` cycle. Mirrors `moveGestureAdapter`,
|
|
2276
|
-
* widened to all op-apply methods.
|
|
2277
|
-
*/
|
|
2278
|
-
|
|
2279
2711
|
/** Build the adapter the default actions commit through when the consumer
|
|
2280
2712
|
* supplies no `applyOps` hook of its own — it applies ops straight to the
|
|
2281
2713
|
* scene. Path and text ops are not covered; those surfaces belong to their
|
|
@@ -2301,289 +2733,26 @@ declare function defaultCommitAdapter<TPose>(scene: Scene<unknown, string, TPose
|
|
|
2301
2733
|
/** Options for `useResizePolicy`. Each omitted field falls back to the kit
|
|
2302
2734
|
* default. */
|
|
2303
2735
|
interface UseResizePolicyOptions<TPose> {
|
|
2304
|
-
constraints?: TPose extends
|
|
2305
|
-
pointSnap?: TPose extends
|
|
2736
|
+
constraints?: TPose extends Bounds ? BoundsConstraint<TPose>[] : never[];
|
|
2737
|
+
pointSnap?: TPose extends Bounds ? PointSnapBehavior<TPose>[] : never[];
|
|
2306
2738
|
expandIds?: (ids: string[]) => string[];
|
|
2307
|
-
projection?: PoseProjection<TPose>;
|
|
2308
2739
|
}
|
|
2309
2740
|
/** Publish how resizing should behave — constraints, point snapping, group
|
|
2310
|
-
* expansion
|
|
2741
|
+
* expansion — for the resize action to consult. */
|
|
2311
2742
|
declare function useResizePolicy<TPose>(options: UseResizePolicyOptions<TPose>): void;
|
|
2312
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
|
+
|
|
2313
2752
|
/** Publish how a slice (knife cut) is performed, so the `slice` action can
|
|
2314
2753
|
* run against the consumer's geometry. */
|
|
2315
2754
|
declare function useSliceDep(dep: SliceDep): void;
|
|
2316
2755
|
|
|
2317
|
-
/**
|
|
2318
|
-
* The painted cursor a surface is currently showing, shared between whoever
|
|
2319
|
-
* decides it and the layer that draws it.
|
|
2320
|
-
*
|
|
2321
|
-
* Two slots rather than one, mirroring the precedence the cursor pipeline
|
|
2322
|
-
* already has: `<Canvas>` writes the active tool's cursor to `base` from
|
|
2323
|
-
* render, and the hover pump writes an affordance's or an action's cursor to
|
|
2324
|
-
* `override` imperatively. The override wins while it is set, and clearing it
|
|
2325
|
-
* restores the base without a React commit — the same reason the pump uses an
|
|
2326
|
-
* inline style for the CSS tier.
|
|
2327
|
-
*/
|
|
2328
|
-
|
|
2329
|
-
/** The painted arm of `ResolvedCursor` — what this module stores. */
|
|
2330
|
-
type PaintedCursor = Extract<ResolvedCursor, {
|
|
2331
|
-
kind: 'painted';
|
|
2332
|
-
}>;
|
|
2333
|
-
interface PaintedCursorFrame {
|
|
2334
|
-
readonly cursor: PaintedCursor;
|
|
2335
|
-
/** Pointer position in the layer's own space: canvas-local CSS px. */
|
|
2336
|
-
readonly at: {
|
|
2337
|
-
readonly x: number;
|
|
2338
|
-
readonly y: number;
|
|
2339
|
-
};
|
|
2340
|
-
}
|
|
2341
|
-
interface PaintedCursorState {
|
|
2342
|
-
setBase(cursor: PaintedCursor | null): void;
|
|
2343
|
-
setOverride(cursor: PaintedCursor | null): void;
|
|
2344
|
-
/** Canvas-local CSS px. */
|
|
2345
|
-
setPointer(x: number, y: number): void;
|
|
2346
|
-
/** Pointer left the surface: nothing to draw until it returns. */
|
|
2347
|
-
clearPointer(): void;
|
|
2348
|
-
/**
|
|
2349
|
-
* Whether a painted cursor is set at all, regardless of where the pointer is.
|
|
2350
|
-
*
|
|
2351
|
-
* Lets the pointer path skip measuring the canvas rect on every move in the
|
|
2352
|
-
* overwhelmingly common case where the compositor is drawing the cursor and
|
|
2353
|
-
* nothing here needs its position.
|
|
2354
|
-
*/
|
|
2355
|
-
active(): boolean;
|
|
2356
|
-
/** What the layer should draw this frame, or null for none. */
|
|
2357
|
-
current(): PaintedCursorFrame | null;
|
|
2358
|
-
/** Run `fn` whenever the answer to `current()` may have changed. */
|
|
2359
|
-
subscribe(fn: () => void): () => void;
|
|
2360
|
-
}
|
|
2361
|
-
declare function createPaintedCursorState(): PaintedCursorState;
|
|
2362
|
-
|
|
2363
|
-
/**
|
|
2364
|
-
* Everything about handling an input event that depends on *which view* it
|
|
2365
|
-
* landed in: the dispatcher that runs it, and the three lookups that resolve
|
|
2366
|
-
* a client point against that view's camera.
|
|
2367
|
-
*
|
|
2368
|
-
* @internal One per view. The hook builds the `id: null` one from its flat
|
|
2369
|
-
* options; `views` supplies the rest, and the hook chooses between them per
|
|
2370
|
-
* event, so that it — and its listener set — still mounts exactly once.
|
|
2371
|
-
*/
|
|
2372
|
-
interface DispatcherViewTarget {
|
|
2373
|
-
/** `null` is the root view — the whole canvas. Matches `ViewTarget.id`. */
|
|
2374
|
-
id: string | null;
|
|
2375
|
-
dispatcher: Dispatcher;
|
|
2376
|
-
affordanceAt: UseGestureDispatcherOptions['affordanceAt'];
|
|
2377
|
-
classifyTarget: UseGestureDispatcherOptions['classifyTarget'];
|
|
2378
|
-
clientToWorld: UseGestureDispatcherOptions['clientToWorld'];
|
|
2379
|
-
/**
|
|
2380
|
-
* The deps this view answers for itself — its camera, its selection, and
|
|
2381
|
-
* whatever else is per-view rather than per-canvas. Read per event; every
|
|
2382
|
-
* name it does not carry still resolves through the canvas registry.
|
|
2383
|
-
*
|
|
2384
|
-
* This is why a view does not get a `DepRegistryProvider` of its own. The
|
|
2385
|
-
* registry is where a consumer registers *sources*, and one per view would
|
|
2386
|
-
* fragment that: a consumer overriding `insert` would have to know how many
|
|
2387
|
-
* views exist and override each. An overlay keeps one place to register and
|
|
2388
|
-
* one authority per dep, with the view claiming only what is genuinely its.
|
|
2389
|
-
*
|
|
2390
|
-
* Without this a gesture inside a panel pans the whole canvas and selects
|
|
2391
|
-
* into the canvas's selection — correct coordinates alone do not make
|
|
2392
|
-
* routing correct.
|
|
2393
|
-
*/
|
|
2394
|
-
deps?: () => Partial<DepSchema>;
|
|
2395
|
-
/**
|
|
2396
|
-
* This view's chrome-caps rule context, for the eligibility filter. The rule
|
|
2397
|
-
* table is the surface's, but a rule keyed on selection or the in-flight
|
|
2398
|
-
* action answers per view — so an action hidden in one panel must not
|
|
2399
|
-
* decline a gesture in another. `undefined` means "nothing gates here", the
|
|
2400
|
-
* same answer a surface with no mode registry gives.
|
|
2401
|
-
*/
|
|
2402
|
-
getRuleCtx?: () => RuleCtx | undefined;
|
|
2403
|
-
}
|
|
2404
|
-
/**
|
|
2405
|
-
* The part of `features/viewports`' `ViewResolver` the dispatcher needs: which
|
|
2406
|
-
* view a client point belongs to, pinned to the view a gesture began in.
|
|
2407
|
-
*
|
|
2408
|
-
* @internal Structural on purpose — a `ViewResolver` satisfies it, and the
|
|
2409
|
-
* dispatcher stays free of the viewport module.
|
|
2410
|
-
*/
|
|
2411
|
-
interface ViewIdResolver {
|
|
2412
|
-
begin(pointerId: number, clientX: number, clientY: number): {
|
|
2413
|
-
id: string | null;
|
|
2414
|
-
};
|
|
2415
|
-
at(pointerId: number | null, clientX: number, clientY: number): {
|
|
2416
|
-
id: string | null;
|
|
2417
|
-
};
|
|
2418
|
-
end(pointerId: number): void;
|
|
2419
|
-
}
|
|
2420
|
-
/** Options for `useGestureDispatcher`: the element to listen on, the actions
|
|
2421
|
-
* and tools in play, and the hooks that turn raw DOM events into the world
|
|
2422
|
-
* coordinates and hit targets bindings match against. */
|
|
2423
|
-
interface UseGestureDispatcherOptions {
|
|
2424
|
-
/** Ref to the canvas element. Pointer/wheel/multitouch listeners attach here. */
|
|
2425
|
-
canvasRef: RefObject<HTMLElement | null>;
|
|
2426
|
-
/** Action registry (ActionsRegistry from registry.tsx). */
|
|
2427
|
-
actions: ActionsRegistry;
|
|
2428
|
-
/** Tool definitions keyed by id. Typically passes an empty Map. */
|
|
2429
|
-
toolsById: ReadonlyMap<string, Tool>;
|
|
2430
|
-
/** Default true. Set false to opt out of dispatcher wiring (e.g. demos that disable it). */
|
|
2431
|
-
enabled?: boolean;
|
|
2432
|
-
/**
|
|
2433
|
-
* Observer fired whenever the dispatcher synthesizes a double click, in
|
|
2434
|
-
* world coordinates. Runs BEFORE the event is dispatched and independently
|
|
2435
|
-
* of which binding (if any) handles it.
|
|
2436
|
-
*
|
|
2437
|
-
* This is deliberately not an Action. `<SceneCanvas onDoubleClick>` is a
|
|
2438
|
-
* notification — "the user double-clicked, here's what they hit" — and a
|
|
2439
|
-
* notification must not compete with behavior for the gesture. As a binding
|
|
2440
|
-
* it would lose to `enterPathEdit` on any body hit and silently never fire.
|
|
2441
|
-
* Routing it here keeps a single definition of "double click" (the point of
|
|
2442
|
-
* consolidating the kit's three detectors) without giving it
|
|
2443
|
-
* first-match-wins semantics it shouldn't have.
|
|
2444
|
-
*/
|
|
2445
|
-
onDoubleClick?: (world: {
|
|
2446
|
-
x: number;
|
|
2447
|
-
y: number;
|
|
2448
|
-
}) => void;
|
|
2449
|
-
/**
|
|
2450
|
-
* Default true. Set false to leave the window `keydown`/`keyup` listeners
|
|
2451
|
-
* unattached so keyboard-bound actions never dispatch — pointer, wheel, and
|
|
2452
|
-
* contextmenu channels stay live. `<SceneCanvas>` wires this to
|
|
2453
|
-
* `enableKeybindings`, so opting out of keybindings disables the modern
|
|
2454
|
-
* dispatcher key path as well as the legacy `useKeybindings` hook.
|
|
2455
|
-
*/
|
|
2456
|
-
keyboard?: boolean;
|
|
2457
|
-
/**
|
|
2458
|
-
* Optional affordance classifier. Called on every pointerdown with the
|
|
2459
|
-
* world-space coordinates of the pointer. Returns an `AffordanceHit` when
|
|
2460
|
-
* the pointer lands on a known affordance (resize handle, rotate handle, etc.)
|
|
2461
|
-
* or `null` when the pointer hit open canvas.
|
|
2462
|
-
*
|
|
2463
|
-
* The hit is packed into `InputEvent.pointerdown.affordance` and flows
|
|
2464
|
-
* through into `InvocationCtx.drag.affordance`. Action invokers that require
|
|
2465
|
-
* a specific affordance (e.g. `resizeAction` requires `handle:*`) use this
|
|
2466
|
-
* field as a guard in their `start` body.
|
|
2467
|
-
*
|
|
2468
|
-
* When omitted, `affordance` is always `undefined` — meaning only consumers
|
|
2469
|
-
* that explicitly wire a classifier get affordance-gated behavior.
|
|
2470
|
-
* `<SceneCanvas>` wires the full chrome→dispatcher bridge.
|
|
2471
|
-
*/
|
|
2472
|
-
affordanceAt?: (worldPoint: {
|
|
2473
|
-
x: number;
|
|
2474
|
-
y: number;
|
|
2475
|
-
}) => AffordanceHit | null;
|
|
2476
|
-
/**
|
|
2477
|
-
* Optional body classifier. Called on every pointerdown with the world-space
|
|
2478
|
-
* coordinates of the pointer. Its result is packed onto the event as
|
|
2479
|
-
* `bodyTarget` + `bodyKind`, which `matchTarget` reads to resolve the
|
|
2480
|
-
* string-form `TargetSpec` values in `Tool.bindings`.
|
|
2481
|
-
*
|
|
2482
|
-
* `body` is `'empty'` when nothing is under the pointer, `'selected-body'`
|
|
2483
|
-
* when the topmost hit belongs to the current selection, or
|
|
2484
|
-
* `'unselected-body'` when it belongs to a node that isn't selected. `kind`
|
|
2485
|
-
* is the hit node's semantic kind, when the scene can name it.
|
|
2486
|
-
*
|
|
2487
|
-
* When omitted, every body-derived target form (`'empty'`,
|
|
2488
|
-
* `'selected-body'`, `'unselected-body'`, `kind:<k>`, `kind:<k>:selected`)
|
|
2489
|
-
* never matches — bindings using those specs are silently skipped.
|
|
2490
|
-
* `<SceneCanvas>` wires this.
|
|
2491
|
-
*/
|
|
2492
|
-
classifyTarget?: (worldPoint: {
|
|
2493
|
-
x: number;
|
|
2494
|
-
y: number;
|
|
2495
|
-
}) => BodyClassification;
|
|
2496
|
-
/**
|
|
2497
|
-
* Optional pre-created `Dispatcher`. When provided, this hook pumps events
|
|
2498
|
-
* into the supplied instance instead of creating its own. Lets a parent
|
|
2499
|
-
* scope (e.g. `<SceneCanvas>`) share one dispatcher between the gesture
|
|
2500
|
-
* mounter and other consumers (the preview-ghost layer).
|
|
2501
|
-
*/
|
|
2502
|
-
dispatcher?: Dispatcher;
|
|
2503
|
-
/**
|
|
2504
|
-
* Converts a client-space pointer position (e.g. `e.clientX`, `e.clientY`)
|
|
2505
|
-
* to world-space coordinates. When supplied, every pointer/wheel event's
|
|
2506
|
-
* `x`/`y` is converted before the dispatcher builds `InvocationCtx.world`.
|
|
2507
|
-
*
|
|
2508
|
-
* Without this, `ctx.world` is populated with the raw client coords, which
|
|
2509
|
-
* silently breaks any action whose overlay/output uses absolute world
|
|
2510
|
-
* positions (marquee, lasso polyline, world-space affordances). Actions
|
|
2511
|
-
* that only read `drag.delta` are unaffected because client→world deltas
|
|
2512
|
-
* are equal at scale 1, but as soon as a consumer pans/zooms the view the
|
|
2513
|
-
* deltas diverge too.
|
|
2514
|
-
*
|
|
2515
|
-
* `<SceneCanvas>` always wires this via its canvas rect + current view.
|
|
2516
|
-
* Tests / harnesses without a view can omit it and continue passing raw
|
|
2517
|
-
* coordinates as before.
|
|
2518
|
-
*/
|
|
2519
|
-
clientToWorld?: (clientX: number, clientY: number) => {
|
|
2520
|
-
x: number;
|
|
2521
|
-
y: number;
|
|
2522
|
-
};
|
|
2523
|
-
/**
|
|
2524
|
-
* Invoked once per pump event (`pointermove`, `pointerup`, `pointercancel`,
|
|
2525
|
-
* `key-held` up-phase, `multitouch` move) when a dispatcher-side handle is
|
|
2526
|
-
* in flight. Lets the host canvas schedule a redraw so dispatcher-only
|
|
2527
|
-
* overlays (marquee, lasso, preview-ghost) repaint on each frame.
|
|
2528
|
-
*
|
|
2529
|
-
* Required because dispatcher actions don't go through the legacy
|
|
2530
|
-
* `tools.dispatcher.onGestureChange` redraw bump that ambient tool drags
|
|
2531
|
-
* relied on. Without it, the overlay layer's `draw` never runs between
|
|
2532
|
-
* pointerdown and pointerup, and the chrome flashes once at gesture start
|
|
2533
|
-
* and then sits frozen until the gesture ends.
|
|
2534
|
-
*
|
|
2535
|
-
* `<SceneCanvas>` wires this to the canvas's `requestRedraw`. Test
|
|
2536
|
-
* harnesses can omit it; their dispatchers won't paint between events but
|
|
2537
|
-
* that's already the test contract.
|
|
2538
|
-
*/
|
|
2539
|
-
requestRedraw?: () => void;
|
|
2540
|
-
/**
|
|
2541
|
-
* The surface's painted-cursor channel, read live because the canvas handle
|
|
2542
|
-
* it lives on arrives a render after this hook runs.
|
|
2543
|
-
*
|
|
2544
|
-
* Given one, a cursor the CSS tier cannot express — sized in world units, or
|
|
2545
|
-
* past the size the browser drops the image at — is published here and drawn
|
|
2546
|
-
* by the painted-cursor layer instead. Without one, such a cursor resolves to
|
|
2547
|
-
* `none` and the pointer shows nothing.
|
|
2548
|
-
*/
|
|
2549
|
-
paintedCursor?: () => PaintedCursorState | undefined;
|
|
2550
|
-
/**
|
|
2551
|
-
* Thunk returning the live `RuleCtx` for the current frame. When supplied,
|
|
2552
|
-
* the dispatcher filters matched candidates by their declared
|
|
2553
|
-
* `Action.eligible` rule (omitted => always eligible). `<SceneCanvas>`
|
|
2554
|
-
* wires this; tests / harnesses without chrome-caps state can omit it.
|
|
2555
|
-
*/
|
|
2556
|
-
getRuleCtx?: () => RuleCtx | undefined;
|
|
2557
|
-
/**
|
|
2558
|
-
* Routing for a canvas hosting more than one view: the non-root dispatch
|
|
2559
|
-
* records to choose between, read fresh per event, and the resolver that
|
|
2560
|
-
* chooses. Omit for a single view — then every event runs on the record the
|
|
2561
|
-
* flat options above describe, which is what they are: view zero.
|
|
2562
|
-
*
|
|
2563
|
-
* A resolved id with no live record falls back to the root, so a view that
|
|
2564
|
-
* unmounts mid-gesture degrades instead of dropping the event.
|
|
2565
|
-
*
|
|
2566
|
-
* Keyboard and paste have no coordinates to resolve; they run on the view
|
|
2567
|
-
* the last coordinate-bearing event resolved to.
|
|
2568
|
-
*
|
|
2569
|
-
* @internal
|
|
2570
|
-
*/
|
|
2571
|
-
views?: {
|
|
2572
|
-
targets: () => readonly DispatcherViewTarget[];
|
|
2573
|
-
resolver: ViewIdResolver;
|
|
2574
|
-
};
|
|
2575
|
-
}
|
|
2576
|
-
/**
|
|
2577
|
-
* Attach the input pipeline to a canvas: DOM pointer, wheel, keyboard and
|
|
2578
|
-
* multitouch listeners in, normalized input events out, routed through the
|
|
2579
|
-
* dispatcher to whichever action a binding names.
|
|
2580
|
-
*
|
|
2581
|
-
* Everything it needs beyond its options — the active tool, the dep registry —
|
|
2582
|
-
* comes from context, so it must be mounted inside `<SceneCanvas>`'s
|
|
2583
|
-
* providers.
|
|
2584
|
-
*/
|
|
2585
|
-
declare function useGestureDispatcher(opts: UseGestureDispatcherOptions): void;
|
|
2586
|
-
|
|
2587
2756
|
/**
|
|
2588
2757
|
* The one place weasel decides whether a frame may run, so that "a loop does no
|
|
2589
2758
|
* work nobody can see" holds by construction rather than by every loop author
|
|
@@ -2687,14 +2856,6 @@ declare function wheelPan(view: View, delta: {
|
|
|
2687
2856
|
/** Pure reducer: the whole wheel convention in one call. */
|
|
2688
2857
|
declare function computeWheelAction(view: View, input: WheelInput, clamp?: ZoomClampOpts, opts?: Pick<WheelPanOpts, 'axis'>): View;
|
|
2689
2858
|
|
|
2690
|
-
/**
|
|
2691
|
-
* Convert client coords to element CSS-pixel coords (relative to the element's
|
|
2692
|
-
* top-left). Apps drawing in CSS-pixel space feed the result directly into
|
|
2693
|
-
* world math when pan/zoom is identity. With pan/zoom, compose this with
|
|
2694
|
-
* your inverse-viewport transform.
|
|
2695
|
-
*/
|
|
2696
|
-
declare function clientToCanvas(canvas: HTMLElement, clientX: number, clientY: number): [number, number];
|
|
2697
|
-
|
|
2698
2859
|
/** Records recent deltas and reports the current velocity, averaged over the
|
|
2699
2860
|
* last 100ms — the throw speed a momentum decay starts from. */
|
|
2700
2861
|
interface VelocityTracker {
|
|
@@ -2734,93 +2895,28 @@ declare function usePinchGesture(canvasRef: React.RefObject<HTMLElement | null>,
|
|
|
2734
2895
|
declare function interpolateView(from: View, to: View): (t: number) => View;
|
|
2735
2896
|
|
|
2736
2897
|
/**
|
|
2737
|
-
*
|
|
2898
|
+
* The routing types that carry an overlay, bound to the kit's `RenderLayer`.
|
|
2738
2899
|
*
|
|
2739
|
-
*
|
|
2740
|
-
*
|
|
2741
|
-
*
|
|
2742
|
-
*
|
|
2743
|
-
*
|
|
2744
|
-
* identity plumbing plus the id check and the cursor resolver.
|
|
2745
|
-
*
|
|
2746
|
-
* It stays a function rather than becoming a spread because the id validation
|
|
2747
|
-
* and the `initScratch` / `cursor` defaults are worth applying uniformly, and
|
|
2748
|
-
* because `Tool.def` gives reflection a handle on the authored form.
|
|
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.
|
|
2749
2905
|
*/
|
|
2750
|
-
declare function defineTool<TScratch = void>(def: ToolDef<TScratch>): Tool<TScratch>;
|
|
2751
2906
|
|
|
2752
|
-
/**
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
* more than the type gymnastics it replaced.
|
|
2764
|
-
*/
|
|
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>;
|
|
2765
2918
|
declare function defineViewportTool<TScratch = void>(def: ViewportToolDef<TScratch>): Tool<TScratch>;
|
|
2766
|
-
|
|
2767
|
-
/** Options for `useTools`: which tools exist, which one starts active, and
|
|
2768
|
-
* which run continuously regardless of the active one. */
|
|
2769
|
-
interface UseToolsOptions {
|
|
2770
|
-
/** Initial active-slot tool id. Must exist in `registry`. */
|
|
2771
|
-
active: string;
|
|
2772
|
-
/** Tools eligible for the active slot or hotkey slot. The keys are the
|
|
2773
|
-
* tool ids; the values are the tool records. A tool with `hotkey` set
|
|
2774
|
-
* is wired into the hotkey slot whenever the engagement state matches. */
|
|
2775
|
-
registry: Record<string, AnyTool>;
|
|
2776
|
-
/** Always-on tools — listen continuously regardless of active slot. */
|
|
2777
|
-
ambient?: AnyTool[];
|
|
2778
|
-
}
|
|
2779
|
-
/** The tool registry's runtime surface: which tool is active, which is
|
|
2780
|
-
* temporarily held by a hotkey, and how to change either. */
|
|
2781
|
-
interface ToolsApi {
|
|
2782
|
-
/** Current active-slot tool id. */
|
|
2783
|
-
active: string;
|
|
2784
|
-
/** Set the active-slot tool. The gesture dispatcher watches the active
|
|
2785
|
-
* tool and cancels any in-flight handle itself. */
|
|
2786
|
-
setActive: (id: string) => void;
|
|
2787
|
-
/** Currently hotkey-engaged tool id (or `null`). Derived as the top of
|
|
2788
|
-
* the hotkey stack for backwards compat with the pre-stack API. */
|
|
2789
|
-
hotkeyEngaged: string | null;
|
|
2790
|
-
/** Engage a hotkey-slot tool by id. */
|
|
2791
|
-
engageHotkey: (id: string) => void;
|
|
2792
|
-
/** Disengage the hotkey-slot tool, if any. */
|
|
2793
|
-
disengageHotkey: () => void;
|
|
2794
|
-
/** All always-on tools, in registration order. */
|
|
2795
|
-
ambient: readonly AnyTool[];
|
|
2796
|
-
/** Full registry — for userland UI (palette buttons, etc.). */
|
|
2797
|
-
registry: Readonly<Record<string, AnyTool>>;
|
|
2798
|
-
/** Returns true if a tool with the given id is in the registry or ambient list. */
|
|
2799
|
-
has(id: string): boolean;
|
|
2800
|
-
/** All overlay layers from currently-engaged tools (active slot, hotkey
|
|
2801
|
-
* slot if engaged, all ambient slot tools) that declare `position`.
|
|
2802
|
-
* Filters out tools with no `overlay` field. Order: active, then hotkey
|
|
2803
|
-
* (if engaged), then ambient (registration order). */
|
|
2804
|
-
getActiveOverlays(position?: OverlayPosition): RenderLayer<unknown>[];
|
|
2805
|
-
}
|
|
2806
|
-
/**
|
|
2807
|
-
* Manages the active tool and hotkey slot.
|
|
2808
|
-
*
|
|
2809
|
-
* A thin shim over {@link useContributions}: the `registry` / `ambient`
|
|
2810
|
-
* arguments are restated as declared eligibility (`focus` / `always`), and
|
|
2811
|
-
* assembly happens in one place for tools and non-tool contributions alike.
|
|
2812
|
-
*
|
|
2813
|
-
* Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /
|
|
2814
|
-
* `<SceneCanvas>`, which mount one internally) in scope: active/hotkey state
|
|
2815
|
-
* lives in the context so the gesture dispatcher and any sibling
|
|
2816
|
-
* `useTools` calls all read the same source of truth.
|
|
2817
|
-
*
|
|
2818
|
-
* **First-mount-wins semantics**: if `opts.active` differs from the context
|
|
2819
|
-
* default (`'select'`) on first mount, `useTools` pushes `opts.active` to
|
|
2820
|
-
* the context. Subsequent mounts respect whatever the context currently
|
|
2821
|
-
* holds (the first caller wins).
|
|
2822
|
-
*/
|
|
2823
|
-
declare function useTools(opts: UseToolsOptions): ToolsApi;
|
|
2919
|
+
declare const useTools: (opts: UseToolsOptions) => ToolsApi;
|
|
2824
2920
|
|
|
2825
2921
|
/** Options for `useKeybindings`. */
|
|
2826
2922
|
interface UseKeybindingsOptions {
|
|
@@ -2876,6 +2972,9 @@ interface ToolPrefBase<K extends string, Value> {
|
|
|
2876
2972
|
}
|
|
2877
2973
|
/** How a schema-driven UI should present a number pref. */
|
|
2878
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';
|
|
2879
2978
|
/** How a schema-driven UI should present a boolean pref. */
|
|
2880
2979
|
type ToolPrefBooleanControl = 'checkbox' | 'switch' | 'toggle';
|
|
2881
2980
|
/** How a schema-driven UI should present a string pref. */
|
|
@@ -2890,7 +2989,21 @@ interface ToolPrefNumberUnit {
|
|
|
2890
2989
|
fromDisplay: (display: number) => number;
|
|
2891
2990
|
/** Shown after the input, e.g. `'°'`. */
|
|
2892
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>>;
|
|
2893
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;
|
|
2894
3007
|
/** A numeric pref, optionally bounded and stepped, and optionally stored in a
|
|
2895
3008
|
* different unit from the one shown. */
|
|
2896
3009
|
interface ToolPrefNumber extends ToolPrefBase<'number', number> {
|
|
@@ -2898,6 +3011,7 @@ interface ToolPrefNumber extends ToolPrefBase<'number', number> {
|
|
|
2898
3011
|
max?: number;
|
|
2899
3012
|
step?: number;
|
|
2900
3013
|
control?: ToolPrefNumberControl;
|
|
3014
|
+
format?: ToolPrefNumberFormat;
|
|
2901
3015
|
unit?: ToolPrefNumberUnit;
|
|
2902
3016
|
}
|
|
2903
3017
|
/** An on/off pref. */
|
|
@@ -3045,21 +3159,144 @@ interface ToolPrefGroup {
|
|
|
3045
3159
|
children: Record<string, ToolPrefLeaf | ToolPrefGroup>;
|
|
3046
3160
|
}
|
|
3047
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
|
+
|
|
3048
3285
|
/** Options for `useSelectTool`: how a point resolves to nodes, how a click
|
|
3049
3286
|
* chooses among them, and the appearance of the marquee. */
|
|
3050
3287
|
interface UseSelectToolOptions<TPose> {
|
|
3051
3288
|
/** Return ids of all objects whose painted body covers (worldX, worldY).
|
|
3052
3289
|
* Order doesn't matter — the tool collapses parent/child overlap via
|
|
3053
|
-
* `pickTopMostHit`. When omitted, defaults to
|
|
3054
|
-
*
|
|
3055
|
-
*
|
|
3056
|
-
* (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). */
|
|
3057
3293
|
pickEvery?: (worldX: number, worldY: number) => string[];
|
|
3058
3294
|
/** Optional alt-aware selection-update hit returning the single id the
|
|
3059
3295
|
* click should act on. */
|
|
3060
3296
|
pickBest?: (worldX: number, worldY: number, alt: boolean, selection: readonly string[]) => string | null;
|
|
3061
|
-
/**
|
|
3062
|
-
|
|
3297
|
+
/** How to read poses for the default `pickEvery`. Default
|
|
3298
|
+
* `AUTO_POSE_DESCRIPTOR`. */
|
|
3299
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
3063
3300
|
/**
|
|
3064
3301
|
* How the default `pickEvery` decides a **leaf** node covers the pointer.
|
|
3065
3302
|
* Ignored when `pickEvery` is supplied.
|
|
@@ -3090,6 +3327,13 @@ interface UseSelectToolOptions<TPose> {
|
|
|
3090
3327
|
* Without some slop a hairline outline is an unhittable target.
|
|
3091
3328
|
*/
|
|
3092
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;
|
|
3093
3337
|
/** Move-action options. The move gesture is dispatcher-routed,
|
|
3094
3338
|
* so only `behaviors` is consumed here — threaded into the move binding's
|
|
3095
3339
|
* `opts.behaviors`. Other `UseMoveOptions` fields are accepted for API shape
|
|
@@ -3650,6 +3894,266 @@ interface PencilPoint {
|
|
|
3650
3894
|
*/
|
|
3651
3895
|
declare function usePencilTool(): Tool<null>;
|
|
3652
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
|
+
|
|
3653
4157
|
/** Standard slot names — render in this canonical order.
|
|
3654
4158
|
* `cellHighlight` is internal: emitted from the `grid` slot's nested
|
|
3655
4159
|
* `highlight` config, not a top-level layer key. */
|
|
@@ -3667,6 +4171,108 @@ interface CustomLayerEntry {
|
|
|
3667
4171
|
before?: StandardSlotName | (string & {});
|
|
3668
4172
|
}
|
|
3669
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;
|
|
4262
|
+
|
|
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;
|
|
4275
|
+
}
|
|
3670
4276
|
/**
|
|
3671
4277
|
* The **base imperative ref handle** shared by the canvas components. For
|
|
3672
4278
|
* `<SceneCanvas>` refs use {@link SceneCanvasApi} (this type plus the
|
|
@@ -3700,8 +4306,23 @@ interface CanvasExtensionApi {
|
|
|
3700
4306
|
*
|
|
3701
4307
|
* Under `paintInto` this is the caller's shared canvas, which co-tenant
|
|
3702
4308
|
* panes also paint into: its rect is the whole surface, not this pane's, so
|
|
3703
|
-
* 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}. */
|
|
3704
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
|
+
};
|
|
3705
4326
|
requestRedraw(): void;
|
|
3706
4327
|
/**
|
|
3707
4328
|
* Run `fn` after every paint, on the frame that painted — for chrome that
|
|
@@ -3786,6 +4407,10 @@ interface CanvasExtensionApi {
|
|
|
3786
4407
|
x: number;
|
|
3787
4408
|
y: number;
|
|
3788
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;
|
|
3789
4414
|
}
|
|
3790
4415
|
/**
|
|
3791
4416
|
* The imperative ref handle for `<SceneCanvas>` — everything on
|
|
@@ -3809,6 +4434,16 @@ interface SceneCanvasApi extends CanvasExtensionApi {
|
|
|
3809
4434
|
/** Cancel a camera animation. The view stays where it is. */
|
|
3810
4435
|
stopViewAnimation(): void;
|
|
3811
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;
|
|
3812
4447
|
}
|
|
3813
4448
|
|
|
3814
4449
|
/**
|
|
@@ -4016,7 +4651,10 @@ interface CanvasHelpers<TPose> extends CanvasViewHelpers<TPose>, CanvasSurfaceHe
|
|
|
4016
4651
|
* Built-in entries (`kit:text`, `kit:path`, `kit:rect-fallback`) are
|
|
4017
4652
|
* registered at module load. Consumer entries added via
|
|
4018
4653
|
* `registerNodeShape` join the chain; the first entry whose
|
|
4019
|
-
* `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.
|
|
4020
4658
|
*
|
|
4021
4659
|
* Two priority tiers:
|
|
4022
4660
|
* - `'high'` — checked before all `'normal'` entries. Use this to
|
|
@@ -4050,6 +4688,10 @@ interface NodePaintCtx {
|
|
|
4050
4688
|
* the wrapper hands such a node the caller's own ctx untouched. `null`
|
|
4051
4689
|
* means the node derives but has nothing to draw. */
|
|
4052
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;
|
|
4053
4695
|
}
|
|
4054
4696
|
/**
|
|
4055
4697
|
* Per-node draw function — the scene-slot `drawOne` signature shared by
|
|
@@ -4069,7 +4711,9 @@ interface NodeShapeEntry<TData = unknown, TPose = unknown> {
|
|
|
4069
4711
|
* something descriptive: `'kit:text'`, `'app:image'`, etc. */
|
|
4070
4712
|
id: string;
|
|
4071
4713
|
/** Returns true when this painter renders the node. The first matching
|
|
4072
|
-
* 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. */
|
|
4073
4717
|
matches(node: Node$1<TData, string, TPose>): boolean;
|
|
4074
4718
|
/** Emits the draw commands for the node's primary visual. `ctx` is an
|
|
4075
4719
|
* optional per-call paint context (see `NodePaintCtx`); painters that
|
|
@@ -4227,11 +4871,9 @@ declare function getNodeShapes(): readonly NodeShapeEntry[];
|
|
|
4227
4871
|
* `createSelectionOverlayLayer` is a thin convenience that returns a single
|
|
4228
4872
|
* `RenderLayer` whose draw runs the outline pass then the handles pass.
|
|
4229
4873
|
*
|
|
4230
|
-
* **Pose shape:** TPose is generic; callers
|
|
4231
|
-
*
|
|
4232
|
-
*
|
|
4233
|
-
* `boundsOfPath`. Container ids reduce via `unionAABB` over the projected
|
|
4234
|
-
* 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.
|
|
4235
4877
|
*/
|
|
4236
4878
|
|
|
4237
4879
|
/** Options for `composeSelectionPose`. */
|
|
@@ -4253,19 +4895,8 @@ interface ComposeSelectionPoseOpts<TPose> {
|
|
|
4253
4895
|
} | null;
|
|
4254
4896
|
/** Fallback pose lookup (typically the stored/committed pose). */
|
|
4255
4897
|
getStoredPose: (id: string) => TPose;
|
|
4256
|
-
/**
|
|
4257
|
-
|
|
4258
|
-
* into a single union AABB. Defaults to the identity — rect-shaped poses
|
|
4259
|
-
* (`{x, y, width, height}`) need no override. For `Path` poses pass
|
|
4260
|
-
* `boundsOfPath`.
|
|
4261
|
-
*/
|
|
4262
|
-
getBounds?: (pose: TPose) => Bounds;
|
|
4263
|
-
/**
|
|
4264
|
-
* Wrap an AABB back into a TPose. Called only when the resolver collapses
|
|
4265
|
-
* a container's leaves into a single union AABB. Defaults to the identity —
|
|
4266
|
-
* for `Path` poses pass `(b) => ({ kind: 'rect', ...b })`.
|
|
4267
|
-
*/
|
|
4268
|
-
fromBounds?: (bounds: Bounds) => TPose;
|
|
4898
|
+
/** How to read poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
4899
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
4269
4900
|
/** Walk a container's direct children (e.g. `scene.childrenOf`). With
|
|
4270
4901
|
* `isContainer`, a selected container resolves to the union AABB of its
|
|
4271
4902
|
* transitive leaf poses instead of its own stored pose. */
|
|
@@ -4285,12 +4916,8 @@ declare function composeSelectionPose<TPose>(opts: ComposeSelectionPoseOpts<TPos
|
|
|
4285
4916
|
* declared on {@link SelectionOverlayLayerOpts}, which makes both optional —
|
|
4286
4917
|
* omitted, they come off the draw envelope. */
|
|
4287
4918
|
interface SelectionLayerCommon<TPose> {
|
|
4288
|
-
/**
|
|
4289
|
-
|
|
4290
|
-
* poses (`{x, y, width, height}`) need no override. For `Path` poses pass
|
|
4291
|
-
* `boundsOfPath`.
|
|
4292
|
-
*/
|
|
4293
|
-
getBounds?: (pose: TPose) => Bounds;
|
|
4919
|
+
/** How to read poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
4920
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
4294
4921
|
/** Walk a container's direct children (e.g. `scene.childrenOf`). When
|
|
4295
4922
|
* supplied with `isContainer`, any id that resolves to a container is
|
|
4296
4923
|
* rendered using the union bounds of all its transitive leaves. */
|
|
@@ -4388,6 +5015,10 @@ interface HierarchicalAdapter<TNode, TPose> {
|
|
|
4388
5015
|
getNode(id: string): TNode | undefined;
|
|
4389
5016
|
getChildren(parentId: string | null): readonly string[];
|
|
4390
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;
|
|
4391
5022
|
}
|
|
4392
5023
|
|
|
4393
5024
|
/**
|
|
@@ -4567,16 +5198,15 @@ interface CanvasProps<TNode extends {
|
|
|
4567
5198
|
*/
|
|
4568
5199
|
selection?: SelectionApi;
|
|
4569
5200
|
/**
|
|
4570
|
-
*
|
|
4571
|
-
* the
|
|
4572
|
-
* 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.
|
|
4573
5203
|
* Defaults to the rect identity (`AUTO_POSE_DESCRIPTOR`).
|
|
4574
5204
|
*
|
|
4575
5205
|
* This is a math helper, not a scene-shaped concern — it converts a pose
|
|
4576
5206
|
* value to an AABB and extracts rotation for the selection chrome. Bare-
|
|
4577
5207
|
* Canvas consumers that use a non-rect pose type should supply this.
|
|
4578
5208
|
*/
|
|
4579
|
-
|
|
5209
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
4580
5210
|
/**
|
|
4581
5211
|
* Used by `PickHud` to display the list of ids under the cursor.
|
|
4582
5212
|
* NOT used for tool routing — see `getNodeAtPoint` for that.
|
|
@@ -4586,7 +5216,7 @@ interface CanvasProps<TNode extends {
|
|
|
4586
5216
|
pickEvery?: (worldX: number, worldY: number) => string | string[] | null;
|
|
4587
5217
|
/**
|
|
4588
5218
|
* Override for committed bounds lookup. When supplied, takes precedence over
|
|
4589
|
-
* the `
|
|
5219
|
+
* the `poseDescriptor`-derived fallback. Used by the selection overlay, the
|
|
4590
5220
|
* multi-select union AABB, and `helpersRef.getEffectiveBounds`. Optional —
|
|
4591
5221
|
* bare-Canvas consumers that use a custom bounds shape should supply this;
|
|
4592
5222
|
* `<SceneCanvas>` derives it from its scene adapter and passes it via the
|
|
@@ -4851,6 +5481,12 @@ interface ReorderAdapter {
|
|
|
4851
5481
|
* touch an adapter directly. */
|
|
4852
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>>> & {
|
|
4853
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;
|
|
4854
5490
|
getSelection(): string[];
|
|
4855
5491
|
setSelection(ids: string[]): void;
|
|
4856
5492
|
insertNode(node: Node$1<TData, TLayer, TPose>, index?: number): void;
|
|
@@ -4890,10 +5526,8 @@ interface SceneToAdapterOptions<TData, TLayer extends string, TPose> {
|
|
|
4890
5526
|
* fine for read-only or selection-less canvases, but the marquee gesture
|
|
4891
5527
|
* won't update any external selection state. */
|
|
4892
5528
|
selection?: SceneAdapterSelection;
|
|
4893
|
-
/**
|
|
4894
|
-
|
|
4895
|
-
* poses. */
|
|
4896
|
-
poseBounds?: (pose: TPose) => Bounds;
|
|
5529
|
+
/** How to read and rewrite this scene's poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
5530
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
4897
5531
|
/** Layout strategies keyed by container node id. When a container is
|
|
4898
5532
|
* configured here, `move` runs its layout-aware pass on drag (reflow on
|
|
4899
5533
|
* enter, reflow leftovers on exit, reparent + write reflowed poses on
|
|
@@ -4901,14 +5535,16 @@ interface SceneToAdapterOptions<TData, TLayer extends string, TPose> {
|
|
|
4901
5535
|
* either a static map, or a `getLayout(id)` function for dynamic
|
|
4902
5536
|
* resolution. */
|
|
4903
5537
|
layouts?: Record<string, LayoutStrategy<TPose>> | ((containerId: string) => LayoutStrategy<TPose> | null);
|
|
4904
|
-
/** When
|
|
4905
|
-
*
|
|
4906
|
-
*
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
*
|
|
4910
|
-
*
|
|
4911
|
-
|
|
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>;
|
|
4912
5548
|
}
|
|
4913
5549
|
/** Derive the adapter for a scene. Reads go straight to the scene; writes are
|
|
4914
5550
|
* ops applied through its history, so anything done through the adapter is
|
|
@@ -4933,27 +5569,17 @@ declare function useSceneAdapter<TData, TLayer extends string, TPose>(scene: Sce
|
|
|
4933
5569
|
* Consumers should import from here directly; `rotate.ts` re-exports the
|
|
4934
5570
|
* same symbols for back-compat. */
|
|
4935
5571
|
|
|
4936
|
-
/** Projects a pose to and from a rotated bounding box, so the rotate action
|
|
4937
|
-
* can work on pose shapes that carry rotation differently. */
|
|
4938
|
-
interface RotateGeometry<TPose> {
|
|
4939
|
-
getRotatedBounds(pose: TPose): RotatedPose;
|
|
4940
|
-
/** Write a new rotation back into the pose; bounds stay the same. */
|
|
4941
|
-
withRotation(pose: TPose, rotation: number): TPose;
|
|
4942
|
-
}
|
|
4943
5572
|
/** Options for the `rotate` action. */
|
|
4944
5573
|
interface UseRotateOptions<TPose> {
|
|
4945
5574
|
/** Behaviors are typed against the pose shape; the kit ships none yet
|
|
4946
5575
|
* (rotation snap behaviors are deferred). For non-rect TPose, behaviors
|
|
4947
|
-
* are typed `never`
|
|
5576
|
+
* are typed `never` for a pose without a numeric `rotation`. */
|
|
4948
5577
|
behaviors?: TPose extends RotatedPose ? RotateBehavior<TPose>[] : never;
|
|
4949
5578
|
rotateLabel?: string;
|
|
4950
5579
|
/** Reserved; rotate is never transient in practice. Ignored. */
|
|
4951
5580
|
transient?: boolean;
|
|
4952
5581
|
onGestureStart?: (id: string) => void;
|
|
4953
5582
|
onGestureEnd?: (committed: boolean) => void;
|
|
4954
|
-
/** Project pose ↔ rotated bounds. Defaults to the identity for
|
|
4955
|
-
* `RotatedPose`. Required for non-rect TPose (e.g. a rotated path). */
|
|
4956
|
-
geometry?: RotateGeometry<TPose>;
|
|
4957
5583
|
/** Optional debug sink. When supplied, records the rotation-handle
|
|
4958
5584
|
* position + circular hitbox at gesture start. Tree-shakes via
|
|
4959
5585
|
* optional-chain when omitted. */
|
|
@@ -4974,60 +5600,95 @@ interface UseRotateOptions<TPose> {
|
|
|
4974
5600
|
pivot?: 'each' | 'union';
|
|
4975
5601
|
}
|
|
4976
5602
|
|
|
4977
|
-
/** A rect on the surface, in CSS pixels from the canvas top-left. */
|
|
4978
|
-
interface ViewRect {
|
|
4979
|
-
x: number;
|
|
4980
|
-
y: number;
|
|
4981
|
-
w: number;
|
|
4982
|
-
h: number;
|
|
4983
|
-
}
|
|
4984
|
-
/** Props for `<CanvasView>`. @experimental */
|
|
4985
|
-
interface CanvasViewProps {
|
|
4986
|
-
/** Identifies the view to the surface and to input routing. Must be unique
|
|
4987
|
-
* among the views on one canvas. */
|
|
4988
|
-
id: string;
|
|
4989
|
-
/** Where this view paints, recomputed every frame so the rect can track the
|
|
4990
|
-
* outer camera. A plain rect is accepted for a fixed panel. */
|
|
4991
|
-
bounds: ViewRect | ((outer: View, dims: Dims) => ViewRect);
|
|
4992
|
-
/** Camera. Supply this to control it; otherwise the view keeps its own,
|
|
4993
|
-
* seeded from `defaultView`. `onViewChange` fires either way. */
|
|
4994
|
-
view?: View;
|
|
4995
|
-
defaultView?: View;
|
|
4996
|
-
onViewChange?: (v: View) => void;
|
|
4997
|
-
/** Pan limits, applied to every camera change the same way `<Canvas>`
|
|
4998
|
-
* applies its own. */
|
|
4999
|
-
viewBounds?: Bounds;
|
|
5000
|
-
/** Which of the surface's layers this view paints. Defaults to all of them —
|
|
5001
|
-
* the same content through a second camera. */
|
|
5002
|
-
layers?: (surface: readonly RenderLayer<unknown>[]) => readonly RenderLayer<unknown>[];
|
|
5003
|
-
/** Opaque ground painted before the source layers, so the surface does not
|
|
5004
|
-
* show through where the inner camera sees nothing. */
|
|
5005
|
-
background?: string;
|
|
5006
|
-
/** Paint and hit order. Defaults to `Infinity` — after every view the
|
|
5007
|
-
* surface declared as a prop. */
|
|
5008
|
-
order?: number;
|
|
5009
|
-
/** Label for debug overlays. Defaults to the id. */
|
|
5010
|
-
label?: string;
|
|
5011
|
-
/** A selection of this view's own, which actions dispatched inside it read
|
|
5012
|
-
* and write instead of the surface's. Omit both this and
|
|
5013
|
-
* `selectionOptions` and the view shares the surface's selection — the
|
|
5014
|
-
* default, so undo restores one selection rather than N. */
|
|
5015
|
-
selection?: SelectionApi;
|
|
5016
|
-
/** Opts this view into owning a selection, configured thus. Ignored when
|
|
5017
|
-
* `selection` is supplied. */
|
|
5018
|
-
selectionOptions?: UseSelectionOptions;
|
|
5019
|
-
}
|
|
5020
5603
|
/**
|
|
5021
|
-
*
|
|
5604
|
+
* The kit's built-in shape kinds — one table, every other spelling derived.
|
|
5022
5605
|
*
|
|
5023
|
-
*
|
|
5024
|
-
*
|
|
5025
|
-
*
|
|
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.
|
|
5026
5611
|
*
|
|
5027
|
-
*
|
|
5028
|
-
*
|
|
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.
|
|
5029
5615
|
*/
|
|
5030
|
-
|
|
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[];
|
|
5031
5692
|
|
|
5032
5693
|
/** Per-tool option overrides for the built-in shape/lasso tools.
|
|
5033
5694
|
* Each entry is a narrow subset of the underlying hook's options surface
|
|
@@ -5230,7 +5891,7 @@ interface SceneCanvasHit {
|
|
|
5230
5891
|
/** Props for `<SceneCanvas>`. Most are optional: a scene is the only thing it
|
|
5231
5892
|
* truly needs, and everything else — tools, layers, selection handling,
|
|
5232
5893
|
* layouts, animation — layers onto sensible defaults. */
|
|
5233
|
-
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'> & {
|
|
5234
5895
|
/** A `Scene` (typically from `useScene`) — or a `SerializedScene`
|
|
5235
5896
|
* JSON object, which SceneCanvas bakes into a Scene internally on
|
|
5236
5897
|
* first render. The serialized form is read once; subsequent
|
|
@@ -5258,6 +5919,12 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5258
5919
|
* to `sceneToAdapter` so `useMove`'s layout pass runs on configured
|
|
5259
5920
|
* containers (reflow on enter, reparent + reflow on commit). */
|
|
5260
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'];
|
|
5261
5928
|
/**
|
|
5262
5929
|
* Optional consumer seam for eager geometry sync: lets pose-transform
|
|
5263
5930
|
* actions (move, resize, nudge, flip — NOT rotate) also rewrite a node's
|
|
@@ -5294,6 +5961,10 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5294
5961
|
* it with extras is what needs the memo.)
|
|
5295
5962
|
*/
|
|
5296
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>;
|
|
5297
5968
|
geometry?: {
|
|
5298
5969
|
/** Hit-test override. Return the topmost id, the full back-to-front hit
|
|
5299
5970
|
* stack (`string[]`), or `null` for empty space. The stack form lets a
|
|
@@ -5577,9 +6248,9 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5577
6248
|
/**
|
|
5578
6249
|
* Optional animator to bind for per-frame redraws. When supplied,
|
|
5579
6250
|
* SceneCanvas subscribes to `animator.onTick` and requests a redraw on
|
|
5580
|
-
* every active animation frame
|
|
5581
|
-
*
|
|
5582
|
-
*
|
|
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
|
|
5583
6254
|
* mutations trigger repaints automatically, but `colorOverrides` writes
|
|
5584
6255
|
* do not.
|
|
5585
6256
|
*
|
|
@@ -5702,6 +6373,25 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5702
6373
|
* Defaults to `() => 1` (no effect).
|
|
5703
6374
|
*/
|
|
5704
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[];
|
|
5705
6395
|
/**
|
|
5706
6396
|
* Optional per-id pointer-interactivity predicate. When supplied, ids
|
|
5707
6397
|
* for which the predicate returns `false` are excluded from hit-test
|
|
@@ -6008,6 +6698,194 @@ declare const defaultNodeProperties: readonly NodePropertiesEntry[];
|
|
|
6008
6698
|
*/
|
|
6009
6699
|
declare const inferredNodeProperties: readonly NodePropertiesEntry[];
|
|
6010
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
|
+
|
|
6011
6889
|
/**
|
|
6012
6890
|
* `renderSceneToCanvas` — substrate for detached, read-only scene views
|
|
6013
6891
|
* (`<SceneViewCanvas>` / `<MinimapCanvas>`). Given a `<canvas>`, a `Scene`,
|
|
@@ -6027,6 +6905,18 @@ declare const inferredNodeProperties: readonly NodePropertiesEntry[];
|
|
|
6027
6905
|
* in sync by hand where it matters (DPR handling, viewToMat3 wrap).
|
|
6028
6906
|
*/
|
|
6029
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
|
+
}
|
|
6030
6920
|
/** What to draw into an existing canvas: the scene, the view, and the same
|
|
6031
6921
|
* painting hooks `<SceneCanvas>` takes. */
|
|
6032
6922
|
interface RenderSceneToCanvasArgs<TData, TLayer extends string, TPose> {
|
|
@@ -6056,6 +6946,13 @@ interface RenderSceneToCanvasArgs<TData, TLayer extends string, TPose> {
|
|
|
6056
6946
|
* `alphaFor`. Pass the same function the main canvas uses to keep a
|
|
6057
6947
|
* scoping-dim treatment consistent across both. Defaults to `() => 1`. */
|
|
6058
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;
|
|
6059
6956
|
/** Optional device-pixel ratio. Defaults to `window.devicePixelRatio || 1`
|
|
6060
6957
|
* when available, otherwise 1. Tests typically pin this to 1 or 2. */
|
|
6061
6958
|
dpr?: number;
|
|
@@ -6077,13 +6974,21 @@ interface RenderSceneToCanvasArgs<TData, TLayer extends string, TPose> {
|
|
|
6077
6974
|
* emit unrotated geometry and let the pose drive it.
|
|
6078
6975
|
*
|
|
6079
6976
|
* Output shape follows `buildSceneTree`: one group per **visible** layer, in
|
|
6080
|
-
* 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.
|
|
6081
6979
|
*
|
|
6082
6980
|
* Exported for tests and for callers that want to render into something
|
|
6083
6981
|
* other than a real `<canvas>` (e.g. an offscreen renderer or a
|
|
6084
6982
|
* snapshot fixture).
|
|
6085
6983
|
*/
|
|
6086
|
-
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[];
|
|
6087
6992
|
/**
|
|
6088
6993
|
* Render one frame of `scene` at `view` into `canvas`. See module docstring
|
|
6089
6994
|
* for the design context.
|
|
@@ -6127,6 +7032,15 @@ interface SceneViewCanvasProps<TData, TLayer extends string, TPose> {
|
|
|
6127
7032
|
* `alphaFor`. Pass the same function the main canvas uses to keep a
|
|
6128
7033
|
* scoping-dim treatment consistent across both. Defaults to `() => 1`. */
|
|
6129
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;
|
|
6130
7044
|
/** Optional CSS class for sizing / positioning the `<canvas>`. The kit
|
|
6131
7045
|
* does not emit inline styles for layout — use a class. */
|
|
6132
7046
|
className?: string;
|
|
@@ -6160,7 +7074,7 @@ declare function sceneSelectionStore(scene: {
|
|
|
6160
7074
|
* registry passed in `options`. Throws on unknown version, unknown registry
|
|
6161
7075
|
* keys, or invalid scene shape (cross-layer subtrees, unknown layer ids).
|
|
6162
7076
|
* Loaded scenes start with empty history — undo/redo is NOT serialized. */
|
|
6163
|
-
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?: {
|
|
6164
7078
|
registry?: SceneRegistry<TPose>;
|
|
6165
7079
|
historyLimit?: number;
|
|
6166
7080
|
coalesceWindowMs?: number;
|
|
@@ -6206,18 +7120,116 @@ declare function useScene<TItem extends {
|
|
|
6206
7120
|
declare function useScene<TData, TLayer extends string, TPose = RectPose>(options: UseSceneOptions<TData, TLayer, TPose>): Scene<TData, TLayer, TPose>;
|
|
6207
7121
|
|
|
6208
7122
|
/**
|
|
6209
|
-
*
|
|
7123
|
+
* Build a {@link PoseOverrides} map.
|
|
7124
|
+
*
|
|
7125
|
+
* `getNode` resolves an id to the node object the painter memo is keyed on —
|
|
7126
|
+
* the only thing this module needs from the scene, and the reason it doesn't
|
|
7127
|
+
* import one. `onInvalidate` lets the scene invalidate derived nodes from the
|
|
7128
|
+
* same chokepoint.
|
|
7129
|
+
*/
|
|
7130
|
+
declare function createPoseOverrides<TPose>(getNode: (id: NodeId) => {
|
|
7131
|
+
data?: unknown;
|
|
7132
|
+
} | undefined, onInvalidate?: (id: NodeId) => void): PoseOverrides<TPose>;
|
|
7133
|
+
|
|
7134
|
+
/** The subset of a node this module reads. Structural so a `Node` satisfies
|
|
7135
|
+
* it without importing the full generic shape. */
|
|
7136
|
+
interface PosedNode<TPose> {
|
|
7137
|
+
id: NodeId;
|
|
7138
|
+
kind?: 'leaf' | 'container';
|
|
7139
|
+
pose: TPose;
|
|
7140
|
+
/** Read only by the memo, which keys on its reference alongside the pose. */
|
|
7141
|
+
data?: unknown;
|
|
7142
|
+
dependsOn?: readonly NodeId[] | 'children';
|
|
7143
|
+
derivePose?: (node: never, deps: readonly (DerivedDep<TPose> | undefined)[]) => TPose | null;
|
|
7144
|
+
/** Read only when something asks a dependency for its `path`. */
|
|
7145
|
+
derivePath?: (node: never, deps: readonly (DerivedDep<TPose> | undefined)[]) => Path | null;
|
|
7146
|
+
}
|
|
7147
|
+
/** What resolving a pose needs: the overrides, and enough of the scene to
|
|
7148
|
+
* reach a node's dependencies. A `Scene` satisfies it. */
|
|
7149
|
+
interface PoseSource<TPose> {
|
|
7150
|
+
readonly overrides: Pick<PoseOverrides<TPose>, 'get'>;
|
|
7151
|
+
get(id: NodeId): PosedNode<TPose> | undefined;
|
|
7152
|
+
childrenOf(id: NodeId): readonly NodeId[];
|
|
7153
|
+
}
|
|
7154
|
+
/**
|
|
7155
|
+
* The pose `node` computes from its dependencies, or `null` when it derives
|
|
7156
|
+
* nothing — it has no `derivePose`, nothing to derive from, or its
|
|
7157
|
+
* `derivePose` returned `null`.
|
|
7158
|
+
*
|
|
7159
|
+
* A dependency is read through {@link effectivePose}, so a group of groups
|
|
7160
|
+
* resolves bottom-up and a dragged dependency's override reaches the
|
|
7161
|
+
* derivation the same frame it is published.
|
|
7162
|
+
*/
|
|
7163
|
+
declare function derivedPose<TPose>(source: PoseSource<TPose>, node: PosedNode<TPose>): TPose | null;
|
|
7164
|
+
/**
|
|
7165
|
+
* `id` as a derivation sees it: the node, the pose it is painted at, and the
|
|
7166
|
+
* path it derives.
|
|
7167
|
+
*
|
|
7168
|
+
* The pose is resolved eagerly — every derivation reads it — and the path
|
|
7169
|
+
* lazily, because most do not and resolving a route costs a router run. Both
|
|
7170
|
+
* resolve *through* this function, so a dependency that is itself derived is
|
|
7171
|
+
* resolved before it is read.
|
|
7172
|
+
*/
|
|
7173
|
+
declare function derivedDepOf<TPose>(source: PoseSource<TPose>, id: NodeId): DerivedDep<TPose> | undefined;
|
|
7174
|
+
/**
|
|
7175
|
+
* The pose the *document* says `node` is at: derived when it derives, else
|
|
7176
|
+
* authored. `effectivePose` minus the override step.
|
|
7177
|
+
*
|
|
7178
|
+
* For a reader that must not see an in-flight gesture — an action capturing
|
|
7179
|
+
* the `from` of a transform op, a placement computed against a sibling. A
|
|
7180
|
+
* derived pose belongs here and an override does not: derivation is what the
|
|
7181
|
+
* document means, an override is what one gesture is currently showing.
|
|
7182
|
+
*/
|
|
7183
|
+
declare function documentPose<TPose>(source: PoseSource<TPose>, node: PosedNode<TPose>): TPose;
|
|
7184
|
+
/**
|
|
7185
|
+
* The pose to draw, pick and measure `node` at.
|
|
6210
7186
|
*
|
|
6211
|
-
*
|
|
6212
|
-
*
|
|
6213
|
-
|
|
6214
|
-
|
|
7187
|
+
* The one rule. Every pose a reader acts on comes from here: the three render
|
|
7188
|
+
* walks, the pick walk, the adapters tools and actions commit through.
|
|
7189
|
+
*/
|
|
7190
|
+
declare function effectivePose<TPose>(source: PoseSource<TPose>, node: PosedNode<TPose>): TPose;
|
|
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
|
+
|
|
7211
|
+
/** Registry key for {@link unionOfChildren}. */
|
|
7212
|
+
declare const UNION_OF_CHILDREN = "kit:unionOfChildren";
|
|
7213
|
+
/**
|
|
7214
|
+
* A container's pose as the envelope of what it holds — `unionAABB`, so a
|
|
7215
|
+
* rotated member contributes the extent of its ink rather than its unrotated
|
|
7216
|
+
* box. Paired with `dependsOn: 'children'`, this is what makes a group's
|
|
7217
|
+
* bounds track its members instead of freezing at the moment it was made.
|
|
6215
7218
|
*
|
|
6216
|
-
*
|
|
6217
|
-
*
|
|
7219
|
+
* Returns `null` for an emptied container, which falls back to its authored
|
|
7220
|
+
* pose — the group stays where the last member left it rather than collapsing
|
|
7221
|
+
* to a zero box at the origin.
|
|
6218
7222
|
*
|
|
6219
|
-
*
|
|
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.
|
|
6220
7229
|
*/
|
|
7230
|
+
declare function unionOfChildren<TPose>(_node: unknown, deps: readonly ({
|
|
7231
|
+
pose: TPose;
|
|
7232
|
+
} | undefined)[]): TPose | null;
|
|
6221
7233
|
|
|
6222
7234
|
/**
|
|
6223
7235
|
* Fallback view returned when there is nothing to fit (empty scene, etc.).
|
|
@@ -6227,7 +7239,7 @@ declare const FALLBACK_FIT_VIEW: View;
|
|
|
6227
7239
|
/**
|
|
6228
7240
|
* Fit policy for `<MinimapCanvas>` / `computeFitView`.
|
|
6229
7241
|
*
|
|
6230
|
-
* - `"scene"` — union of leaf-node pose AABBs (via
|
|
7242
|
+
* - `"scene"` — union of leaf-node pose AABBs (via the pose descriptor).
|
|
6231
7243
|
* - `{ kind: "world", rect }` — caller-supplied world rect.
|
|
6232
7244
|
* - `(scene, dims) => View` — caller derives the view directly.
|
|
6233
7245
|
*/
|
|
@@ -6255,7 +7267,7 @@ interface ComputeFitViewOptions {
|
|
|
6255
7267
|
* is centered with `padding` (default 8) on each side. The smaller-axis
|
|
6256
7268
|
* fit ratio wins, so the whole rect is visible.
|
|
6257
7269
|
*
|
|
6258
|
-
* - `fit === "scene"`: union AABB of leaf-node poses via `
|
|
7270
|
+
* - `fit === "scene"`: union AABB of leaf-node poses via `descriptor`.
|
|
6259
7271
|
* Empty scene → {@link FALLBACK_FIT_VIEW}.
|
|
6260
7272
|
* - `fit` is `{ kind: "world", rect }`: fit `rect`. A degenerate rect
|
|
6261
7273
|
* (zero or negative area) falls back to identity scale centered on the
|
|
@@ -6263,7 +7275,7 @@ interface ComputeFitViewOptions {
|
|
|
6263
7275
|
* - `fit` is a function: called with `(scene, dims)`; its return is
|
|
6264
7276
|
* passed through unchanged.
|
|
6265
7277
|
*/
|
|
6266
|
-
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;
|
|
6267
7279
|
/**
|
|
6268
7280
|
* Build the visible-window indicator `DrawCommand` for the minimap.
|
|
6269
7281
|
*
|
|
@@ -6315,13 +7327,21 @@ interface MinimapCanvasProps<TData, TLayer extends string, TPose> {
|
|
|
6315
7327
|
* frame if it goes there, rather than making the whole minimap rescale on
|
|
6316
7328
|
* every frame of a drag or a settle. */
|
|
6317
7329
|
fit?: MinimapFit<TData, TLayer, TPose>;
|
|
6318
|
-
/**
|
|
6319
|
-
|
|
6320
|
-
poseBounds?: (pose: TPose) => Bounds;
|
|
7330
|
+
/** How to read poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
7331
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
6321
7332
|
/** Optional per-id alpha multiplier, mirroring `<SceneCanvas>`'s scene-slot
|
|
6322
7333
|
* `alphaFor`. Pass the same function the main canvas uses so a
|
|
6323
7334
|
* scoping-dim treatment shows up in the minimap too. */
|
|
6324
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;
|
|
6325
7345
|
/** Visual tuning of the indicator stroke. */
|
|
6326
7346
|
indicatorStyle?: IndicatorStyle;
|
|
6327
7347
|
/** CSS class for sizing / positioning the canvas. */
|
|
@@ -6385,6 +7405,9 @@ interface RenderSceneToPixelsArgs<TData, TLayer extends string, TPose> {
|
|
|
6385
7405
|
* `alphaFor`. Pass the same function the on-screen canvas uses so an
|
|
6386
7406
|
* export matches what the user is looking at. Defaults to `() => 1`. */
|
|
6387
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;
|
|
6388
7411
|
/** Background fill (any CSS color accepted by the renderer). Default:
|
|
6389
7412
|
* fully transparent. Passing a color is always valid. */
|
|
6390
7413
|
background?: string;
|
|
@@ -6893,9 +7916,9 @@ declare function renderLabel(ctx: CanvasRenderingContext2D, text: string, x: num
|
|
|
6893
7916
|
declare const defaultLabelTextRenderer: TextRenderer;
|
|
6894
7917
|
|
|
6895
7918
|
/**
|
|
6896
|
-
* Text RenderLayer
|
|
6897
|
-
*
|
|
6898
|
-
*
|
|
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.
|
|
6899
7922
|
*
|
|
6900
7923
|
* The GL renderer uses MSDF text. The resolved style's `fontFamily` must
|
|
6901
7924
|
* be registered via `registerFont(family, variant, metricsUrl, atlasUrl)`
|
|
@@ -6930,10 +7953,10 @@ declare function createTextLayer<T>(opts: CreateTextLayerOpts<T>): RenderLayer<u
|
|
|
6930
7953
|
*
|
|
6931
7954
|
* `caretIndexAt` does the finer test: given a world-space (x, y) inside the
|
|
6932
7955
|
* pose, returns the corresponding character offset so the consumer can place
|
|
6933
|
-
* the caret on click. It reads the caret stops off the
|
|
6934
|
-
*
|
|
6935
|
-
*
|
|
6936
|
-
*
|
|
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.
|
|
6937
7960
|
*/
|
|
6938
7961
|
|
|
6939
7962
|
/** Options for `pointInTextPose`. */
|
|
@@ -6943,19 +7966,6 @@ interface PointInTextPoseOpts {
|
|
|
6943
7966
|
}
|
|
6944
7967
|
/** Coarse pose-rect hit-test for a text node — suitable for click-to-edit dispatch. */
|
|
6945
7968
|
declare function pointInTextPose(x: number, y: number, pose: TextPose, opts?: PointInTextPoseOpts): boolean;
|
|
6946
|
-
/** Options for `caretIndexAt`. */
|
|
6947
|
-
interface CaretIndexAtOpts {
|
|
6948
|
-
/**
|
|
6949
|
-
* Wrap width. Default `pose.width`, which is what `createTextLayer` passes
|
|
6950
|
-
* and what `TextPose` means by its box.
|
|
6951
|
-
*
|
|
6952
|
-
* Pass `Infinity` for a node painted by the built-in `kit:text` painter:
|
|
6953
|
-
* that painter deliberately does not forward `maxWidth`, so its text does
|
|
6954
|
-
* not wrap, and a caret mapped through a finite width would answer for a
|
|
6955
|
-
* line break the paint never made. Mirrors `textLineBoxes`.
|
|
6956
|
-
*/
|
|
6957
|
-
maxWidth?: number;
|
|
6958
|
-
}
|
|
6959
7969
|
/**
|
|
6960
7970
|
* Map a world-space point inside `pose` to a character offset into the pose's
|
|
6961
7971
|
* text (0..length). Clicks above the first line clamp to 0; clicks below the
|
|
@@ -6967,7 +7977,7 @@ interface CaretIndexAtOpts {
|
|
|
6967
7977
|
* produced) and `pose.verticalAlign`. The offset is into the runs'
|
|
6968
7978
|
* concatenated text, which `TextPose` requires to equal `pose.text`.
|
|
6969
7979
|
*/
|
|
6970
|
-
declare function caretIndexAt(x: number, y: number, pose: TextPose
|
|
7980
|
+
declare function caretIndexAt(x: number, y: number, pose: TextPose): number;
|
|
6971
7981
|
|
|
6972
7982
|
/**
|
|
6973
7983
|
* Resize a text node's pose to fit its content. Pure helper — does not own
|
|
@@ -6977,8 +7987,9 @@ declare function caretIndexAt(x: number, y: number, pose: TextPose, opts?: Caret
|
|
|
6977
7987
|
* Two modes:
|
|
6978
7988
|
*
|
|
6979
7989
|
* - `axis: 'height'` (default): keep `pose.width`, recompute `height` as
|
|
6980
|
-
* the
|
|
6981
|
-
*
|
|
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.
|
|
6982
7993
|
*
|
|
6983
7994
|
* - `axis: 'both'`: ignore wrapping; recompute both `width` (longest
|
|
6984
7995
|
* `\n`-split line) and `height` (line count × line height) plus padding.
|
|
@@ -7198,6 +8209,13 @@ interface TextEditScreenPose {
|
|
|
7198
8209
|
*/
|
|
7199
8210
|
zoom?: number;
|
|
7200
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
|
+
}
|
|
7201
8219
|
/** Options for `useTextEdit`. */
|
|
7202
8220
|
interface UseTextEditOptions {
|
|
7203
8221
|
/** Element the overlay is appended to. Must be `position: relative`/absolute. */
|
|
@@ -7224,6 +8242,15 @@ interface UseTextEditOptions {
|
|
|
7224
8242
|
setStyle?: (id: string, style: TextStyle) => void;
|
|
7225
8243
|
/** Read screen-space pose for `id`. Called per frame while editing. */
|
|
7226
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;
|
|
7227
8254
|
/** Commit text. Caller wraps in op/undo. */
|
|
7228
8255
|
setText: (id: string, text: string) => void;
|
|
7229
8256
|
/**
|
|
@@ -7386,9 +8413,9 @@ declare function unionAABB<TPose extends RectPose>(parts: Iterable<TPose | null
|
|
|
7386
8413
|
* (`getText` / `getStyle` / `getRuns` / `setText` / `setRuns` / `setStyle`).
|
|
7387
8414
|
*
|
|
7388
8415
|
* Pose component: the helper reads `(x, y, width, height)` straight off
|
|
7389
|
-
* the node's pose (typed `RectPose`)
|
|
7390
|
-
*
|
|
7391
|
-
*
|
|
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.
|
|
7392
8419
|
* Consumers with non-rect poses should drop down to raw `useTextEdit` and
|
|
7393
8420
|
* supply their own `getScreenPose`.
|
|
7394
8421
|
*/
|
|
@@ -7402,6 +8429,7 @@ interface DefaultTextData {
|
|
|
7402
8429
|
runs?: readonly StyledRun[];
|
|
7403
8430
|
fill?: FillStyle | null;
|
|
7404
8431
|
stroke?: Stroke | null;
|
|
8432
|
+
verticalAlign?: TextVerticalAlign;
|
|
7405
8433
|
}
|
|
7406
8434
|
/** All-optional projections + fontSize fallback. */
|
|
7407
8435
|
interface UseSceneTextEditOptions<TData> {
|
|
@@ -7413,6 +8441,8 @@ interface UseSceneTextEditOptions<TData> {
|
|
|
7413
8441
|
getPaint?: (data: TData) => TextPaint | undefined;
|
|
7414
8442
|
/** Read rich-text runs from `data`. Default: `data.runs`. */
|
|
7415
8443
|
getRuns?: (data: TData) => readonly StyledRun[] | undefined;
|
|
8444
|
+
/** Read the box vertical alignment from `data`. Default: `data.verticalAlign`. */
|
|
8445
|
+
getVerticalAlign?: (data: TData) => TextVerticalAlign | undefined;
|
|
7416
8446
|
/** Produce updated data with new text. Default: `{ ...data, text }`. */
|
|
7417
8447
|
setText?: (data: TData, text: string) => TData;
|
|
7418
8448
|
/** Produce updated data with new runs. Default: `{ ...data, runs }`. */
|
|
@@ -7428,21 +8458,24 @@ interface UseSceneTextEditOptions<TData> {
|
|
|
7428
8458
|
/** Fallback fontSize when `style.fontSize` is unset. Default `16`. */
|
|
7429
8459
|
defaultFontSize?: number;
|
|
7430
8460
|
/**
|
|
7431
|
-
*
|
|
7432
|
-
*
|
|
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
|
|
7433
8468
|
* by the view, so every typographic metric on it — including the
|
|
7434
8469
|
* `fontSize` / `letterSpacing` a *run* carries — stays in world units and
|
|
7435
|
-
* scales together.
|
|
7436
|
-
* screen pixels (correct at `{x: 0, y: 0, scale: 1}`).
|
|
8470
|
+
* scales together.
|
|
7437
8471
|
*
|
|
7438
8472
|
* The overlay takes a single scale factor, so a non-uniform view scale is
|
|
7439
8473
|
* represented by its `scale.x`; text under `scale.x !== scale.y` will not
|
|
7440
8474
|
* match the canvas.
|
|
7441
8475
|
*
|
|
7442
|
-
*
|
|
7443
|
-
*
|
|
7444
|
-
*
|
|
7445
|
-
* 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.
|
|
7446
8479
|
*/
|
|
7447
8480
|
view?: View | (() => View);
|
|
7448
8481
|
/**
|
|
@@ -7468,8 +8501,10 @@ interface UseSceneTextEditReturn extends UseTextEditReturn {
|
|
|
7468
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;
|
|
7469
8502
|
|
|
7470
8503
|
/**
|
|
7471
|
-
* Build a `TextDrawCommand`. `
|
|
7472
|
-
*
|
|
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
|
|
7473
8508
|
* resolve through `resolveTextStyle` + `resolveRuns`, so every emitter of a
|
|
7474
8509
|
* text command derives `align` and per-run resolution the same way — a
|
|
7475
8510
|
* caller that assembles the command by hand is one field away from a
|
|
@@ -7479,11 +8514,18 @@ declare function useSceneTextEdit<TData extends DefaultTextData, TLayer extends
|
|
|
7479
8514
|
* a HUD widget, a debug overlay — states its color on the run instead.
|
|
7480
8515
|
*/
|
|
7481
8516
|
|
|
7482
|
-
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;
|
|
7483
8518
|
/** Build a draw command for a single unstyled string. Text is laid out with
|
|
7484
|
-
* the registered font's metrics, wrapped at `maxWidth
|
|
7485
|
-
* `height` when
|
|
7486
|
-
|
|
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;
|
|
7487
8529
|
|
|
7488
8530
|
/**
|
|
7489
8531
|
* Pure DOM ↔ `StyledRun[]` serializers for the contenteditable overlay
|
|
@@ -7975,10 +9017,8 @@ interface NestedHitOpts<TNode extends {
|
|
|
7975
9017
|
/** Compose a child's local pose into world coords given its parent's world
|
|
7976
9018
|
* pose. Same shape as `composeRectPose` (the default expectation). */
|
|
7977
9019
|
composePose: (parent: TPose, child: TPose) => TPose;
|
|
7978
|
-
/**
|
|
7979
|
-
|
|
7980
|
-
* `RectPose`). Override for non-rect poses (e.g. paths). */
|
|
7981
|
-
poseBounds?: (pose: TPose) => Bounds;
|
|
9020
|
+
/** How to read world poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
9021
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
7982
9022
|
/** Predicate for "this object is a nesting parent body". The leaf scan
|
|
7983
9023
|
* skips objects for which this returns true so a click on a parent's
|
|
7984
9024
|
* painted body resolves to a child leaf, not the parent itself. Default:
|
|
@@ -8007,6 +9047,22 @@ declare function nestedHitTester<TNode extends {
|
|
|
8007
9047
|
id: string;
|
|
8008
9048
|
}, TPose>(adapter: HitAdapter<TNode, TPose>, opts: NestedHitOpts<TNode, TPose>): NestedHitTester;
|
|
8009
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
|
+
|
|
8010
9066
|
/**
|
|
8011
9067
|
* Fluent builder for `PolygonPath`. Hides the `Uint8Array` / `Float32Array`
|
|
8012
9068
|
* encoding behind move/line/curve/close calls and a final `build()`. Use
|
|
@@ -8242,6 +9298,35 @@ declare function pathIntersectsPolygon(path: Path, polygon: readonly Vec2[], opt
|
|
|
8242
9298
|
* combine with `pathContainsPoint` at the call site. */
|
|
8243
9299
|
declare function pathDistanceToPoint(path: Path, px: number, py: number): number;
|
|
8244
9300
|
|
|
9301
|
+
/**
|
|
9302
|
+
* A station along a path: where it is at a fraction of its length, and which
|
|
9303
|
+
* way it is heading there.
|
|
9304
|
+
*
|
|
9305
|
+
* For anything positioned *along* geometry rather than beside it — a label on a
|
|
9306
|
+
* routed edge, a tick on a curve, a badge near an arrowhead. Curves are
|
|
9307
|
+
* flattened first, so the fraction is arc length along the drawn shape rather
|
|
9308
|
+
* than a curve parameter, which is what makes 0.5 look like the middle.
|
|
9309
|
+
*/
|
|
9310
|
+
|
|
9311
|
+
interface PathStation {
|
|
9312
|
+
point: Vec2;
|
|
9313
|
+
/** Unit vector along the path at `point`, pointing toward the end. */
|
|
9314
|
+
tangent: Vec2;
|
|
9315
|
+
}
|
|
9316
|
+
interface PointAlongPathOptions {
|
|
9317
|
+
/** Curve flattening tolerance, in world units. Default 0.5. */
|
|
9318
|
+
flattenTolerance?: number;
|
|
9319
|
+
}
|
|
9320
|
+
/**
|
|
9321
|
+
* Where `path` is at `t` of its total length, and its heading there.
|
|
9322
|
+
*
|
|
9323
|
+
* `t` is clamped to 0..1. Subpaths are measured in order and treated as one
|
|
9324
|
+
* run, the way a browser measures a whole `<path>`. Returns `null` for a path
|
|
9325
|
+
* with no points at all; a path of zero length answers at its single point,
|
|
9326
|
+
* heading along +X.
|
|
9327
|
+
*/
|
|
9328
|
+
declare function pointAlongPath(path: Path, t: number, opts?: PointAlongPathOptions): PathStation | null;
|
|
9329
|
+
|
|
8245
9330
|
/**
|
|
8246
9331
|
* In-place and copy-out path transforms. Translation is the most common —
|
|
8247
9332
|
* called every pointermove during a drag — so the polygon variant mutates
|
|
@@ -8249,9 +9334,7 @@ declare function pathDistanceToPoint(path: Path, px: number, py: number): number
|
|
|
8249
9334
|
*
|
|
8250
9335
|
* `scalePathToBounds` is for the resize interaction: given the path's
|
|
8251
9336
|
* current AABB and the desired new AABB, scales every coordinate
|
|
8252
|
-
* proportionally.
|
|
8253
|
-
* the corresponding axis to the new origin — preferable to dividing by
|
|
8254
|
-
* zero or refusing to resize.
|
|
9337
|
+
* proportionally.
|
|
8255
9338
|
*/
|
|
8256
9339
|
|
|
8257
9340
|
/**
|
|
@@ -8270,9 +9353,9 @@ declare function translatePolygonInPlace(path: PolygonPath, dx: number, dy: numb
|
|
|
8270
9353
|
* Scale a path's coords so its current AABB maps to `target`. Resize
|
|
8271
9354
|
* interactions use this to make a polygon follow a corner-handle drag.
|
|
8272
9355
|
*
|
|
8273
|
-
*
|
|
8274
|
-
* `
|
|
8275
|
-
*
|
|
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.
|
|
8276
9359
|
*/
|
|
8277
9360
|
declare function scalePathToBounds(path: Path, target: RectPath): Path;
|
|
8278
9361
|
|
|
@@ -8429,48 +9512,6 @@ interface CreatePathLayerOpts<T> {
|
|
|
8429
9512
|
/** Build a `RenderLayer` that fills/strokes `Path` instances enumerated from a node list. */
|
|
8430
9513
|
declare function createPathLayer<T>(opts: CreatePathLayerOpts<T>): RenderLayer<unknown>;
|
|
8431
9514
|
|
|
8432
|
-
/**
|
|
8433
|
-
* Bezier flattening — subdivide cubic and quadratic segments into polyline
|
|
8434
|
-
* approximations within a flatness tolerance. Used by hit-testing and
|
|
8435
|
-
* (eventually) any kernel that doesn't want to special-case curves.
|
|
8436
|
-
*
|
|
8437
|
-
* The flatness metric is the maximum perpendicular distance from any
|
|
8438
|
-
* control point to the chord between endpoints. When that distance falls
|
|
8439
|
-
* below `tolerance`, the segment is "flat enough" and emitted as a single
|
|
8440
|
-
* line segment.
|
|
8441
|
-
*
|
|
8442
|
-
* Tolerance is in world units. 0.5 is a sensible default for screen-rate
|
|
8443
|
-
* rendering at 1× zoom; consumers that zoom in heavily should pass a
|
|
8444
|
-
* tighter tolerance.
|
|
8445
|
-
*/
|
|
8446
|
-
declare const DEFAULT_FLATTEN_TOLERANCE = 0.5;
|
|
8447
|
-
/**
|
|
8448
|
-
* Recursively subdivide a cubic bezier (P0..P3) and append `lineTo`-style
|
|
8449
|
-
* vertices to `out` (interleaved x,y). The starting endpoint is *not*
|
|
8450
|
-
* appended — callers usually emitted it as the segment's previous vertex.
|
|
8451
|
-
*/
|
|
8452
|
-
declare function flattenCubic(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, tolerance: number, out: number[]): void;
|
|
8453
|
-
/** Recursively subdivide a quadratic bezier (P0, P1, P2). */
|
|
8454
|
-
declare function flattenQuadratic(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, tolerance: number, out: number[]): void;
|
|
8455
|
-
/**
|
|
8456
|
-
* Like `flattenCubic` but also appends, for each new flattened point, its
|
|
8457
|
-
* arc-length fraction `t` (relative to the polyline distance accumulated so
|
|
8458
|
-
* far inside this curve) to `arcOut`. Caller then post-processes the segment's
|
|
8459
|
-
* `arcOut` range by dividing each by the segment's total flattened arc length
|
|
8460
|
-
* to yield t ∈ (0, 1].
|
|
8461
|
-
*
|
|
8462
|
-
* The returned values are *cumulative distance from the segment start*, not
|
|
8463
|
-
* normalized fractions. Two-pass design (accumulate, then divide) keeps the
|
|
8464
|
-
* recursive splitter simple — it doesn't need to know the total length up
|
|
8465
|
-
* front.
|
|
8466
|
-
*/
|
|
8467
|
-
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;
|
|
8468
|
-
/** Flatten a quadratic bezier into line segments within `tolerance`, appending
|
|
8469
|
-
* points to `out` and their cumulative arc lengths to `arcOut`. The arc
|
|
8470
|
-
* lengths are what lets per-anchor color and dash phase be interpolated
|
|
8471
|
-
* evenly along the curve rather than per segment. */
|
|
8472
|
-
declare function flattenQuadraticWithArcLen(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, tolerance: number, out: number[], arcOut: number[]): number;
|
|
8473
|
-
|
|
8474
9515
|
/**
|
|
8475
9516
|
* `pathFromD` — build a weasel `Path` from an **SVG path-data string** (the
|
|
8476
9517
|
* value of SVG's `d` attribute, e.g. `"M0 0 L100 0 Z"`).
|
|
@@ -8564,17 +9605,16 @@ declare function splitPathByLine(path: Path, a: Point, b: Point, opts?: SplitByL
|
|
|
8564
9605
|
declare function unionBoundsPath(paths: Iterable<Path>): RectPath | null;
|
|
8565
9606
|
|
|
8566
9607
|
/**
|
|
8567
|
-
* `
|
|
9608
|
+
* `PoseDescriptor` for `Path` poses — wires `useResize` to operate
|
|
8568
9609
|
* on `Path` directly. `getBounds` defers to the same `boundsOfPath` kernel
|
|
8569
|
-
* the rest of the kit uses
|
|
8570
|
-
* coord against `src`/`dst`. Degenerate axes (zero src extent) collapse to
|
|
8571
|
-
* the new origin so resize from a flat edge doesn't produce NaN.
|
|
9610
|
+
* the rest of the kit uses.
|
|
8572
9611
|
*
|
|
8573
|
-
*
|
|
8574
|
-
* knows the group's origin AABB and uses it for every leaf,
|
|
8575
|
-
* 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).
|
|
8576
9616
|
*/
|
|
8577
|
-
declare const pathPoseDescriptor:
|
|
9617
|
+
declare const pathPoseDescriptor: PoseDescriptor<Path>;
|
|
8578
9618
|
|
|
8579
9619
|
/**
|
|
8580
9620
|
* `OriginProjection` for `Path` poses. The "origin" is the top-left of the
|
|
@@ -8710,11 +9750,6 @@ declare function pathExclude(...paths: Path[]): PolygonPath;
|
|
|
8710
9750
|
* Fracture N paths along every intersection into the maximal set of
|
|
8711
9751
|
* non-overlapping regions. Returns one `PolygonPath` per region.
|
|
8712
9752
|
*
|
|
8713
|
-
* Algorithm: for every non-empty subset S ⊆ {A1..AN}, emit the region
|
|
8714
|
-
* `(∩ S) − (∪ complement)` — points covered by exactly the members of S
|
|
8715
|
-
* and no others. By construction the emitted regions are pairwise disjoint
|
|
8716
|
-
* and their union equals `pathUnion(A1..AN)`.
|
|
8717
|
-
*
|
|
8718
9753
|
* For N=2 this collapses to the three Illustrator "Divide" outputs
|
|
8719
9754
|
* (A−B, B−A, A∩B). For N=3 up to 7 regions are emitted. The 2^N − 1
|
|
8720
9755
|
* subset count limits this to small N in practice; passing more than ~8
|
|
@@ -8901,10 +9936,19 @@ interface PaintBindContext {
|
|
|
8901
9936
|
* from the paint's space to the frame the geometry arrives in. Paired with
|
|
8902
9937
|
* the vertex shader's `v_world` varying this is *the* paint-space
|
|
8903
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.
|
|
9943
|
+
*/
|
|
9944
|
+
spaceInverse(units: GradientUnits | undefined): Mat3$1 | null;
|
|
9945
|
+
/**
|
|
9946
|
+
* Bake a stop ramp into the frame's ramp atlas, bind that atlas to a texture
|
|
9947
|
+
* unit, and return the `v` the ramp's own row sits at — every ramp in a
|
|
9948
|
+
* frame shares one texture, so a paint must sample at the returned `v` and
|
|
9949
|
+
* not at a constant.
|
|
8904
9950
|
*/
|
|
8905
|
-
|
|
8906
|
-
/** Upload a stop ramp and bind it to a texture unit. */
|
|
8907
|
-
bindRamp(stops: GradStop[], unit: number): void;
|
|
9951
|
+
bindRamp(stops: GradStop[], unit: number): number;
|
|
8908
9952
|
}
|
|
8909
9953
|
/**
|
|
8910
9954
|
* One paint kind.
|
|
@@ -9247,21 +10291,15 @@ interface ArrayAdapterConfig<TNode extends {
|
|
|
9247
10291
|
* Consumers own id generation and any palette/payload fields. Returning
|
|
9248
10292
|
* `null` aborts the insert. When omitted, `commitInsert` returns `null`. */
|
|
9249
10293
|
createDefault?: (bounds: Bounds) => TNode | null;
|
|
9250
|
-
/**
|
|
9251
|
-
*
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
* `pathPoseDescriptor.intersectsRect`). */
|
|
9256
|
-
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>;
|
|
9257
10299
|
/** Factory for fresh node ids in `commitPaste`. Default: `crypto.randomUUID()`
|
|
9258
10300
|
* when available, otherwise a monotonic `paste-<n>` counter. Override
|
|
9259
10301
|
* when consumers want stable id schemes (e.g. `clip-${n++}`). */
|
|
9260
10302
|
nextId?: () => string;
|
|
9261
|
-
/** Translate a pose by `(dx, dy)`. Default: shallow-spread `{ x, y }`,
|
|
9262
|
-
* which matches the canonical axis-aligned rect pose. Override for
|
|
9263
|
-
* non-rect poses whose translation isn't a top-level `x`/`y` bump. */
|
|
9264
|
-
translatePose?: (pose: TPose, dx: number, dy: number) => TPose;
|
|
9265
10303
|
}
|
|
9266
10304
|
/**
|
|
9267
10305
|
* Combined adapter satisfying every narrow adapter the kit ships. Methods
|
|
@@ -9433,14 +10471,6 @@ interface GuidesLayerOpts {
|
|
|
9433
10471
|
* screen space, projected from world offsets via the active view. */
|
|
9434
10472
|
declare function createGuidesLayer(opts: GuidesLayerOpts): RenderLayer<unknown>;
|
|
9435
10473
|
|
|
9436
|
-
/** Axis-aligned bounding box. Alignment matches AABBs throughout; a rotated
|
|
9437
|
-
* pose enters as the AABB of its ink (see `AlignBoundsProjection.boundsOf`). */
|
|
9438
|
-
interface AlignBounds {
|
|
9439
|
-
x: number;
|
|
9440
|
-
y: number;
|
|
9441
|
-
width: number;
|
|
9442
|
-
height: number;
|
|
9443
|
-
}
|
|
9444
10474
|
/** Which feature of a box to test against candidates, per axis.
|
|
9445
10475
|
* 'min' = left/top edge, 'center' = centerline, 'max' = right/bottom edge. */
|
|
9446
10476
|
type AlignAnchor = 'min' | 'center' | 'max';
|
|
@@ -9453,31 +10483,18 @@ interface AlignMatchResult {
|
|
|
9453
10483
|
activeX: Guide | null;
|
|
9454
10484
|
activeY: Guide | null;
|
|
9455
10485
|
}
|
|
9456
|
-
/** Bounds analog of the gesture `OriginProjection`: reads an AABB from a pose
|
|
9457
|
-
* and translates a pose. The rect default handles `{x,y,width,height}` poses;
|
|
9458
|
-
* non-rect poses (Path, polygon) supply their own. */
|
|
9459
|
-
interface AlignBoundsProjection<TPose> {
|
|
9460
|
-
/** The pose's *visual* AABB — a rotated pose reports the extent of its ink,
|
|
9461
|
-
* not the box it was posed in. Guides and matching both read this, so an
|
|
9462
|
-
* implementation that returns the stored box makes a rotated shape snap to
|
|
9463
|
-
* lines nothing is drawn at. */
|
|
9464
|
-
boundsOf(pose: TPose): AlignBounds;
|
|
9465
|
-
/** Move the pose, preserving every other field it carries — nothing
|
|
9466
|
-
* downstream re-derives rotation or style from anywhere else. */
|
|
9467
|
-
translate(pose: TPose, dx: number, dy: number): TPose;
|
|
9468
|
-
}
|
|
9469
10486
|
/** Which candidate lines to derive from a set of poses — edges, centers, or
|
|
9470
10487
|
* both, and whether the page box contributes its own. */
|
|
9471
|
-
interface DeriveAlignmentGuidesOptions<TPose =
|
|
10488
|
+
interface DeriveAlignmentGuidesOptions<TPose = Bounds> {
|
|
9472
10489
|
/** Include the document/page box's edges + center as candidates. */
|
|
9473
|
-
page?:
|
|
10490
|
+
page?: Bounds;
|
|
9474
10491
|
/** Emit left/right (x) and top/bottom (y) edge guides. Default true. */
|
|
9475
10492
|
edges?: boolean;
|
|
9476
10493
|
/** Emit centerX (x) and centerY (y) guides. Default true. */
|
|
9477
10494
|
centers?: boolean;
|
|
9478
|
-
/**
|
|
9479
|
-
*
|
|
9480
|
-
|
|
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>;
|
|
9481
10498
|
}
|
|
9482
10499
|
/** Common options shared by the three alignment behavior factories. */
|
|
9483
10500
|
interface AlignmentBehaviorBase {
|
|
@@ -9497,20 +10514,15 @@ interface AlignmentBehaviorBase {
|
|
|
9497
10514
|
/** Derive candidate alignment lines from a set of sibling poses plus an
|
|
9498
10515
|
* optional page box. Each box contributes up to 3 guides per axis: the two
|
|
9499
10516
|
* edges and the center. Overlapping offsets collapse to one candidate.
|
|
9500
|
-
* Poses go through the same
|
|
10517
|
+
* Poses go through the same descriptor `alignMoveBehavior` matches with, so
|
|
9501
10518
|
* a rotated sibling advertises its ink edges rather than its stored box. */
|
|
9502
|
-
declare function deriveAlignmentGuides<TPose =
|
|
10519
|
+
declare function deriveAlignmentGuides<TPose = Bounds>(targets: readonly TPose[], opts?: DeriveAlignmentGuidesOptions<TPose>): Guide[];
|
|
9503
10520
|
|
|
9504
10521
|
/** Move/insert test all three features per axis. */
|
|
9505
10522
|
declare const MOVE_ANCHORS: {
|
|
9506
10523
|
x: readonly AlignAnchor[];
|
|
9507
10524
|
y: readonly AlignAnchor[];
|
|
9508
10525
|
};
|
|
9509
|
-
/** Default projection for rect-shaped poses (`{x,y,width,height,rotation?}`).
|
|
9510
|
-
* A rotated pose reports the AABB of its ink, so guides derived from a
|
|
9511
|
-
* stationary sibling and the box a dragged selection matches with are the
|
|
9512
|
-
* same measurement. */
|
|
9513
|
-
declare const RECT_ALIGN_PROJECTION: AlignBoundsProjection<RectPose>;
|
|
9514
10526
|
/**
|
|
9515
10527
|
* Match a moving box's selected edge/center features against candidate guide
|
|
9516
10528
|
* lines. Returns the per-axis snap delta and the matched candidate line(s).
|
|
@@ -9522,7 +10534,7 @@ declare const RECT_ALIGN_PROJECTION: AlignBoundsProjection<RectPose>;
|
|
|
9522
10534
|
* distance along that axis alone, so there is an exact answer rather than an
|
|
9523
10535
|
* approximation. Pass the same number twice for a world-space tolerance.
|
|
9524
10536
|
*/
|
|
9525
|
-
declare function matchAlignment(bounds:
|
|
10537
|
+
declare function matchAlignment(bounds: Bounds, candidates: readonly Guide[], worldTolerance: {
|
|
9526
10538
|
x: number;
|
|
9527
10539
|
y: number;
|
|
9528
10540
|
}, anchors: {
|
|
@@ -9530,9 +10542,9 @@ declare function matchAlignment(bounds: AlignBounds, candidates: readonly Guide[
|
|
|
9530
10542
|
y: readonly AlignAnchor[];
|
|
9531
10543
|
}): AlignMatchResult;
|
|
9532
10544
|
|
|
9533
|
-
/** Options for move/insert — adds the
|
|
10545
|
+
/** Options for move/insert — adds the pose descriptor for non-rect poses. */
|
|
9534
10546
|
interface AlignMoveArgs<TPose> extends AlignmentBehaviorBase {
|
|
9535
|
-
|
|
10547
|
+
poseDescriptor?: PoseDescriptor<TPose>;
|
|
9536
10548
|
}
|
|
9537
10549
|
/** Move behavior: snap the dragged selection's union box (edges + center) to
|
|
9538
10550
|
* candidates, shaping the proposed translate. The gesture applies the
|
|
@@ -9545,10 +10557,10 @@ declare function alignMoveBehavior<TPose>(args: AlignMoveArgs<TPose>): MoveBehav
|
|
|
9545
10557
|
declare function alignInsertBehavior<TPose>(args: AlignmentBehaviorBase): InsertBehavior<TPose>;
|
|
9546
10558
|
/** Resize constraint: snap the moving edge(s) of the dragged rect to
|
|
9547
10559
|
* candidates. The pinned (anchor) edge stays fixed. Publishes the line(s). */
|
|
9548
|
-
declare function alignResizeBehavior<TPose extends
|
|
10560
|
+
declare function alignResizeBehavior<TPose extends Bounds>(args: AlignmentBehaviorBase): BoundsConstraint<TPose>;
|
|
9549
10561
|
|
|
9550
10562
|
/** AABB center of an unrotated rect — the canonical rotation pivot. */
|
|
9551
|
-
declare function aabbCenter(bounds:
|
|
10563
|
+
declare function aabbCenter(bounds: Bounds): {
|
|
9552
10564
|
x: number;
|
|
9553
10565
|
y: number;
|
|
9554
10566
|
};
|
|
@@ -9558,7 +10570,7 @@ declare function rotatePoint(px: number, py: number, cx: number, cy: number, ang
|
|
|
9558
10570
|
y: number;
|
|
9559
10571
|
};
|
|
9560
10572
|
/** Four corners of an unrotated rect, in TL/TR/BR/BL order. */
|
|
9561
|
-
declare function rectCorners(bounds:
|
|
10573
|
+
declare function rectCorners(bounds: Bounds): {
|
|
9562
10574
|
x: number;
|
|
9563
10575
|
y: number;
|
|
9564
10576
|
}[];
|
|
@@ -9843,65 +10855,6 @@ interface AnchorHit {
|
|
|
9843
10855
|
* are within `threshold` (controls are smaller and rendered on top). */
|
|
9844
10856
|
declare function hitAnchor(path: PolygonPath, worldX: number, worldY: number, threshold: number): AnchorHit | null;
|
|
9845
10857
|
|
|
9846
|
-
/**
|
|
9847
|
-
* Typed keys for the gesture/behavior scratch store.
|
|
9848
|
-
*
|
|
9849
|
-
* Gestures expose `ctx.scratch: Record<string, unknown>` as a per-gesture
|
|
9850
|
-
* mutable bag that behaviors use to stash state across `onDown` / `onMove`
|
|
9851
|
-
* / `onEnd` calls. The store is `unknown`-valued because behaviors are
|
|
9852
|
-
* tool-agnostic — a single behavior may run under different tools with
|
|
9853
|
-
* different scratch shapes. Without a typing convention every read site
|
|
9854
|
-
* has to `(ctx.scratch as <some shape>)[KEY]`, and a writer changing the
|
|
9855
|
-
* shape can silently break readers with no compile-time signal.
|
|
9856
|
-
*
|
|
9857
|
-
* `ScratchKey<T>` is a phantom-typed string that carries its payload type
|
|
9858
|
-
* via a branded interface. `getScratch` and `setScratch` use the brand to
|
|
9859
|
-
* narrow / constrain at the typing layer; at runtime the key is just its
|
|
9860
|
-
* underlying string and the store remains a plain `Record`.
|
|
9861
|
-
*
|
|
9862
|
-
* @example
|
|
9863
|
-
* ```ts
|
|
9864
|
-
* // Module-level (or behavior-level) constant, shared by writer + reader:
|
|
9865
|
-
* const LASSO_VERTICES = scratchKey<readonly { x: number; y: number }[]>('lasso.vertices');
|
|
9866
|
-
*
|
|
9867
|
-
* // Writer (a tool's onMove):
|
|
9868
|
-
* setScratch(ctx.scratch, LASSO_VERTICES, vertices);
|
|
9869
|
-
*
|
|
9870
|
-
* // Reader (a behavior's onEnd):
|
|
9871
|
-
* const vertices = getScratch(ctx.scratch, LASSO_VERTICES) ?? [];
|
|
9872
|
-
* // ^? readonly { x: number; y: number }[] | undefined
|
|
9873
|
-
* ```
|
|
9874
|
-
*/
|
|
9875
|
-
/** Phantom-typed key for a scratch slot. The `__scratchKeyPayload` phantom
|
|
9876
|
-
* field carries the value type without occupying any runtime memory. */
|
|
9877
|
-
interface ScratchKey<T> {
|
|
9878
|
-
readonly name: string;
|
|
9879
|
-
/** Phantom — never read at runtime. Only present so TypeScript can
|
|
9880
|
-
* recover `T` at use sites. */
|
|
9881
|
-
readonly __scratchKeyPayload?: (_: T) => T;
|
|
9882
|
-
}
|
|
9883
|
-
/** Compatible scratch store shape. The kit's gesture context's `scratch`
|
|
9884
|
-
* field already satisfies this; consumers don't need to construct one. */
|
|
9885
|
-
type ScratchStore = Record<string, unknown>;
|
|
9886
|
-
/**
|
|
9887
|
-
* Make a typed scratch key. Use module-level constants so the same key
|
|
9888
|
-
* is shared by writer and reader.
|
|
9889
|
-
*
|
|
9890
|
-
* Namespace the name by behavior or feature to avoid collisions
|
|
9891
|
-
* (`'behavior.field'` is a good convention). Two keys with the same
|
|
9892
|
-
* `name` refer to the same slot at runtime — the type parameter is a
|
|
9893
|
-
* compile-time contract, not a uniqueness guarantee.
|
|
9894
|
-
*/
|
|
9895
|
-
declare function scratchKey<T>(name: string): ScratchKey<T>;
|
|
9896
|
-
/** Read a typed slot from the scratch store. Returns `undefined` if
|
|
9897
|
-
* nothing has been written under the key. */
|
|
9898
|
-
declare function getScratch<T>(store: ScratchStore, key: ScratchKey<T>): T | undefined;
|
|
9899
|
-
/** Write a value to a typed slot. Overwrites whatever was there. */
|
|
9900
|
-
declare function setScratch<T>(store: ScratchStore, key: ScratchKey<T>, value: T): void;
|
|
9901
|
-
/** Remove a slot from the scratch store. Returns `true` if it was set,
|
|
9902
|
-
* `false` if it wasn't. */
|
|
9903
|
-
declare function deleteScratch<T>(store: ScratchStore, key: ScratchKey<T>): boolean;
|
|
9904
|
-
|
|
9905
10858
|
/** Options for `selectFromLasso`. */
|
|
9906
10859
|
interface SelectFromLassoOptions {
|
|
9907
10860
|
/** Hit mode for `hitTestLasso`. Default 'intersect'. */
|
|
@@ -9919,7 +10872,11 @@ type AlignEdge = 'left' | 'right' | 'top' | 'bottom' | 'center-x' | 'center-y';
|
|
|
9919
10872
|
/** Adapter for `useAlign`. */
|
|
9920
10873
|
interface AlignAdapter<TPose> {
|
|
9921
10874
|
getSelection(): NodeId[];
|
|
10875
|
+
/** The pose as stored — local to the node's parent. */
|
|
9922
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;
|
|
9923
10880
|
applyOps?(ops: Op[], label?: string): void;
|
|
9924
10881
|
}
|
|
9925
10882
|
/** Options for `useAlign`. */
|
|
@@ -9927,38 +10884,30 @@ interface UseAlignOptions<TPose> {
|
|
|
9927
10884
|
/** Projection between `TPose` and bounds. Defaults to `RECT_POSE_DESCRIPTOR`
|
|
9928
10885
|
* for `{x,y,width,height}` poses. Pass `pathPoseDescriptor` for `Path`
|
|
9929
10886
|
* poses so polygon coords translate correctly. */
|
|
9930
|
-
geometry?:
|
|
10887
|
+
geometry?: PoseDescriptor<TPose>;
|
|
9931
10888
|
/** Label passed to applyOps. Default 'Align'. */
|
|
9932
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>;
|
|
9933
10893
|
}
|
|
9934
10894
|
/** Return shape of `useAlign`. */
|
|
9935
10895
|
interface UseAlignReturn {
|
|
9936
10896
|
/** Imperative trigger. No-op when fewer than 2 items selected. */
|
|
9937
10897
|
align(edge: AlignEdge): void;
|
|
9938
10898
|
}
|
|
9939
|
-
/**
|
|
9940
|
-
* The pose's *visual* bounds: its descriptor bounds expanded to cover the
|
|
9941
|
-
* rotated rectangle, so a turned shape reports the extent of its ink rather
|
|
9942
|
-
* than the box it was posed in. Align, distribute and flip all fold these.
|
|
9943
|
-
*
|
|
9944
|
-
* Both ends of an align must use it — a visual union measured against
|
|
9945
|
-
* unrotated member boxes misplaces every rotated member. The expanded box
|
|
9946
|
-
* shares its centre with the stored one, so the delta stays a translation of
|
|
9947
|
-
* the stored pose and no re-posing is needed.
|
|
9948
|
-
*/
|
|
9949
|
-
declare function visualBoundsViaDescriptor<TPose>(pose: TPose, geometry: PoseProjection<TPose>): ResizePose;
|
|
9950
10899
|
/** Compute the (dx, dy) translation that moves AABB `b` so that the requested
|
|
9951
10900
|
* `edge`/center matches the corresponding feature of the union AABB `u`. */
|
|
9952
|
-
declare function alignDeltaFor(b:
|
|
10901
|
+
declare function alignDeltaFor(b: Bounds, u: Bounds, edge: AlignEdge): {
|
|
9953
10902
|
dx: number;
|
|
9954
10903
|
dy: number;
|
|
9955
10904
|
};
|
|
9956
|
-
/** Translate `pose` by `(dx, dy)` using `geometry.translate` if available,
|
|
9957
|
-
* otherwise via `remapBounds` with a translated `dst` rect. */
|
|
9958
|
-
declare function translatePoseViaDescriptor<TPose>(pose: TPose, dx: number, dy: number, geometry: PoseProjection<TPose>): TPose;
|
|
9959
10905
|
/** Align the current multi-selection to a shared edge or center of the
|
|
9960
10906
|
* selection's union AABB. No-op when fewer than 2 items selected.
|
|
9961
|
-
* 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. */
|
|
9962
10911
|
declare function useAlign<TPose>(adapter: AlignAdapter<TPose>, options?: UseAlignOptions<TPose>): UseAlignReturn;
|
|
9963
10912
|
|
|
9964
10913
|
/** Axis along which selection is distributed. `'x'` spreads horizontally. */
|
|
@@ -9970,18 +10919,25 @@ type DistributeMode = 'centers' | 'gaps';
|
|
|
9970
10919
|
/** Adapter for `useDistribute`. */
|
|
9971
10920
|
interface DistributeAdapter<TPose> {
|
|
9972
10921
|
getSelection(): NodeId[];
|
|
10922
|
+
/** The pose as stored — local to the node's parent. */
|
|
9973
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;
|
|
9974
10927
|
applyOps?(ops: Op[], label?: string): void;
|
|
9975
10928
|
}
|
|
9976
10929
|
/** Options for `useDistribute`. */
|
|
9977
10930
|
interface UseDistributeOptions<TPose> {
|
|
9978
10931
|
/** Projection between `TPose` and bounds. Defaults to `RECT_POSE_DESCRIPTOR`
|
|
9979
10932
|
* for `{x,y,width,height}` poses. */
|
|
9980
|
-
geometry?:
|
|
10933
|
+
geometry?: PoseDescriptor<TPose>;
|
|
9981
10934
|
/** Default mode when `distribute(axis)` is called without one. Default 'centers'. */
|
|
9982
10935
|
defaultMode?: DistributeMode;
|
|
9983
10936
|
/** Label passed to applyOps. Default 'Distribute'. */
|
|
9984
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>;
|
|
9985
10941
|
}
|
|
9986
10942
|
/** Return shape of `useDistribute`. */
|
|
9987
10943
|
interface UseDistributeReturn {
|
|
@@ -9990,7 +10946,10 @@ interface UseDistributeReturn {
|
|
|
9990
10946
|
}
|
|
9991
10947
|
/** Distribute the current multi-selection along `axis`. Requires ≥3 items;
|
|
9992
10948
|
* no-op otherwise. Endpoints (min and max along the axis) stay put; the
|
|
9993
|
-
* 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. */
|
|
9994
10953
|
declare function useDistribute<TPose>(adapter: DistributeAdapter<TPose>, options?: UseDistributeOptions<TPose>): UseDistributeReturn;
|
|
9995
10954
|
|
|
9996
10955
|
/** The six Boolean path operations, each acting on the current selection and
|
|
@@ -10122,7 +11081,7 @@ interface TweenPoseOptions<TPose> {
|
|
|
10122
11081
|
easing?: EasingSpec;
|
|
10123
11082
|
/** Pose descriptor with a `lerp(from, to, t)` method. Defaults to
|
|
10124
11083
|
* `RECT_POSE_DESCRIPTOR`, which interpolates x/y/width/height linearly. */
|
|
10125
|
-
geometry?:
|
|
11084
|
+
geometry?: PoseDescriptor<TPose>;
|
|
10126
11085
|
/** When true (default), emit a transform op before the tween so undo
|
|
10127
11086
|
* restores the pre-animation pose. */
|
|
10128
11087
|
recordOp?: boolean;
|
|
@@ -10138,7 +11097,7 @@ interface SpringPoseOptions<TPose> {
|
|
|
10138
11097
|
stiffness?: number;
|
|
10139
11098
|
damping?: number;
|
|
10140
11099
|
mass?: number;
|
|
10141
|
-
geometry?:
|
|
11100
|
+
geometry?: PoseDescriptor<TPose>;
|
|
10142
11101
|
recordOp?: boolean;
|
|
10143
11102
|
opLabel?: string;
|
|
10144
11103
|
onDone?: () => void;
|
|
@@ -10173,7 +11132,7 @@ interface AnimateOnSetPoseOptions<TPose> {
|
|
|
10173
11132
|
damping?: number;
|
|
10174
11133
|
mass?: number;
|
|
10175
11134
|
};
|
|
10176
|
-
geometry?:
|
|
11135
|
+
geometry?: PoseDescriptor<TPose>;
|
|
10177
11136
|
/** Predicate: return false to skip animation and write through immediately. */
|
|
10178
11137
|
shouldAnimate?: (id: string, from: TPose, to: TPose) => boolean;
|
|
10179
11138
|
/** Convenience: when true, auto-skip animation if the id is currently being
|
|
@@ -10214,7 +11173,7 @@ interface LifecycleAnimation<TPose> {
|
|
|
10214
11173
|
exitTo?: (current: TPose) => TPose;
|
|
10215
11174
|
ms?: number;
|
|
10216
11175
|
easing?: EasingSpec;
|
|
10217
|
-
geometry?:
|
|
11176
|
+
geometry?: PoseDescriptor<TPose>;
|
|
10218
11177
|
}
|
|
10219
11178
|
/** Wrap an adapter so inserts and removals animate — the scene-graph
|
|
10220
11179
|
* equivalent of CSS enter/leave transitions. */
|
|
@@ -10259,6 +11218,8 @@ interface MomentumOptions {
|
|
|
10259
11218
|
* decays the velocity). Default 'stop'.
|
|
10260
11219
|
*/
|
|
10261
11220
|
boundary?: 'stop' | 'continue';
|
|
11221
|
+
/** How to translate poses. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
11222
|
+
poseDescriptor?: PoseDescriptor<unknown>;
|
|
10262
11223
|
}
|
|
10263
11224
|
/**
|
|
10264
11225
|
* Move behavior that keeps a dragged node coasting after the pointer is
|
|
@@ -10730,43 +11691,6 @@ declare function CropIcon(): react_jsx_runtime.JSX.Element;
|
|
|
10730
11691
|
declare const PAINTED_CURSOR_LAYER_ID = "painted-cursor";
|
|
10731
11692
|
declare function createPaintedCursorLayer(state: PaintedCursorState): RenderLayer<unknown>;
|
|
10732
11693
|
|
|
10733
|
-
/** What the registry knows at dispatch time. */
|
|
10734
|
-
interface EligibilityState {
|
|
10735
|
-
focusedId: string | null;
|
|
10736
|
-
heldTriggers: ReadonlySet<string>;
|
|
10737
|
-
/** Ids the host reports as hotkey-engaged. A declared `offhand` registers
|
|
10738
|
-
* the binding, but `tool.offhand`'s invoker still reports engagement by
|
|
10739
|
-
* pushing an id — this retires only if that contract changes. */
|
|
10740
|
-
engagedIds?: ReadonlySet<string>;
|
|
10741
|
-
/** Whether the active mode allows these capability tags. Omitted → allow. */
|
|
10742
|
-
allows?: (tags: readonly CapabilityTag[]) => boolean;
|
|
10743
|
-
}
|
|
10744
|
-
/**
|
|
10745
|
-
* The scope tier an entry's bindings are live at, or null when none are.
|
|
10746
|
-
* Ordered hotkey > active > ambient to match the dispatcher's own walk.
|
|
10747
|
-
*/
|
|
10748
|
-
declare function liveScope(id: string, eligibility: Eligibility, state: EligibilityState): BindingScope | null;
|
|
10749
|
-
|
|
10750
|
-
/**
|
|
10751
|
-
* Every binding the entry set contributes right now, each tiered by the
|
|
10752
|
-
* entry's own declared eligibility. Entries with no live tier are omitted.
|
|
10753
|
-
*
|
|
10754
|
-
* Order is preserved: `matchSorted` sorts by specificity within a scope and
|
|
10755
|
-
* breaks ties by declaration order, so the caller's entry order decides which
|
|
10756
|
-
* of two same-specificity bindings in one tier wins.
|
|
10757
|
-
*/
|
|
10758
|
-
declare function scopeBindings(entries: Iterable<Contribution>, state: EligibilityState): ScopedBinding[];
|
|
10759
|
-
|
|
10760
|
-
/**
|
|
10761
|
-
* Concatenate contribution bundles into one registry, preserving order —
|
|
10762
|
-
* entry order decides which of two same-specificity bindings in one scope
|
|
10763
|
-
* tier wins, so it is part of the result, not an accident of it.
|
|
10764
|
-
*
|
|
10765
|
-
* Throws on a duplicate id rather than dropping one: a feature silently
|
|
10766
|
-
* losing its bindings is the failure this registry exists to make loud.
|
|
10767
|
-
*/
|
|
10768
|
-
declare function mergeContributions(...bundles: readonly Contribution[][]): Contribution[];
|
|
10769
|
-
|
|
10770
11694
|
/** Appearance of the dashed box drawn during a marquee or insert drag. */
|
|
10771
11695
|
interface InsertOverlayStyle {
|
|
10772
11696
|
fill?: string;
|
|
@@ -10775,4 +11699,4 @@ interface InsertOverlayStyle {
|
|
|
10775
11699
|
lineWidth?: number;
|
|
10776
11700
|
}
|
|
10777
11701
|
|
|
10778
|
-
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, 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 PenAnchor, PenIcon, type PenPreviewStyle, type PenScratch, type PenSubpath, PencilIcon, type PencilPoint, PickHud, type PickHudProps, type PickTopMostHitAdapter, type PinchZoomOptions, type PixelRenderPlan, type PointInPathOptions, type PointInTextPoseOpts, PointSnapBehavior, PointerProviderIfRoot, type PointerSample, type PointerSession, type PointerSessionCallbacks, type PointerSessionCancelReason, type PointerSessionOptions, type PointerStylusState, PolygonIcon, PolygonPath, type PolygonPoint, type Pose, PoseProjection, type PoseRotation, 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 SimulationForce, type SimulationNode, 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, 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, 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, createReorderOp, createReparentOp, createRotationAffordance, createScene, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, createSetDataOp, createSetLayerOp, createSetPathOp, createSetSelectionOp, createSetTextOp, createTextLayer, createTilePattern, createTransformOp, createVelocityTracker, createViewResolver, createViewportLayer, cycleVertexColors, decomposePath, defaultCommitAdapter, defaultDrawOne, defaultLabelTextRenderer, defaultNodeProperties, defaultNodeRouting, defaultVisibilityRules, defineTool, defineViewportTool, deleteScratch, deriveAlignmentGuides, deriveParallaxView, dispatchApplyBatch, dlog, domPositionToCharOffset, domToRuns, dwarn, editAnchorsAction, 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, 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, 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, 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 };
|