@weasel-js/core 1.2.0 → 1.3.0-pre.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 +1508 -0
- package/dist/{DrawCommand-uNkv5TjO.d.ts → DrawCommand-BnZyQaDc.d.ts} +6 -189
- package/dist/chunk-2KKYDDDD.js +121 -0
- package/dist/chunk-2KKYDDDD.js.map +1 -0
- package/dist/{chunk-J7LUY47N.js → chunk-3FB44DBC.js} +3 -3
- package/dist/{chunk-J7LUY47N.js.map → chunk-3FB44DBC.js.map} +1 -1
- package/dist/{chunk-CKADTCHK.js → chunk-3ZV53ZW2.js} +51 -14
- package/dist/chunk-3ZV53ZW2.js.map +1 -0
- package/dist/{chunk-ADWOB5K2.js → chunk-67KE7SDP.js} +4 -4
- package/dist/{chunk-ADWOB5K2.js.map → chunk-67KE7SDP.js.map} +1 -1
- package/dist/{chunk-CSMF654J.js → chunk-AQS4JGRA.js} +50 -7
- package/dist/chunk-AQS4JGRA.js.map +1 -0
- package/dist/{chunk-HGF5X6MZ.js → chunk-BJN5ZRIJ.js} +2 -2
- package/dist/chunk-BJN5ZRIJ.js.map +1 -0
- package/dist/{chunk-4Z6J4IVH.js → chunk-F74NVEHT.js} +14 -46
- package/dist/chunk-F74NVEHT.js.map +1 -0
- package/dist/{chunk-7KYLIC3E.js → chunk-IFOVTYAK.js} +16611 -15749
- package/dist/chunk-IFOVTYAK.js.map +1 -0
- package/dist/{chunk-UGFFCMQP.js → chunk-MXFSHJOM.js} +4 -4
- package/dist/{chunk-UGFFCMQP.js.map → chunk-MXFSHJOM.js.map} +1 -1
- package/dist/{chunk-BHVYVFGV.js → chunk-ZB7UYJVG.js} +3 -3
- package/dist/{chunk-BHVYVFGV.js.map → chunk-ZB7UYJVG.js.map} +1 -1
- package/dist/clipboard.d.ts +3 -3
- package/dist/clipboard.js +3 -3
- package/dist/clone.d.ts +2 -2
- package/dist/clone.js +3 -3
- package/dist/{geometry-C56YbnfD.d.ts → geometry-Dtt_k6Dq.d.ts} +1 -1
- package/dist/{grid-DqOi0Vgi.d.ts → grid-nnXU4VjN.d.ts} +1 -1
- package/dist/index.d.ts +1510 -1292
- package/dist/index.js +10 -10
- package/dist/insert.d.ts +3 -3
- package/dist/insert.js +1 -1
- package/dist/move.d.ts +4 -4
- package/dist/move.js +3 -3
- package/dist/{options-C6HYCKP7.d.ts → options-CdFl510T.d.ts} +1 -1
- package/dist/{path-B6MMiodD.d.ts → path-JEV2c5If.d.ts} +2 -13
- package/dist/patterns-builtin.d.ts +1 -1
- package/dist/patterns-builtin.js +1 -1
- package/dist/{pointSnapToGrid-BBtn5bus.d.ts → pointSnapToGrid-Dmthv94u.d.ts} +2 -2
- package/dist/{registry-l3JX0Z6b.d.ts → registry-BU1_3L_C.d.ts} +629 -34
- package/dist/renderer.d.ts +38 -37
- package/dist/renderer.js +10 -10
- package/dist/resize.d.ts +4 -4
- package/dist/resize.js +2 -2
- package/dist/routing.d.ts +35 -9
- package/dist/routing.js +1 -1
- package/dist/{stroke-DaxnQ-u7.d.ts → stroke-5pBwOm9s.d.ts} +41 -4
- package/dist/{types-C2R2bjxf.d.ts → types-DIQAisSG.d.ts} +99 -5
- package/dist/{types-DbysOO-2.d.ts → types-XBcDEp3Y.d.ts} +14 -9
- package/dist/{types-BhrifbZ1.d.ts → types-miXHGrZM.d.ts} +1 -1
- package/package.json +8 -6
- package/dist/chunk-4Z6J4IVH.js.map +0 -1
- package/dist/chunk-7KYLIC3E.js.map +0 -1
- package/dist/chunk-CKADTCHK.js.map +0 -1
- package/dist/chunk-CSMF654J.js.map +0 -1
- package/dist/chunk-GVCNT7UH.js +0 -47
- package/dist/chunk-GVCNT7UH.js.map +0 -1
- package/dist/chunk-HGF5X6MZ.js.map +0 -1
- package/dist/paint-types-1fUdZUaH.d.ts +0 -266
package/dist/index.d.ts
CHANGED
|
@@ -1,39 +1,42 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
|
-
import React__default, { RefObject, ReactNode, Ref, MouseEvent as MouseEvent$1, MutableRefObject } from 'react';
|
|
2
|
+
import React__default, { RefObject, ReactNode, Ref, MouseEvent as MouseEvent$1, ComponentType, MutableRefObject } from 'react';
|
|
3
3
|
import { a as ViewTransform, V as View, Z as ZoomBound, b as ZoomFactor } from './view-DSQgxBJB.js';
|
|
4
4
|
export { s as screenToWorld, v as viewToTransform, w as worldToScreen } from './view-DSQgxBJB.js';
|
|
5
|
-
import { a as UnitValue, b as UnitSystem, U as UseMoveOptions, O as OriginProjection } from './grid-
|
|
6
|
-
export { I as IMPERIAL_INCHES, M as METRIC_MM, P as PIXELS, R as RECT_ORIGIN_PROJECTION, c as Unit, f as formatUnit, g as gridSnapStrategy, p as pointToGridCell, r as resolveUnit } from './grid-
|
|
7
|
-
import { R as RenderLayer, D as Dims, a as DeviceProfile, b as DetectedDeviceFacts, C as Condition, c as Rule, d as RuleCtx, V as VisibilityRules, e as ChromeCtx, f as ChromeId, A as Action, g as DepSchema, S as SliceDep,
|
|
8
|
-
export {
|
|
9
|
-
import {
|
|
10
|
-
export {
|
|
11
|
-
import {
|
|
12
|
-
export {
|
|
5
|
+
import { a as UnitValue, b as UnitSystem, U as UseMoveOptions, O as OriginProjection } from './grid-nnXU4VjN.js';
|
|
6
|
+
export { I as IMPERIAL_INCHES, M as METRIC_MM, P as PIXELS, R as RECT_ORIGIN_PROJECTION, c as Unit, f as formatUnit, g as gridSnapStrategy, p as pointToGridCell, r as resolveUnit } from './grid-nnXU4VjN.js';
|
|
7
|
+
import { R as RenderLayer, D as Dims, a as DeviceProfile, b as DetectedDeviceFacts, C as Condition, c as Rule, d as RuleCtx, V as VisibilityRules, e as ChromeCtx, f as ChromeId, A as Action, g as ViewAnimationOptions, h as DepSchema, S as SliceDep, i as ActionsRegistry, T as Tool, j as AffordanceHit, k as Dispatcher, l as ToolDef, m as ViewportToolDef, n as AnyTool, O as OverlayPosition, o as ToolKeybinding, H as HotkeyTrigger, L as LayerHit, p as OngoingOverlay, q as ChromeState, r as SelectionApi, U as UseSelectionOptions, I as InsertExtras, B as BuiltinShapeToolId, G as GeometryProjection, s as ContentHandlerEntry, t as SvgIngestOptions, u as ActionsProp, v as Animator, w as Affordance, x as AffordanceRegion, y as AffordanceBinding, z as CommonAffordanceScratch, E as ColorOverrideRegistry, F as BooleansAdapter, J as EasingFn, K as SpringPresetName, M as SpringPreset, N as UseAnimatorOptions, P as AnimationHandle, Q as VertexColorChannel, W as SampledTrack, X as Eligibility, Y as BindingScope, Z as Contribution, _ as ScopedBinding } from './registry-BU1_3L_C.js';
|
|
8
|
+
export { $ as ALWAYS, a0 as ActionDeps, a1 as ActionDisabledReason, a2 as ActionEnabledResult, a3 as ActionEntry, a4 as ActionsProvider, a5 as ActiveToolContextProvider, a6 as ActiveToolContextProviderIfRoot, a7 as ActiveToolContextProviderProps, a8 as ActiveToolContextValue, a9 as AnimateToBoundsOptions, aa as AreaSelectDep, ab as BindingOpts, ac as BooleanOp, ad as BooleanOpResult, ae as BoundGesture, af as BuildRuleCtxArgs, ag as ClaimableGesture, ah as ClipboardDep, ai as ClipboardIngestCtx, aj as ColorOverride, ak as ColorOverrideFn, al as CustomPaintContext, am as DecayOptions, an as DepName, ao as DepRegistry, ap as DepRegistryProvider, aq as DispatcherContext, ar as DragSample, as as EditAnchorsDep, at as EventTrack, au as GestureBinding, av as IDENTITY_POSE_COMPOSITION, aw as ImmediateInvoker, ax as IngestCtx, ay as IngestionDep, az as InsertDep, aA as Interpolate, aB as InterpolatorFactory, aC as InvocationCtx, aD as Invoker, aE as KIT_SHAPE_KINDS, aF as Keyframe, aG as LassoSelectDep, aH as LayerCommandCache, aI as LayoutDep, aJ as LoopFactory, aK as LoopOptions, aL as MatchResult, aM as NEVER, aN as NestedTimeline, aO as NodeAtPointDep, aP as OngoingHandle, aQ as OngoingInvoker, aR as PhysicsHandle, aS as PhysicsOptions, aT as Point2, aU as PointerContextProvider, aV as PointerContextValue, aW as PointerWorldPos, aX as PoseAdapter, aY as PoseComposition, aZ as ResizePolicy, a_ as ResolveAllOptions, a$ as ResolveOnlyResult, b0 as ResolvedCandidate, b1 as SelectionExtendKey, b2 as SelectionMode, b3 as Selector, b4 as SnapDep, b5 as SpringOptions, b6 as StaggerBuilder, b7 as StaggerDelay, b8 as StaggerFactory, b9 as StaggerOptions, ba as StaggerPerItem, bb as StaggerSpringPoseOptions, bc as StaggerTweenOptions, bd as SvgUnpacker, be as TextEditDep, bf as TimelineHandle, bg as TimelineOptions, bh as TimelineTrack, bi as ToolCtx, bj as ToolModifiers, bk as ToolPresentation, bl as ToolSlot, bm as Track, bn as TweenLoopOptions, bo as TweenOptions, bp as UiOngoingControl, bq as VIEW_ANIMATION_KEY, br as ViewAnimationApi, bs as ViewApi, bt as ViewChannel, bu as actionBindings, bv as applyBooleanOp, bw as buildRuleCtx, bx as clipboardCopyAction, by as clipboardCutAction, bz as composeRectPose, bA as composeWorldPose, bB as createDispatcher, bC as decomposeRectPose, bD as describeRule, bE as drawLayers, bF as drawOneLayer, bG as enterTextEditAction, bH as evaluate, bI as evaluateEnabled, bJ as isLayerPainted, bK as isLayerVisible, bL as rebaseLocalPose, bM as registerContentHandler, bN as resolveParams, bO as sliceAction, bP as specificity, bQ as translateRectPose, bR as useAction, bS as useActionsRegistry, bT as useActiveToolContext, bU as useDepRegistry, bV as useDepSource, bW as useOptionalActiveToolContext, bX as useOptionalDepRegistry, bY as usePointerContext, bZ as useSelection, b_ as useViewAnimation, b$ as worldPoseLookup } from './registry-BU1_3L_C.js';
|
|
9
|
+
import { Stroke, FillStyle, TextureHandle, TilePatternSpec, GradientKind, GradStop, GradientFill, GradientUnits, MarkerKey, MarkerRef } from '@weasel-js/paint';
|
|
10
|
+
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 { R as RectPose, S as Scene, N as NodeId, a as Node$1, b as SerializedScene, U as UseSceneOptions, c as SceneRegistry, d as RegisteredOp } from './types-DIQAisSG.js';
|
|
12
|
+
export { A as AddLayerSpec, e as AddNodeSpec, C as ContainerNode, L as LayerRecord, f as LeafNode, P as PoseOverride, g as PoseOverrides, h as SerializedNode, i as SystemLayerRecord, j as SystemLayerSpec, k as UserLayerRecord, l as asNodeId } from './types-DIQAisSG.js';
|
|
13
|
+
import { B as Bounds, P as PoseProjection, V as ViewportDims } from './geometry-Dtt_k6Dq.js';
|
|
14
|
+
export { F as FitViewToBoundsOptions, R as RECT_POSE_DESCRIPTOR, a as ROTATED_POSE_DESCRIPTOR, f as fitViewToBounds } from './geometry-Dtt_k6Dq.js';
|
|
13
15
|
import { GestureSpec, BodyClassification, IngestItem } from '@weasel-js/gestures';
|
|
14
16
|
export { ClickSpec, DragSpec, DropSpec, GestureSpec, IngestItem, InputEvent, KeyHeldSpec, KeySpec, ModSpec, MultiTouchSpec, PasteSpec, TargetSpec, WheelSpec } from '@weasel-js/gestures';
|
|
15
|
-
import {
|
|
16
|
-
export { A as
|
|
17
|
-
import {
|
|
18
|
-
export {
|
|
19
|
-
import {
|
|
20
|
-
export {
|
|
21
|
-
import { M as MoveAdapter, A as AreaSelectAdapter, R as RotateAdapter, a as LassoHitMode, b as LassoSelectAdapter, c as ResizeAdapter, d as SceneAdapter, L as LayoutStrategy, e as LayerEnumerableAdapter, I as InsertAdapter, C as ClipboardSnapshot, O as OrderedAdapter, f as LayoutSnap } from './types-DbysOO-2.js';
|
|
22
|
-
export { g as ContainerBounds, D as DropTarget, h as LayoutChild, i as LayoutContainer, j as LayoutDragged, S as SnapTarget } from './types-DbysOO-2.js';
|
|
17
|
+
import { M as ModifierState, R as ResizePose, B as BoundsConstraint, P as PointSnapBehavior, L as LassoSelectBehavior, a as RotatedPose, e as RotateBehavior, S as SnapStrategy, c as ResizeAnchor, b as MoveBehavior, I as InsertBehavior } from './types-miXHGrZM.js';
|
|
18
|
+
export { A as ActionBehavior, f as AreaSelectOverlay, g as BehaviorMoveResult, h as BehaviorResult, C as CloneBehavior, i as CloneLayer, j as ClonePose, G as GestureContext, k as GroupTransform, l as InsertMoveResult, m as InsertOverlay, n as InsertPoint, o as InsertProposed, p as LassoSelectMoveResult, q as LassoSelectOverlay, r as LassoSelectPose, s as LassoSelectProposed, t as PointSnapContext, d as PointSnapFrame, u as PointSnapResult, v as PointerState, w as ResizeMoveResult, x as ResizeOverlay, y as ResizeProposed, z as RotateMoveResult, D as RotateOverlay, E as RotateProposed } from './types-miXHGrZM.js';
|
|
19
|
+
import { U as UseResizeOptions } from './pointSnapToGrid-Dmthv94u.js';
|
|
20
|
+
export { C as CORNER_ANCHORS, a as CornerAnchor, e as CornerEdge, b as CornerHandle, c as cornerPoint, d as cornerResizeHandles, h as hitCornerHandle, p as pointSnapToGrid } from './pointSnapToGrid-Dmthv94u.js';
|
|
21
|
+
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-XBcDEp3Y.js';
|
|
22
|
+
export { g as ContainerBounds, D as DropTarget, h as LayoutChild, i as LayoutContainer, j as LayoutDragged, S as SnapTarget } from './types-XBcDEp3Y.js';
|
|
23
23
|
import { D as DebugSink, a as DebugConfig, b as DebugSnapshot, c as DebugStrokes, d as DebugTheme } from './types-BHK2dkMu.js';
|
|
24
24
|
export { e as DebugFeature, f as DebugStroke, H as HandleKind, g as HitShape, R as RecordedBounds, h as RecordedHandle, i as RecordedHitbox, j as RecordedLayer, k as RecordedOrigin, l as RecordedSnap } from './types-BHK2dkMu.js';
|
|
25
|
-
import { a as PolygonPath, P as Path, b as PathFillRule, R as RectPath } from './path-
|
|
26
|
-
export { c as PATH_C, d as PATH_CMD_LENGTHS, e as PATH_L, f as PATH_M, g as PATH_Q, h as PATH_Z } from './path-B6MMiodD.js';
|
|
25
|
+
import { a as PolygonPath, P as Path, b as PathFillRule, R as RectPath } from './path-JEV2c5If.js';
|
|
27
26
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
28
|
-
import { D as DrawCommand, S as ShaderProgramHandle, P as PathDrawCommand,
|
|
29
|
-
export {
|
|
27
|
+
import { D as DrawCommand, S as ShaderProgramHandle, P as PathDrawCommand, M as Mat3$1 } from './DrawCommand-BnZyQaDc.js';
|
|
28
|
+
export { G as GroupDrawCommand, I as ImageDrawCommand, a as ShaderDrawCommand, b as ShaderUniform, T as TextDrawCommand, m as mat3 } from './DrawCommand-BnZyQaDc.js';
|
|
30
29
|
import { Op, HistorySelection, CreateHistoryOptions, History } from '@weasel-js/history';
|
|
31
30
|
export * from '@weasel-js/history';
|
|
32
31
|
export { Op } from '@weasel-js/history';
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
import { TextRenderer, TextPose, StyledRun, TextStyle, TextPaint, TextVerticalAlign } from '@weasel-js/text';
|
|
33
|
+
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';
|
|
34
|
+
import { S as ShaderProgram } from './stroke-5pBwOm9s.js';
|
|
35
|
+
export { I as ImageMinification, b as SpriteSheet, f as frameRect, r as resolveStrokeWidth, v as viewToMat3 } from './stroke-5pBwOm9s.js';
|
|
36
|
+
import { Rect, Mat3 } from '@weasel-js/geom';
|
|
37
|
+
export { PATH_C, PATH_CMD_LENGTHS, PATH_L, PATH_M, PATH_Q, PATH_Z, Rect, pathCommandCoordCount } from '@weasel-js/geom';
|
|
35
38
|
import { G as Guide } from './types-D2tTKEU0.js';
|
|
36
|
-
export { U as UseInsertOptions } from './options-
|
|
39
|
+
export { U as UseInsertOptions } from './options-CdFl510T.js';
|
|
37
40
|
export { UseClipboardOpsOptions, UseClipboardOpsReturn, WEASEL_CLIPBOARD_MIME, WEASEL_CLIPBOARD_MIME_WEB, buildWeaselClipboardText, embedWeaselMetadataInSvg, extractWeaselClipboardFromSvg, parseWeaselClipboardText, sniffWeaselClipboardText, useClipboardOps } from './clipboard.js';
|
|
38
41
|
export { cloneByAltDrag } from './clone.js';
|
|
39
42
|
export { FontVariant, LocalFontOutlinesResult, OutlineFontStyle, OutlineSource, OutlineStatus, OutlineVariant, canQueryLocalFonts, enableLocalFontOutlines, hasFontOutlines, isCanvasFont, listFontOutlines, outlineStatus, registerCanvasFont, registerFont, registerFontOutlines, subscribeGlyphReady, unregisterCanvasFont, unregisterFontOutlines } from '@weasel-js/font';
|
|
@@ -552,6 +555,71 @@ declare const DEFAULT_VELOCITY_DECAY = 0.4;
|
|
|
552
555
|
*/
|
|
553
556
|
declare function useSimulation<TNode extends SimulationNode>(opts: UseSimulationOptions<TNode>): Simulation<TNode>;
|
|
554
557
|
|
|
558
|
+
/**
|
|
559
|
+
* `useNodeOverlayFrame` — the coordinate frame a DOM overlay pinned to one
|
|
560
|
+
* scene node needs: the node's world box, the projection from that box's
|
|
561
|
+
* frame into overlay pixels, and the overlay's measured size.
|
|
562
|
+
*
|
|
563
|
+
* This is the frame half of `subscribeView`'s "DOM pinned to world
|
|
564
|
+
* coordinates" case. Consumers positioning chrome over a node — gradient
|
|
565
|
+
* handles, a badge, a caret — otherwise re-derive it, and the
|
|
566
|
+
* translate-and-scale inverse that derivation usually reaches for drops
|
|
567
|
+
* `pose.rotation`, so the chrome sits where the node would be unrotated.
|
|
568
|
+
*
|
|
569
|
+
* `toScreen` maps the node's **unrotated world box** frame, which is the
|
|
570
|
+
* frame `fillInPoseFrame` resolves a `units: 'bounds'` paint into and the
|
|
571
|
+
* one `pathInPoseFrame` projects geometry into. Rotation lives in this hook,
|
|
572
|
+
* not in those: a node's stored geometry is pre-rotation by definition.
|
|
573
|
+
*/
|
|
574
|
+
|
|
575
|
+
/** Structural point, matching every other `{ x, y }` the kit passes across a
|
|
576
|
+
* boundary. */
|
|
577
|
+
interface OverlayPoint {
|
|
578
|
+
x: number;
|
|
579
|
+
y: number;
|
|
580
|
+
}
|
|
581
|
+
/** The overlay frame for one node. `null` from the hook means there is no
|
|
582
|
+
* frame yet — no node, or nothing measured to draw it on. */
|
|
583
|
+
interface NodeOverlayFrame {
|
|
584
|
+
/** The node's composed world box, **unrotated**: the frame `toScreen` maps
|
|
585
|
+
* from, and the box to hand `fillInPoseFrame` / `fillToBoundsFrame`. */
|
|
586
|
+
box: {
|
|
587
|
+
x: number;
|
|
588
|
+
y: number;
|
|
589
|
+
width: number;
|
|
590
|
+
height: number;
|
|
591
|
+
};
|
|
592
|
+
/** Node box frame → overlay pixels, rotation and view included. */
|
|
593
|
+
toScreen: (p: OverlayPoint) => OverlayPoint;
|
|
594
|
+
/** Overlay pixels → node box frame. Inverts `toScreen`. */
|
|
595
|
+
toLocal: (p: OverlayPoint) => OverlayPoint;
|
|
596
|
+
/** The container's size in CSS pixels — the overlay's own box. */
|
|
597
|
+
width: number;
|
|
598
|
+
height: number;
|
|
599
|
+
}
|
|
600
|
+
interface UseNodeOverlayFrameOptions<TPose> {
|
|
601
|
+
/**
|
|
602
|
+
* Current viewport. A thunk is re-read on every projection, which is what
|
|
603
|
+
* an uncontrolled `SceneCanvas` needs — its camera lives in a ref and moves
|
|
604
|
+
* without a render, so pass the handle's `getView`. A plain `View` is the
|
|
605
|
+
* value from the render that supplied it, correct for a controlled
|
|
606
|
+
* consumer. Omit it and world units are handed through as screen pixels.
|
|
607
|
+
*/
|
|
608
|
+
view?: View | (() => View);
|
|
609
|
+
/** Fold a child pose into its parent's frame. Default `composeRectPose`. */
|
|
610
|
+
compose?: (parent: TPose, child: TPose) => TPose;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Resolve the overlay frame for `nodeId` against `containerRef` — the element
|
|
614
|
+
* the overlay is positioned in, which must be the canvas's own box for the
|
|
615
|
+
* projection to land.
|
|
616
|
+
*
|
|
617
|
+
* Returns `null` when there is no node under `nodeId`, when the container has
|
|
618
|
+
* not been measured, or when the view collapses an axis to zero — the three
|
|
619
|
+
* states in which an overlay has nothing to draw.
|
|
620
|
+
*/
|
|
621
|
+
declare function useNodeOverlayFrame<TData, TLayer extends string, TPose extends RectPose>(scene: Scene<TData, TLayer, TPose>, containerRef: RefObject<HTMLElement | null>, nodeId: string | null | undefined, options?: UseNodeOverlayFrameOptions<TPose>): NodeOverlayFrame | null;
|
|
622
|
+
|
|
555
623
|
/**
|
|
556
624
|
* Stylus / Pencil pointer-event helpers.
|
|
557
625
|
*
|
|
@@ -888,7 +956,7 @@ interface CanvasSizeSnapshot extends CanvasSize {
|
|
|
888
956
|
* so dragging a window to a different-density display without resizing it
|
|
889
957
|
* left the snapshot stale. The profile watches a re-armed resolution media
|
|
890
958
|
* query instead. */
|
|
891
|
-
declare function useCanvasSize(containerRef: RefObject<
|
|
959
|
+
declare function useCanvasSize(containerRef: RefObject<HTMLElement | null>): CanvasSizeSnapshot;
|
|
892
960
|
|
|
893
961
|
/**
|
|
894
962
|
* Handle/hit multiplier applied on a coarse pointer.
|
|
@@ -918,25 +986,23 @@ declare function resolveDeviceProfile(detected: DetectedDeviceFacts, overrides?:
|
|
|
918
986
|
declare const DEFAULT_DEVICE_PROFILE: DeviceProfile;
|
|
919
987
|
|
|
920
988
|
/**
|
|
921
|
-
* Base sizes for grabbable chrome, in CSS pixels at `targetScale = 1
|
|
922
|
-
*
|
|
923
|
-
* These were six separate literal `8`s and one `24` scattered across
|
|
924
|
-
* `SceneCanvas`, `features/selection/overlay`, `affordances/cornerResize`,
|
|
925
|
-
* `canvas/affordanceAt`, and `interactions/actions/rotate/handle`. They are
|
|
926
|
-
* consolidated here because paint and hit-test MUST scale together: chrome
|
|
927
|
-
* you can see but cannot grab is the exact failure `chrome-caps` exists to
|
|
928
|
-
* make impossible, and duplicated literals in five files is how that failure
|
|
929
|
-
* gets reintroduced.
|
|
989
|
+
* Base sizes for grabbable chrome, in CSS pixels at `targetScale = 1`, and the
|
|
990
|
+
* one accessor that resolves them for a live pointer type.
|
|
930
991
|
*
|
|
931
|
-
*
|
|
932
|
-
* is
|
|
992
|
+
* Paint and hit-test MUST scale together: chrome you can see but cannot grab
|
|
993
|
+
* is the exact failure `chrome-caps` exists to make impossible, and a literal
|
|
994
|
+
* `8` copied into a fifth file is how that failure gets reintroduced. So every
|
|
995
|
+
* kit-internal use site goes through {@link targetSizesPx} — the selection
|
|
996
|
+
* overlay's handle size, `buildAffordanceAt`'s hit radii, and the slops debug
|
|
997
|
+
* overlay all read the same object. The bare constants below stay exported for
|
|
998
|
+
* consumers, who get the unscaled numbers they always got.
|
|
933
999
|
*/
|
|
934
1000
|
/** Selection corner-handle visual size and hit radius. */
|
|
935
|
-
declare const HANDLE_BASE_PX
|
|
1001
|
+
declare const HANDLE_BASE_PX: 8;
|
|
936
1002
|
/** Path anchor / control-point hit radius. */
|
|
937
|
-
declare const ANCHOR_HIT_BASE_PX
|
|
1003
|
+
declare const ANCHOR_HIT_BASE_PX: 8;
|
|
938
1004
|
/** Distance from a selection's top edge to the rotation handle's center. */
|
|
939
|
-
declare const ROTATION_HANDLE_BASE_PX
|
|
1005
|
+
declare const ROTATION_HANDLE_BASE_PX: 24;
|
|
940
1006
|
|
|
941
1007
|
/**
|
|
942
1008
|
* Read the ambient device profile.
|
|
@@ -1327,10 +1393,9 @@ declare function buildChromeCtx(args: BuildChromeCtxArgs): ChromeCtx;
|
|
|
1327
1393
|
/**
|
|
1328
1394
|
* useHoverTracking — last-hovered NodeId for chrome-caps rules.
|
|
1329
1395
|
*
|
|
1330
|
-
* Attaches a `pointermove` listener to the supplied canvas; on each
|
|
1331
|
-
*
|
|
1332
|
-
* `
|
|
1333
|
-
* `pointerleave` (pointer left the canvas → nothing is hovered).
|
|
1396
|
+
* Attaches a `pointermove` listener to the supplied canvas; on each move it
|
|
1397
|
+
* runs the supplied `nodeAtClientPoint` and caches the resulting id on a ref.
|
|
1398
|
+
* Cleared on `pointerleave` (pointer left the canvas → nothing is hovered).
|
|
1334
1399
|
*
|
|
1335
1400
|
* Returns a stable getter — call once per frame from `buildChromeCtx`.
|
|
1336
1401
|
*
|
|
@@ -1342,13 +1407,11 @@ declare function buildChromeCtx(args: BuildChromeCtxArgs): ChromeCtx;
|
|
|
1342
1407
|
/** Options for `useHoverTracking`. */
|
|
1343
1408
|
interface UseHoverTrackingArgs {
|
|
1344
1409
|
canvasRef: RefObject<HTMLCanvasElement | null>;
|
|
1345
|
-
/**
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
/** Topmost-id resolver. Returns null when the world point hits nothing. */
|
|
1351
|
-
getNodeAtPoint: (worldX: number, worldY: number) => {
|
|
1410
|
+
/** Topmost id under a client point, or null. One lookup rather than a
|
|
1411
|
+
* client→world thunk beside a world-space picker: a screen-pixel pick
|
|
1412
|
+
* tolerance converts against the camera the point resolved to, and two
|
|
1413
|
+
* thunks are two chances to disagree about which view that is. */
|
|
1414
|
+
nodeAtClientPoint: (clientX: number, clientY: number) => {
|
|
1352
1415
|
id: NodeId;
|
|
1353
1416
|
} | null;
|
|
1354
1417
|
enabled?: boolean;
|
|
@@ -1404,22 +1467,29 @@ declare function actionShortcuts(action: Action): readonly ActionShortcut[];
|
|
|
1404
1467
|
* Mirrors the per-frame translate semantics of the `useMove` hook:
|
|
1405
1468
|
* - `start`: capture origin poses for all selected nodes; record the
|
|
1406
1469
|
* current drag delta in scratch each frame.
|
|
1407
|
-
* - `onMove`: update the in-scratch `currentDelta
|
|
1408
|
-
*
|
|
1470
|
+
* - `onMove`: update the in-scratch `currentDelta`, and publish the frame's
|
|
1471
|
+
* poses as ephemeral overrides. No *document* writes, so the undo stack
|
|
1472
|
+
* still sees one entry for the whole drag.
|
|
1409
1473
|
* - `onEnd('commit')`: emit the final delta as transform ops and route
|
|
1410
1474
|
* them through the consumer `applyOps` hook when present, else
|
|
1411
1475
|
* `scene.applyBatch(ops, 'Move', adapter)` — either way a single batch
|
|
1412
1476
|
* → exactly one undo entry for the whole drag.
|
|
1413
|
-
* - `onEnd('cancel')`:
|
|
1414
|
-
* the
|
|
1477
|
+
* - `onEnd('cancel')`: drop the overrides — the document was never mutated,
|
|
1478
|
+
* so the committed poses are the restoration.
|
|
1415
1479
|
*
|
|
1416
|
-
* ## Why no per-frame
|
|
1480
|
+
* ## Why no per-frame document writes
|
|
1417
1481
|
*
|
|
1418
1482
|
* `Scene.setPose` calls `executeAndLog`, which immediately records an undo
|
|
1419
|
-
* entry on the scene's history engine. Per-frame writes during drag would
|
|
1420
|
-
* O(frames) history entries
|
|
1421
|
-
*
|
|
1422
|
-
*
|
|
1483
|
+
* entry on the scene's history engine. Per-frame writes during drag would
|
|
1484
|
+
* create O(frames) history entries, so the drag commits one
|
|
1485
|
+
* `createTransformOp` batch at the end.
|
|
1486
|
+
*
|
|
1487
|
+
* The per-frame poses still go *somewhere* the scene can see: the ephemeral
|
|
1488
|
+
* override table, which bypasses history entirely. That is what lets a node
|
|
1489
|
+
* deriving its geometry from a dragged one follow the drag — `scenePoseLookup`
|
|
1490
|
+
* and the pick source both read overrides, and neither can see this action's
|
|
1491
|
+
* scratch. Keeping the frame in scratch alone is why the edge used to stay
|
|
1492
|
+
* anchored to the old endpoint and jump on drop.
|
|
1423
1493
|
*
|
|
1424
1494
|
* The behavior pipeline (snap-to-grid, snap-back-or-delete, snap-to-container,
|
|
1425
1495
|
* etc.) via `opts.behaviors` from `BindingOpts` IS wired: `start` builds a
|
|
@@ -1828,7 +1898,10 @@ declare const viewportDragPanAction: Action & {
|
|
|
1828
1898
|
*
|
|
1829
1899
|
* ## Bindings (parametric — each passes `params.kind`)
|
|
1830
1900
|
* - `{ kind: 'wheel', mods: { mod: true } }` → Cmd+wheel, params: `{ kind: 'wheel' }`
|
|
1831
|
-
*
|
|
1901
|
+
* - `{ kind: 'wheel', mods: { ctrl: true } }` → trackpad pinch, params: `{ kind: 'wheel' }`.
|
|
1902
|
+
* Browsers synthesize a trackpad pinch as ctrl+wheel. On a Mac that is a
|
|
1903
|
+
* *different* event from the `mod` binding above (`mod` is metaKey there), so
|
|
1904
|
+
* pinch needs its own binding or nothing claims it and the page zooms instead.
|
|
1832
1905
|
* - `{ kind: 'key', key: '=' }` → zoom in, params: `{ kind: 'in' }`
|
|
1833
1906
|
* - `{ kind: 'key', key: '-' }` → zoom out, params: `{ kind: 'out' }`
|
|
1834
1907
|
* - `{ kind: 'key', key: '0' }` → reset zoom, params: `{ kind: 'reset' }`
|
|
@@ -1842,13 +1915,27 @@ declare const viewportDragPanAction: Action & {
|
|
|
1842
1915
|
* - `'in'`/`'out'`: step zoom by ×1.25 / ×0.8, anchored at the host center
|
|
1843
1916
|
* when the `view` dep wires `hostSize()` (SceneCanvas does), falling back
|
|
1844
1917
|
* to the canvas top-left origin for consumers that don't.
|
|
1845
|
-
* - `'reset'`: resets scale to 1, translation to 0
|
|
1918
|
+
* - `'reset'`: resets scale to 1, translation to 0, or calls the `view` dep's
|
|
1919
|
+
* `recenter()`.
|
|
1920
|
+
*
|
|
1921
|
+
* The three discrete branches glide instead of jumping when the `animate`
|
|
1922
|
+
* option is configured and the `view` dep implements `animate` — they hand the
|
|
1923
|
+
* action a target and nothing in between, which is the whole condition for
|
|
1924
|
+
* tweening. `'wheel'` always jumps per sample.
|
|
1846
1925
|
*
|
|
1847
1926
|
* ## Key binding modifier notes
|
|
1848
1927
|
* The key bindings (`=`, `-`, `0`) require `mod: true` (Cmd on Mac, Ctrl elsewhere).
|
|
1849
1928
|
* This matches the behaviour of the dissolved `useKeyboardZoomTool`.
|
|
1850
1929
|
*/
|
|
1851
1930
|
|
|
1931
|
+
/**
|
|
1932
|
+
* @experimental
|
|
1933
|
+
* Tuning for the animated form of the discrete zoom steps.
|
|
1934
|
+
*/
|
|
1935
|
+
interface ViewportZoomAnimateOptions extends ViewAnimationOptions {
|
|
1936
|
+
/** Duration for the Cmd+0 reset branch. Defaults to `ms`. */
|
|
1937
|
+
resetMs?: number;
|
|
1938
|
+
}
|
|
1852
1939
|
/**
|
|
1853
1940
|
* @experimental
|
|
1854
1941
|
* Tuning for {@link makeViewportZoomAction}.
|
|
@@ -1857,7 +1944,8 @@ interface ViewportZoomOptions {
|
|
|
1857
1944
|
/**
|
|
1858
1945
|
* Which wheel gesture triggers zoom.
|
|
1859
1946
|
* - `'mod'` (default): Cmd/Ctrl+wheel — coexists with plain-wheel pan
|
|
1860
|
-
* (`viewport.wheelPan`)
|
|
1947
|
+
* (`viewport.wheelPan`). A Mac trackpad pinch arrives as ctrl+wheel, which
|
|
1948
|
+
* `mod: true` forbids on Mac; nothing here handles it.
|
|
1861
1949
|
* - `'plain'`: bare wheel, no modifier. Pair with `viewport.pan: false`,
|
|
1862
1950
|
* since plain wheel otherwise drives pan and the two would compete.
|
|
1863
1951
|
*/
|
|
@@ -1866,6 +1954,13 @@ interface ViewportZoomOptions {
|
|
|
1866
1954
|
min?: number;
|
|
1867
1955
|
/** Upper clamp on the resulting view scale, forwarded to `zoomAt`. Default 8. */
|
|
1868
1956
|
max?: number;
|
|
1957
|
+
/**
|
|
1958
|
+
* Glide the discrete steps (Cmd+=, Cmd+-, Cmd+0) instead of jumping.
|
|
1959
|
+
* `true` uses the kit defaults; an object tunes them. Wheel and pinch never
|
|
1960
|
+
* animate — their input already samples every frame. Requires a `view` dep
|
|
1961
|
+
* that implements `animate`; without one this is ignored.
|
|
1962
|
+
*/
|
|
1963
|
+
animate?: boolean | ViewportZoomAnimateOptions;
|
|
1869
1964
|
}
|
|
1870
1965
|
/**
|
|
1871
1966
|
* @experimental
|
|
@@ -2013,12 +2108,31 @@ declare const lassoSelectAction: Action & {
|
|
|
2013
2108
|
|
|
2014
2109
|
/**
|
|
2015
2110
|
* @experimental
|
|
2016
|
-
*
|
|
2111
|
+
* Tuning for {@link makePinchZoomAction}.
|
|
2112
|
+
*/
|
|
2113
|
+
interface PinchZoomOptions {
|
|
2114
|
+
/** Lower clamp on the resulting view scale, forwarded to `zoomAt`. Default 0.1. */
|
|
2115
|
+
min?: number;
|
|
2116
|
+
/** Upper clamp on the resulting view scale, forwarded to `zoomAt`. Default 8. */
|
|
2117
|
+
max?: number;
|
|
2118
|
+
}
|
|
2119
|
+
/**
|
|
2120
|
+
* @experimental
|
|
2121
|
+
* Build a `viewport.pinchZoom` Action descriptor with a configurable scale
|
|
2122
|
+
* clamp. The binding (two-finger multitouch) is fixed; only the clamp varies.
|
|
2017
2123
|
*
|
|
2018
2124
|
* Requires dep-schema entries: `view`.
|
|
2019
2125
|
*
|
|
2020
2126
|
* The invoker is `ongoing`. Zoom is applied per-frame via `view.set(zoomAt(...))`.
|
|
2021
2127
|
*/
|
|
2128
|
+
declare function makePinchZoomAction(opts?: PinchZoomOptions): Action & {
|
|
2129
|
+
requires: string[];
|
|
2130
|
+
};
|
|
2131
|
+
/**
|
|
2132
|
+
* @experimental
|
|
2133
|
+
* Default `viewport.pinchZoom` descriptor: two-finger pinch with the kit's
|
|
2134
|
+
* default 0.1–8 scale clamp. Equivalent to `makePinchZoomAction()`.
|
|
2135
|
+
*/
|
|
2022
2136
|
declare const pinchZoomAction: Action & {
|
|
2023
2137
|
requires: string[];
|
|
2024
2138
|
};
|
|
@@ -2143,6 +2257,14 @@ interface DispatcherViewTarget {
|
|
|
2143
2257
|
* routing correct.
|
|
2144
2258
|
*/
|
|
2145
2259
|
deps?: () => Partial<DepSchema>;
|
|
2260
|
+
/**
|
|
2261
|
+
* This view's chrome-caps rule context, for the eligibility filter. The rule
|
|
2262
|
+
* table is the surface's, but a rule keyed on selection or the in-flight
|
|
2263
|
+
* action answers per view — so an action hidden in one panel must not
|
|
2264
|
+
* decline a gesture in another. `undefined` means "nothing gates here", the
|
|
2265
|
+
* same answer a surface with no mode registry gives.
|
|
2266
|
+
*/
|
|
2267
|
+
getRuleCtx?: () => RuleCtx | undefined;
|
|
2146
2268
|
}
|
|
2147
2269
|
/**
|
|
2148
2270
|
* The part of `features/viewports`' `ViewResolver` the dispatcher needs: which
|
|
@@ -2286,7 +2408,7 @@ interface UseGestureDispatcherOptions {
|
|
|
2286
2408
|
* `Action.eligible` rule (omitted => always eligible). `<SceneCanvas>`
|
|
2287
2409
|
* wires this; tests / harnesses without chrome-caps state can omit it.
|
|
2288
2410
|
*/
|
|
2289
|
-
getRuleCtx?: () => RuleCtx;
|
|
2411
|
+
getRuleCtx?: () => RuleCtx | undefined;
|
|
2290
2412
|
/**
|
|
2291
2413
|
* Routing for a canvas hosting more than one view: the non-root dispatch
|
|
2292
2414
|
* records to choose between, read fresh per event, and the resolver that
|
|
@@ -2317,6 +2439,56 @@ interface UseGestureDispatcherOptions {
|
|
|
2317
2439
|
*/
|
|
2318
2440
|
declare function useGestureDispatcher(opts: UseGestureDispatcherOptions): void;
|
|
2319
2441
|
|
|
2442
|
+
/**
|
|
2443
|
+
* The one place weasel decides whether a frame may run, so that "a loop does no
|
|
2444
|
+
* work nobody can see" holds by construction rather than by every loop author
|
|
2445
|
+
* remembering. Nothing runs while the document is hidden; a loop that names an
|
|
2446
|
+
* element also stops while that element is outside the viewport.
|
|
2447
|
+
*
|
|
2448
|
+
* A request made while suspended is held, not dropped, and re-armed when the
|
|
2449
|
+
* surface comes back — so a loop never needs to poll visibility itself.
|
|
2450
|
+
*/
|
|
2451
|
+
|
|
2452
|
+
/** What a loop names as its element, resolved every time the gate is consulted
|
|
2453
|
+
* so a ref filled in after mount still starts the observer. */
|
|
2454
|
+
type VisibleRafTarget = RefObject<Element | null> | (() => Element | null);
|
|
2455
|
+
interface VisibleRafOptions {
|
|
2456
|
+
/** Also gate on this element's intersection with the viewport. Omit it and
|
|
2457
|
+
* the loop is gated on document visibility alone. */
|
|
2458
|
+
target?: VisibleRafTarget;
|
|
2459
|
+
/**
|
|
2460
|
+
* Run frames regardless of visibility. The escape hatch for a loop that is
|
|
2461
|
+
* not painting for a viewer — an offscreen recording, an export driving its
|
|
2462
|
+
* own frames. It is the wrong fix for a loop that stalls after a tab switch:
|
|
2463
|
+
* that is a missing `request()`, and setting this hides it.
|
|
2464
|
+
*/
|
|
2465
|
+
dangerouslyRunWhenHidden?: boolean;
|
|
2466
|
+
/** Frame clock. Read live, so a test may inject one after mount. */
|
|
2467
|
+
requestFrame?: (cb: FrameRequestCallback) => number;
|
|
2468
|
+
cancelFrame?: (handle: number) => void;
|
|
2469
|
+
/**
|
|
2470
|
+
* Runs once when the loop leaves suspension, before the frame that follows
|
|
2471
|
+
* it. Where a loop that measures elapsed time drops the interval it spent
|
|
2472
|
+
* suspended — without it, an hour hidden arrives as one hour-long frame.
|
|
2473
|
+
*/
|
|
2474
|
+
onResume?: () => void;
|
|
2475
|
+
}
|
|
2476
|
+
interface VisibleRaf {
|
|
2477
|
+
/** Ask for a frame. Idempotent while one is outstanding, and held rather than
|
|
2478
|
+
* dropped while suspended. Identity is stable for the component's lifetime. */
|
|
2479
|
+
request(): void;
|
|
2480
|
+
/** Drop the outstanding request, held or scheduled. */
|
|
2481
|
+
cancel(): void;
|
|
2482
|
+
/** Whether a frame would run right now. */
|
|
2483
|
+
isVisible(): boolean;
|
|
2484
|
+
}
|
|
2485
|
+
/**
|
|
2486
|
+
* @param frame Runs on the frame, with the timestamp the clock supplied.
|
|
2487
|
+
* A continuous loop calls `request()` again from inside it; a one-shot loop
|
|
2488
|
+
* does not.
|
|
2489
|
+
*/
|
|
2490
|
+
declare function useVisibleRaf(frame: (time: number) => void, options?: VisibleRafOptions): VisibleRaf;
|
|
2491
|
+
|
|
2320
2492
|
/**
|
|
2321
2493
|
* Pure wheel-event reducer. Stateless sibling of `useZoom`'s
|
|
2322
2494
|
* `onWheel` handler — useful in tests, in non-React reducers, or anywhere
|
|
@@ -2410,17 +2582,6 @@ declare function useDecayLoop(): {
|
|
|
2410
2582
|
cancel: () => void;
|
|
2411
2583
|
};
|
|
2412
2584
|
|
|
2413
|
-
/** Animate the view from where it is to a target view — zoom-to-fit,
|
|
2414
|
-
* zoom-to-selection, and anything else that should glide rather than jump. */
|
|
2415
|
-
declare function useViewTween(setView: (v: View) => void): {
|
|
2416
|
-
animateTo: (from: View, to: View, opts?: {
|
|
2417
|
-
duration?: number;
|
|
2418
|
-
easing?: (t: number) => number;
|
|
2419
|
-
}) => void;
|
|
2420
|
-
cancel: () => void;
|
|
2421
|
-
isAnimating: React$1.RefObject<boolean>;
|
|
2422
|
-
};
|
|
2423
|
-
|
|
2424
2585
|
/**
|
|
2425
2586
|
* Detects two-finger pinch on a canvas element.
|
|
2426
2587
|
*
|
|
@@ -2434,31 +2595,11 @@ declare function usePinchGesture(canvasRef: React.RefObject<HTMLCanvasElement |
|
|
|
2434
2595
|
y: number;
|
|
2435
2596
|
}, scaleFactor: number) => void, enabled?: boolean): void;
|
|
2436
2597
|
|
|
2437
|
-
/** Options accepted by {@link useViewAnimation}'s `animateToBounds`. */
|
|
2438
|
-
interface AnimateToBoundsOptions extends FitViewToBoundsOptions {
|
|
2439
|
-
/** Tween duration in ms (forwarded to `animateTo`). */
|
|
2440
|
-
duration?: number;
|
|
2441
|
-
/** Tween easing (forwarded to `animateTo`). */
|
|
2442
|
-
easing?: (t: number) => number;
|
|
2443
|
-
}
|
|
2444
2598
|
/**
|
|
2445
|
-
*
|
|
2446
|
-
*
|
|
2447
|
-
* `fitViewToBounds` with the existing tween so consumers can say "zoom to this
|
|
2448
|
-
* bounds with animation" in one call.
|
|
2449
|
-
*
|
|
2450
|
-
* `animateToBounds` needs the current `View` and the current viewport
|
|
2451
|
-
* dimensions to compute the target — both are passed as arguments so this
|
|
2452
|
-
* hook stays a leaf (no canvas-size subscription, no `View` storage).
|
|
2599
|
+
* `InterpolatorFactory<View>` for camera animation — built once per animation,
|
|
2600
|
+
* called with eased `t` each frame. Pass to `Animator.tween`'s `interpolator`.
|
|
2453
2601
|
*/
|
|
2454
|
-
declare function
|
|
2455
|
-
animateTo: (from: View, to: View, opts?: {
|
|
2456
|
-
duration?: number;
|
|
2457
|
-
easing?: (t: number) => number;
|
|
2458
|
-
}) => void;
|
|
2459
|
-
animateToBounds: (bounds: Bounds, currentView: View, viewportDims: ViewportDims, opts?: AnimateToBoundsOptions) => void;
|
|
2460
|
-
cancel: () => void;
|
|
2461
|
-
};
|
|
2602
|
+
declare function interpolateView(from: View, to: View): (t: number) => View;
|
|
2462
2603
|
|
|
2463
2604
|
/**
|
|
2464
2605
|
* Build a `Tool<TScratch>` from a declarative `ToolDef<TScratch>`.
|
|
@@ -2574,7 +2715,7 @@ interface UseKeybindingsOptions {
|
|
|
2574
2715
|
declare function useKeybindings(tools: ToolsApi, options?: UseKeybindingsOptions): void;
|
|
2575
2716
|
|
|
2576
2717
|
/** The value types a built-in pref leaf can hold. */
|
|
2577
|
-
type ToolPrefKind = 'number' | 'boolean' | 'string' | 'enum' | 'color' | 'paint';
|
|
2718
|
+
type ToolPrefKind = 'number' | 'boolean' | 'string' | 'enum' | 'color' | 'paint' | 'object';
|
|
2578
2719
|
interface ToolPrefBase<K extends string, Value> {
|
|
2579
2720
|
kind: K;
|
|
2580
2721
|
/** Human-readable label. */
|
|
@@ -2589,6 +2730,12 @@ interface ToolPrefBase<K extends string, Value> {
|
|
|
2589
2730
|
* (weasel-ui `PrefsForm` honors this for leaves whose control brings
|
|
2590
2731
|
* its own chrome). */
|
|
2591
2732
|
block?: boolean;
|
|
2733
|
+
/** Glyph naming this leaf in a host UI's icon set (weasel-ui resolves it
|
|
2734
|
+
* against `ICON_PATHS`). A plain string because core ships no icon set and
|
|
2735
|
+
* cannot depend on one. Read where a leaf's `name` has nowhere to go — a
|
|
2736
|
+
* `pair`ed row is labeled by the pair, so its fields have only the glyph
|
|
2737
|
+
* to tell them apart. */
|
|
2738
|
+
icon?: string;
|
|
2592
2739
|
/** Row-pairing hint for compact property UIs (weasel-ui
|
|
2593
2740
|
* `SelectionPanel`): leaves sharing a `pair` id render side-by-side
|
|
2594
2741
|
* on one row labeled with the `pair` string (e.g. `'Position'` for
|
|
@@ -2602,7 +2749,7 @@ type ToolPrefBooleanControl = 'checkbox' | 'switch';
|
|
|
2602
2749
|
/** How a schema-driven UI should present a string pref. */
|
|
2603
2750
|
type ToolPrefStringControl = 'input' | 'textarea';
|
|
2604
2751
|
/** How a schema-driven UI should present an enum pref. */
|
|
2605
|
-
type ToolPrefEnumControl = 'select' | 'radio';
|
|
2752
|
+
type ToolPrefEnumControl = 'select' | 'radio' | 'toggle';
|
|
2606
2753
|
/** Display-unit conversion for number leaves whose stored value uses a
|
|
2607
2754
|
* canonical unit the user shouldn't see (e.g. radians stored, degrees
|
|
2608
2755
|
* shown). The stored value stays canonical; UIs convert at the edge. */
|
|
@@ -2629,13 +2776,51 @@ interface ToolPrefBoolean extends ToolPrefBase<'boolean', boolean> {
|
|
|
2629
2776
|
interface ToolPrefString extends ToolPrefBase<'string', string> {
|
|
2630
2777
|
control?: ToolPrefStringControl;
|
|
2631
2778
|
}
|
|
2779
|
+
/**
|
|
2780
|
+
* Stored-value bridge for an enum leaf whose value is not the option string —
|
|
2781
|
+
* the counterpart of {@link ToolPrefNumberUnit}, which does the same for a
|
|
2782
|
+
* number stored in a canonical unit.
|
|
2783
|
+
*
|
|
2784
|
+
* A dash array is the case that needs it: `Stroke.dash` stores lengths, and
|
|
2785
|
+
* the thing a person chooses is a style. The presets scale by the stroke's
|
|
2786
|
+
* width, so both directions are given the object's other fields — a style is
|
|
2787
|
+
* meaningless without the width it is a multiple of.
|
|
2788
|
+
*/
|
|
2789
|
+
interface ToolPrefEnumEncoding<T extends string = string> {
|
|
2790
|
+
/**
|
|
2791
|
+
* The option `stored` reads as, or `undefined` for none — which a UI shows
|
|
2792
|
+
* the way it shows a mixed selection, by selecting nothing.
|
|
2793
|
+
*
|
|
2794
|
+
* `siblings` is the object the leaf is a field of, or `undefined` when the
|
|
2795
|
+
* node does not hold that object (and for a top-level leaf, which has none).
|
|
2796
|
+
*/
|
|
2797
|
+
read: (stored: unknown, siblings: Record<string, unknown> | undefined) => T | undefined;
|
|
2798
|
+
/** What to store for `option`. `undefined` removes the field. */
|
|
2799
|
+
write: (option: T, siblings: Record<string, unknown> | undefined) => unknown;
|
|
2800
|
+
}
|
|
2632
2801
|
/** A pref with a fixed set of labeled choices. */
|
|
2633
2802
|
interface ToolPrefEnum<T extends string = string> extends ToolPrefBase<'enum', T> {
|
|
2803
|
+
/** `short` is the label a segmented control uses when a full one would not
|
|
2804
|
+
* fit — a capital or two. `icon` names a glyph in the host UI's set
|
|
2805
|
+
* (weasel-ui resolves it against `ICON_PATHS`) and outranks `short` where
|
|
2806
|
+
* it resolves. It is a plain string because core ships no icon set and
|
|
2807
|
+
* cannot depend on one. The full `label` stays the accessible name, so
|
|
2808
|
+
* neither the abbreviation nor the glyph becomes the only thing naming
|
|
2809
|
+
* the option.
|
|
2810
|
+
*
|
|
2811
|
+
* `disabled` marks an option a control reports but cannot author — the
|
|
2812
|
+
* value a stored form reads as when it matches nothing offered. Dropping it
|
|
2813
|
+
* from the list instead would leave the control selecting nothing and
|
|
2814
|
+
* claiming the field is unset. */
|
|
2634
2815
|
options: readonly {
|
|
2635
2816
|
value: T;
|
|
2636
2817
|
label: string;
|
|
2818
|
+
short?: string;
|
|
2819
|
+
icon?: string;
|
|
2820
|
+
disabled?: boolean;
|
|
2637
2821
|
}[];
|
|
2638
2822
|
control?: ToolPrefEnumControl;
|
|
2823
|
+
encoding?: ToolPrefEnumEncoding<T>;
|
|
2639
2824
|
}
|
|
2640
2825
|
/** A single color, stored as a hex string. For a value that may also be a
|
|
2641
2826
|
* gradient or a pattern, use {@link ToolPrefPaint} instead. */
|
|
@@ -2666,13 +2851,60 @@ interface ToolPrefPaint extends ToolPrefBase<'paint', unknown> {
|
|
|
2666
2851
|
/** Offer an opacity control alongside the color. */
|
|
2667
2852
|
alpha?: boolean;
|
|
2668
2853
|
}
|
|
2854
|
+
/**
|
|
2855
|
+
* A leaf whose value is one object, with its own fields hanging off it.
|
|
2856
|
+
*
|
|
2857
|
+
* A compound value — a stroke, a shadow, a pattern spec — could be described
|
|
2858
|
+
* as several sibling leaves addressing into it (`data.stroke.width`,
|
|
2859
|
+
* `data.stroke.cap`). It shouldn't be: each control would then write one field
|
|
2860
|
+
* of a value it can only half see, and writing into something that is not an
|
|
2861
|
+
* object yet corrupts it. Here the fields are `children` of one leaf, and
|
|
2862
|
+
* every edit commits the parent object whole.
|
|
2863
|
+
*
|
|
2864
|
+
* `children` paths are relative to the object. They are ordinary leaves, so a
|
|
2865
|
+
* field that is itself a union (a stroke's `paint`) declares the kind that
|
|
2866
|
+
* edits that union. A child may also be a {@link ToolPrefGroup}, which
|
|
2867
|
+
* organises the fields under a heading without contributing to the path —
|
|
2868
|
+
* the same rule group keys follow at the top level. A `TextStyle` needs it:
|
|
2869
|
+
* its character and paragraph fields belong to one value but read as two
|
|
2870
|
+
* lists.
|
|
2871
|
+
*/
|
|
2872
|
+
interface ToolPrefObject extends ToolPrefBase<'object', unknown> {
|
|
2873
|
+
children: Record<string, ToolPrefLeaf | ToolPrefGroup>;
|
|
2874
|
+
/**
|
|
2875
|
+
* Lift a non-object value into the object form, for a consumer field that
|
|
2876
|
+
* may also be held as a scalar. Called before a child edit is applied;
|
|
2877
|
+
* without it a scalar-valued leaf shows its children empty and refuses the
|
|
2878
|
+
* edit.
|
|
2879
|
+
*/
|
|
2880
|
+
fromScalar?: (value: unknown) => Record<string, unknown>;
|
|
2881
|
+
}
|
|
2669
2882
|
/** One built-in pref leaf. `ToolPrefLeaf` widens this to include
|
|
2670
2883
|
* app-defined kinds. */
|
|
2671
|
-
type ToolPref = ToolPrefNumber | ToolPrefBoolean | ToolPrefString | ToolPrefEnum | ToolPrefColor | ToolPrefPaint;
|
|
2884
|
+
type ToolPref = ToolPrefNumber | ToolPrefBoolean | ToolPrefString | ToolPrefEnum | ToolPrefColor | ToolPrefPaint | ToolPrefObject;
|
|
2885
|
+
/**
|
|
2886
|
+
* The built-in kinds, as a table. A kind added to {@link ToolPrefKind} is a
|
|
2887
|
+
* compile error here, and from here it is one in every renderer's `never`
|
|
2888
|
+
* guard — the only thing standing between a new kind and rendering as
|
|
2889
|
+
* nothing in four places at once.
|
|
2890
|
+
*/
|
|
2891
|
+
declare const TOOL_PREF_KINDS: Record<ToolPrefKind, true>;
|
|
2892
|
+
/**
|
|
2893
|
+
* Narrows a leaf to the built-in union, so a renderer's switch discriminates
|
|
2894
|
+
* on {@link ToolPrefKind} instead of the open `string` that
|
|
2895
|
+
* {@link ToolPrefCustom} widens `kind` to. An app-defined kind answers false
|
|
2896
|
+
* and belongs to the renderer's custom-renderer path.
|
|
2897
|
+
*/
|
|
2898
|
+
declare function isBuiltinToolPref(leaf: ToolPrefLeaf): leaf is ToolPref;
|
|
2672
2899
|
/** Built-in or app-defined leaf. */
|
|
2673
2900
|
type ToolPrefLeaf = ToolPref | ToolPrefCustom;
|
|
2674
2901
|
/** Nestable group: branch nodes a tool can use to organize its prefs. */
|
|
2675
2902
|
interface ToolPrefGroup {
|
|
2903
|
+
/** Heading for the group's rows. **Empty means no heading** — for a group
|
|
2904
|
+
* that exists to organise, not to name: one whose children are themselves
|
|
2905
|
+
* groups carrying the labels a reader needs. Give it a name whenever the
|
|
2906
|
+
* name is the referent (a `Border` group over `Top` / `Right` / `Bottom`
|
|
2907
|
+
* reads as nothing without it). */
|
|
2676
2908
|
name: string;
|
|
2677
2909
|
description?: string;
|
|
2678
2910
|
children: Record<string, ToolPrefLeaf | ToolPrefGroup>;
|
|
@@ -2773,8 +3005,8 @@ declare function useSelectTool<TNode extends {
|
|
|
2773
3005
|
id: string;
|
|
2774
3006
|
}, TPose>(adapter: SelectAdapter<TNode, TPose>, options: UseSelectToolOptions<TPose>): Tool<null>;
|
|
2775
3007
|
|
|
2776
|
-
/** Options for `useRotateTool` — mostly the placement
|
|
2777
|
-
*
|
|
3008
|
+
/** Options for `useRotateTool` — mostly the placement of the rotation
|
|
3009
|
+
* handle's hover band. */
|
|
2778
3010
|
interface UseRotateToolOptions<TNode extends {
|
|
2779
3011
|
id: string;
|
|
2780
3012
|
}, _TPose> {
|
|
@@ -2784,10 +3016,10 @@ interface UseRotateToolOptions<TNode extends {
|
|
|
2784
3016
|
* backwards-compat with consumers (notably `SceneCanvas`'s
|
|
2785
3017
|
* `rotateOptions`) that still pass a value. */
|
|
2786
3018
|
rotate?: unknown;
|
|
2787
|
-
/**
|
|
3019
|
+
/** Minimum thickness of the rotate band outside the selection AABB, in
|
|
3020
|
+
* screen px. Defaults to {@link ROTATION_HANDLE_BASE_PX}; `<SceneCanvas>`
|
|
3021
|
+
* passes the device-scaled value. */
|
|
2788
3022
|
rotationHandleDistance?: number;
|
|
2789
|
-
/** Square hit-radius for the rotation handle. Default: 8. */
|
|
2790
|
-
handleHitRadius?: number;
|
|
2791
3023
|
/** World-space bounds lookup. Required for the rotation affordance hit-test
|
|
2792
3024
|
* in consumers that wire a `boundsOf` source separately from the
|
|
2793
3025
|
* ChromeState-driven affordance pipeline. Retained for parity with
|
|
@@ -2951,8 +3183,12 @@ interface PinchZoomToolOpts {
|
|
|
2951
3183
|
*
|
|
2952
3184
|
* The anchor point under the gesture midpoint stays fixed on screen as the
|
|
2953
3185
|
* view scales.
|
|
3186
|
+
*
|
|
3187
|
+
* @param getView Read at gesture time, not at render time: each pinch move
|
|
3188
|
+
* applies a per-frame delta to the view the previous move produced, and the
|
|
3189
|
+
* canvas does not re-render between them.
|
|
2954
3190
|
*/
|
|
2955
|
-
declare function usePinchZoomTool(canvasRef: React.RefObject<HTMLCanvasElement | null>,
|
|
3191
|
+
declare function usePinchZoomTool(canvasRef: React.RefObject<HTMLCanvasElement | null>, getView: () => View, setView: (v: View) => void, opts?: PinchZoomToolOpts): void;
|
|
2956
3192
|
|
|
2957
3193
|
/**
|
|
2958
3194
|
* In-progress pen anchor. `outHandle` is set when the anchor was placed via
|
|
@@ -3364,6 +3600,35 @@ interface CanvasExtensionApi {
|
|
|
3364
3600
|
* (Replaces the pre-A2 pattern where `ref.current` directly *was* the element.) */
|
|
3365
3601
|
readonly element: HTMLCanvasElement | null;
|
|
3366
3602
|
requestRedraw(): void;
|
|
3603
|
+
/**
|
|
3604
|
+
* Run `fn` after every paint, on the frame that painted — for chrome that
|
|
3605
|
+
* must observe landed pixels (a loupe readback, a frame counter). Returns
|
|
3606
|
+
* an unsubscribe.
|
|
3607
|
+
*/
|
|
3608
|
+
subscribeFrame(fn: () => void): () => void;
|
|
3609
|
+
/** The current view. Readable mid-frame — this is the value the next paint
|
|
3610
|
+
* will use, not a value from the last React commit. */
|
|
3611
|
+
getView(): View;
|
|
3612
|
+
/**
|
|
3613
|
+
* Set the view without a React render: the ref updates now and the next
|
|
3614
|
+
* frame paints with it.
|
|
3615
|
+
*
|
|
3616
|
+
* Not applied locally when the canvas is controlled by a `view` prop — there
|
|
3617
|
+
* the prop is the authority and a local write would only desynchronize
|
|
3618
|
+
* pixels from props. The value still goes out through `onViewChange`, so a
|
|
3619
|
+
* controlled owner can honor it; without an `onViewChange` it is dropped.
|
|
3620
|
+
* Either way the canvas warns once per mount.
|
|
3621
|
+
*/
|
|
3622
|
+
setView(next: View | ((current: View) => View)): void;
|
|
3623
|
+
/** Called after each view change, for chrome that mirrors the camera — a
|
|
3624
|
+
* zoom readout, a minimap, DOM pinned to world coordinates. Returns an
|
|
3625
|
+
* unsubscribe. */
|
|
3626
|
+
subscribeView(fn: (view: View) => void): () => void;
|
|
3627
|
+
/** The `contentVersion` the current pixels were painted from — on
|
|
3628
|
+
* `<SceneCanvas>`, the scene version. Chrome in lockstep with canvas
|
|
3629
|
+
* content compares this against the version it is about to render and
|
|
3630
|
+
* defers a frame when they differ. `0` until the first paint lands. */
|
|
3631
|
+
getPaintedVersion(): number;
|
|
3367
3632
|
/** Register an externally-owned RenderLayer. The layer participates in the
|
|
3368
3633
|
* draw stack and, if it implements `hitTest`, in {@link hitTestExtras}. */
|
|
3369
3634
|
registerLayer(layer: RenderLayer<unknown>): () => void;
|
|
@@ -3421,21 +3686,50 @@ interface SceneCanvasApi extends CanvasExtensionApi {
|
|
|
3421
3686
|
x: number;
|
|
3422
3687
|
y: number;
|
|
3423
3688
|
}): void;
|
|
3689
|
+
/**
|
|
3690
|
+
* Glide the camera to `to` rather than jumping there — a fit-to-selection, a
|
|
3691
|
+
* recenter, a scripted tour. A thunk receives the pending target when an
|
|
3692
|
+
* animation is already in flight, so steps compound. Any other view write
|
|
3693
|
+
* cancels it.
|
|
3694
|
+
*/
|
|
3695
|
+
animateView(to: View | ((base: View) => View), opts?: ViewAnimationOptions): void;
|
|
3696
|
+
/** Cancel a camera animation. The view stays where it is. */
|
|
3697
|
+
stopViewAnimation(): void;
|
|
3698
|
+
isViewAnimating(): boolean;
|
|
3424
3699
|
}
|
|
3425
3700
|
|
|
3426
3701
|
/**
|
|
3427
|
-
*
|
|
3702
|
+
* The seam `<Canvas>` reads in-flight gesture state through.
|
|
3428
3703
|
*
|
|
3429
3704
|
* `getGestureBounds` answers "where is the thing the user is dragging right
|
|
3430
3705
|
* now, in total?" — a question every other lookup on `CanvasHelpers` can't
|
|
3431
3706
|
* answer because they're keyed by node id, and a drag-to-insert has no node
|
|
3432
|
-
* yet. Canvas collects the parts
|
|
3433
|
-
*
|
|
3707
|
+
* yet. `<Canvas>` collects the parts named here and folds them with
|
|
3708
|
+
* `unionAABB` (`core/geometry/unionBounds`).
|
|
3434
3709
|
*
|
|
3435
|
-
* Kept free of
|
|
3436
|
-
*
|
|
3710
|
+
* Kept free of the dispatcher itself so `<Canvas>` stays dispatcher-agnostic:
|
|
3711
|
+
* it owns the `CanvasHelpers` contract, and the live gesture state lives in
|
|
3712
|
+
* the dispatcher. The overlay and preview shapes an action publishes are data,
|
|
3713
|
+
* and travel through here as such.
|
|
3437
3714
|
*/
|
|
3438
3715
|
|
|
3716
|
+
/**
|
|
3717
|
+
* A source of in-flight preview state — a tool from the tools registry, or an
|
|
3718
|
+
* `OngoingHandle` from the dispatcher's in-flight map. Readers merge several
|
|
3719
|
+
* with first-non-null semantics.
|
|
3720
|
+
*
|
|
3721
|
+
* @public
|
|
3722
|
+
*/
|
|
3723
|
+
interface GesturePreviewSource {
|
|
3724
|
+
previewIds?(): Iterable<string> | null;
|
|
3725
|
+
previewPose?(id: string): unknown;
|
|
3726
|
+
/** Companion to `previewPose` for actions that mutate node data (anchor
|
|
3727
|
+
* edits on `data.path` nodes). Absent/null falls back to committed data. */
|
|
3728
|
+
previewData?(id: string): unknown;
|
|
3729
|
+
/** Subset of `previewIds` painted at full opacity rather than as a ghost —
|
|
3730
|
+
* a layout sibling reflowing to its destination is not in flight. */
|
|
3731
|
+
previewOpaqueIds?(): Iterable<string> | null;
|
|
3732
|
+
}
|
|
3439
3733
|
/**
|
|
3440
3734
|
* Everything `<Canvas>` needs to know about in-flight gestures that it can't
|
|
3441
3735
|
* see for itself.
|
|
@@ -3467,6 +3761,13 @@ interface GestureSource {
|
|
|
3467
3761
|
subscribe(fn: () => void): () => void;
|
|
3468
3762
|
/** Monotonic counter bumped on the same events `subscribe` fires on. */
|
|
3469
3763
|
getVersion(): number;
|
|
3764
|
+
/** The in-flight handles' preview surfaces, in dispatch order. What a ghost
|
|
3765
|
+
* layer paints from — read off the draw envelope so a layer drawn for one
|
|
3766
|
+
* view cannot report another's gesture. */
|
|
3767
|
+
previewSources(): readonly GesturePreviewSource[];
|
|
3768
|
+
/** The overlay shapes the in-flight handles publish — marquee, lasso, insert
|
|
3769
|
+
* preview, raw commands. */
|
|
3770
|
+
overlays(): readonly OngoingOverlay[];
|
|
3470
3771
|
}
|
|
3471
3772
|
|
|
3472
3773
|
/**
|
|
@@ -3542,11 +3843,35 @@ interface CanvasViewHelpers<TPose> {
|
|
|
3542
3843
|
* custom layers that need overlay-aware selection state (selection ids,
|
|
3543
3844
|
* bounds, multi-union AABB, modifier flags) read from this. */
|
|
3544
3845
|
getChromeState(): ChromeState;
|
|
3846
|
+
/**
|
|
3847
|
+
* Everything publishing an in-flight preview for this view, in resolution
|
|
3848
|
+
* order: tool-side first (hotkey → active → registry → ambient), then the
|
|
3849
|
+
* handles in flight on this view's dispatcher. Readers take the first
|
|
3850
|
+
* non-null answer per id.
|
|
3851
|
+
*
|
|
3852
|
+
* A ghost layer must read this off its draw envelope rather than close over
|
|
3853
|
+
* a dispatcher: one layer array paints every view, so a closure ghosts view
|
|
3854
|
+
* zero's drag into every panel.
|
|
3855
|
+
*/
|
|
3856
|
+
getPreviewSources(): readonly GesturePreviewSource[];
|
|
3857
|
+
/** Overlay shapes this view's in-flight handles publish — marquee, lasso,
|
|
3858
|
+
* insert preview, raw commands. Same envelope rule as
|
|
3859
|
+
* {@link CanvasViewHelpers.getPreviewSources}. */
|
|
3860
|
+
getGestureOverlays(): readonly OngoingOverlay[];
|
|
3861
|
+
/**
|
|
3862
|
+
* Chrome-caps visibility predicate, keyed by chrome id. Overlay layers and
|
|
3863
|
+
* affordances call it per element to decide whether to draw / hit-test.
|
|
3864
|
+
*
|
|
3865
|
+
* The rule table is the surface's; the context it resolves against is this
|
|
3866
|
+
* view's selection, camera and in-flight action — so the predicate belongs
|
|
3867
|
+
* here rather than on {@link CanvasSurfaceHelpers}. Unwired, it is the
|
|
3868
|
+
* universal `() => true`.
|
|
3869
|
+
*/
|
|
3870
|
+
getIsVisible(): (id: string) => boolean;
|
|
3545
3871
|
}
|
|
3546
3872
|
/**
|
|
3547
3873
|
* The half of {@link CanvasHelpers} that belongs to the surface — one GL
|
|
3548
|
-
* context, one debug sink,
|
|
3549
|
-
* drawn on it.
|
|
3874
|
+
* context, one debug sink, however many views are drawn on it.
|
|
3550
3875
|
*/
|
|
3551
3876
|
interface CanvasSurfaceHelpers {
|
|
3552
3877
|
/** Active debug sink, when `<Canvas debug=...>` is enabled. Layers that
|
|
@@ -3554,11 +3879,6 @@ interface CanvasSurfaceHelpers {
|
|
|
3554
3879
|
* call into this from their `draw` callback. Returns `null` when
|
|
3555
3880
|
* debug is off — no-op for production renders. */
|
|
3556
3881
|
getDebug(): DebugSink | null;
|
|
3557
|
-
/** Chrome-caps visibility predicate, keyed by chrome id. Returns a
|
|
3558
|
-
* function that affordance/overlay layers can call per-element to
|
|
3559
|
-
* decide whether to draw / hit-test. When the parent didn't supply
|
|
3560
|
-
* a resolver, this returns the universal `() => true`. */
|
|
3561
|
-
getIsVisible(): (id: string) => boolean;
|
|
3562
3882
|
}
|
|
3563
3883
|
/** Live overlay-aware lookups exposed to custom layers via `helpersRef`.
|
|
3564
3884
|
* What a layer receives as its `data` argument, unchanged: the two halves
|
|
@@ -3568,155 +3888,335 @@ interface CanvasHelpers<TPose> extends CanvasViewHelpers<TPose>, CanvasSurfaceHe
|
|
|
3568
3888
|
}
|
|
3569
3889
|
|
|
3570
3890
|
/**
|
|
3571
|
-
*
|
|
3572
|
-
*
|
|
3891
|
+
* NodeShape — the **shape trait's** registry. Each trait of a node
|
|
3892
|
+
* (shape, routing, label, icon, affordances, …) is its own registry;
|
|
3893
|
+
* this one holds the per-kind `paint` + `silhouette` (and future
|
|
3894
|
+
* fields) used by `defaultDrawOne`, clipping, non-rect hit-testing,
|
|
3895
|
+
* and lasso/area-select.
|
|
3573
3896
|
*
|
|
3574
|
-
*
|
|
3575
|
-
*
|
|
3576
|
-
*
|
|
3577
|
-
*
|
|
3578
|
-
*
|
|
3579
|
-
* transitive leaf poses (with the same precedence rules applied per leaf).
|
|
3580
|
-
* - `createSelectionOutlineLayer` draws the outline rect for each selected
|
|
3581
|
-
* id (container ids resolve to a union AABB via `getChildren`/`isContainer`).
|
|
3582
|
-
* - `createSelectionHandlesLayer` draws resize-handle rects (default 4
|
|
3583
|
-
* corners) for each selected id, with the same container-resolution rules.
|
|
3897
|
+
* Teaching the kit about a new kind of shape goes through this registry
|
|
3898
|
+
* rather than by overriding `drawOne`. Overrides are still possible but
|
|
3899
|
+
* shouldn't be the default seam: most consumers want the same dispatch
|
|
3900
|
+
* logic, just extended with their own shape kinds (images, custom paths,
|
|
3901
|
+
* SVG fragments, etc.).
|
|
3584
3902
|
*
|
|
3585
|
-
*
|
|
3586
|
-
*
|
|
3903
|
+
* Built-in entries (`kit:text`, `kit:path`, `kit:rect-fallback`) are
|
|
3904
|
+
* registered at module load. Consumer entries added via
|
|
3905
|
+
* `registerNodeShape` join the chain; the first entry whose
|
|
3906
|
+
* `matches` predicate returns true paints the node.
|
|
3587
3907
|
*
|
|
3588
|
-
*
|
|
3589
|
-
*
|
|
3590
|
-
*
|
|
3591
|
-
*
|
|
3592
|
-
*
|
|
3908
|
+
* Two priority tiers:
|
|
3909
|
+
* - `'high'` — checked before all `'normal'` entries. Use this to
|
|
3910
|
+
* override a kit built-in for a specific data shape (e.g. a custom
|
|
3911
|
+
* text renderer that wins over `kit:text`).
|
|
3912
|
+
* - `'normal'` (default) — appended after the built-ins.
|
|
3913
|
+
*
|
|
3914
|
+
* Within a tier, entries run in registration order. Each
|
|
3915
|
+
* `registerNodeShape` call returns a disposer that removes the
|
|
3916
|
+
* entry — useful for tests, for plugin lifecycles, and for swapping
|
|
3917
|
+
* implementations at runtime.
|
|
3918
|
+
*
|
|
3919
|
+
* See `docs/superpowers/specs/2026-05-24-node-traits-reframe-design.md`
|
|
3920
|
+
* for the trait taxonomy.
|
|
3593
3921
|
*/
|
|
3594
3922
|
|
|
3595
|
-
/**
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
/**
|
|
3602
|
-
*
|
|
3603
|
-
*
|
|
3604
|
-
*
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
/** Fallback pose lookup (typically the stored/committed pose). */
|
|
3613
|
-
getStoredPose: (id: string) => TPose;
|
|
3614
|
-
/**
|
|
3615
|
-
* Project a pose into its AABB. Used when reducing a group of leaf poses
|
|
3616
|
-
* into a single union AABB. Defaults to the identity — rect-shaped poses
|
|
3617
|
-
* (`{x, y, width, height}`) need no override. For `Path` poses pass
|
|
3618
|
-
* `boundsOfPath`.
|
|
3619
|
-
*/
|
|
3620
|
-
getBounds?: (pose: TPose) => Bounds;
|
|
3621
|
-
/**
|
|
3622
|
-
* Wrap an AABB back into a TPose. Called only when the resolver collapses
|
|
3623
|
-
* a container's leaves into a single union AABB. Defaults to the identity —
|
|
3624
|
-
* for `Path` poses pass `(b) => ({ kind: 'rect', ...b })`.
|
|
3625
|
-
*/
|
|
3626
|
-
fromBounds?: (bounds: Bounds) => TPose;
|
|
3627
|
-
/** Walk a container's direct children (e.g. `scene.childrenOf`). With
|
|
3628
|
-
* `isContainer`, a selected container resolves to the union AABB of its
|
|
3629
|
-
* transitive leaf poses instead of its own stored pose. */
|
|
3630
|
-
getChildren?: (id: string) => readonly string[];
|
|
3631
|
-
/** True when `id` is a structural container. */
|
|
3632
|
-
isContainer?: (id: string) => boolean;
|
|
3923
|
+
/** Optional per-call paint context, threaded through `defaultDrawOne`'s third
|
|
3924
|
+
* argument. Lets a rendering entry point override ambient environment reads
|
|
3925
|
+
* — the headless `renderSceneToPixels` path supplies its own bitmap resolver
|
|
3926
|
+
* here so consumers reuse their own decode caches. Custom painters may
|
|
3927
|
+
* ignore it entirely. */
|
|
3928
|
+
interface NodePaintCtx {
|
|
3929
|
+
/** Override bitmap resolution for image nodes. When set it is authoritative:
|
|
3930
|
+
* the global `imageCache` is not consulted, and an `undefined` result
|
|
3931
|
+
* paints the deterministic grey placeholder outline (never the ambient
|
|
3932
|
+
* load-status error variant). */
|
|
3933
|
+
resolveImage?: (node: Node$1<unknown, string, unknown>) => ImageBitmap | undefined;
|
|
3934
|
+
/** The node's derived path, resolved by the scene-aware `drawOne` wrapper
|
|
3935
|
+
* before painting: `paint` has no scene handle, and deriving needs the
|
|
3936
|
+
* dependencies' poses. **Absent** for a node that derives from nothing —
|
|
3937
|
+
* the wrapper hands such a node the caller's own ctx untouched. `null`
|
|
3938
|
+
* means the node derives but has nothing to draw. */
|
|
3939
|
+
derivedPath?: Path | null;
|
|
3633
3940
|
}
|
|
3634
3941
|
/**
|
|
3635
|
-
*
|
|
3636
|
-
*
|
|
3637
|
-
*
|
|
3638
|
-
*
|
|
3639
|
-
*
|
|
3942
|
+
* Per-node draw function — the scene-slot `drawOne` signature shared by
|
|
3943
|
+
* `<SceneCanvas>`, `renderSceneToCanvas` and `renderSceneToPixels`, so a
|
|
3944
|
+
* consumer can reuse one callback across a main canvas and a detached view.
|
|
3945
|
+
*
|
|
3946
|
+
* Called once per node in the walk. Returned commands are world-space; the
|
|
3947
|
+
* caller applies the view transform at the group level. `ctx` is supplied by
|
|
3948
|
+
* the scene-aware wrappers — see {@link NodePaintCtx}.
|
|
3640
3949
|
*/
|
|
3641
|
-
|
|
3642
|
-
/**
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
*
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
*
|
|
3654
|
-
*
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
*
|
|
3659
|
-
*
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
/**
|
|
3694
|
-
|
|
3695
|
-
/**
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
*
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3950
|
+
type SceneViewDrawOne<TData, TLayer extends string, TPose> = (node: Node$1<TData, TLayer, TPose>, pose: TPose, view: View, ctx?: NodePaintCtx) => DrawCommand[];
|
|
3951
|
+
/** A painter for one kind of node: which nodes it claims, and the draw
|
|
3952
|
+
* commands it emits for them. Registering one is how a consumer teaches the
|
|
3953
|
+
* default renderer to draw its own node kinds. */
|
|
3954
|
+
interface NodeShapeEntry<TData = unknown, TPose = unknown> {
|
|
3955
|
+
/** Stable identifier — used for unregistration and debugging. Pick
|
|
3956
|
+
* something descriptive: `'kit:text'`, `'app:image'`, etc. */
|
|
3957
|
+
id: string;
|
|
3958
|
+
/** Returns true when this painter renders the node. The first matching
|
|
3959
|
+
* painter (`'high'` tier first, then `'normal'`) wins. */
|
|
3960
|
+
matches(node: Node$1<TData, string, TPose>): boolean;
|
|
3961
|
+
/** Emits the draw commands for the node's primary visual. `ctx` is an
|
|
3962
|
+
* optional per-call paint context (see `NodePaintCtx`); painters that
|
|
3963
|
+
* don't need it can keep a two-argument signature.
|
|
3964
|
+
*
|
|
3965
|
+
* **The returned array belongs to the painter.** Callers must treat it as
|
|
3966
|
+
* immutable and copy before appending — a painter is free to memoize its
|
|
3967
|
+
* command list (`kit:shape` and `kit:path` do), and an in-place `push`
|
|
3968
|
+
* would grow that list on every frame. `defaultDrawOne` copies before
|
|
3969
|
+
* adding its label overlay for exactly this reason. */
|
|
3970
|
+
paint(node: Node$1<TData, string, TPose>, pose: TPose, ctx?: NodePaintCtx): DrawCommand[];
|
|
3971
|
+
/** Optional: derive the node's silhouette path from its pose.
|
|
3972
|
+
* Used by clipping (when the container has no explicit
|
|
3973
|
+
* `clipFromPose`), by non-rect hit-testing, and by lasso/area-select.
|
|
3974
|
+
* Painters whose visual has no meaningful closed silhouette (e.g. text)
|
|
3975
|
+
* leave this undefined. */
|
|
3976
|
+
silhouette?(node: Node$1<TData, string, TPose>, pose: TPose, ctx?: NodeSilhouetteCtx): Path | null;
|
|
3977
|
+
/** Optional: how the silhouette is inked — whether the interior is filled,
|
|
3978
|
+
* and how wide the outline is. Read by picking, so that an unfilled shape
|
|
3979
|
+
* is grabbable by its outline rather than by its empty middle.
|
|
3980
|
+
*
|
|
3981
|
+
* This is declared separately from `paint` rather than read back off the
|
|
3982
|
+
* emitted draw commands because picking runs on every pointer move, and
|
|
3983
|
+
* `paint` is allowed to be expensive (`kit:text` lays out glyphs). Keep it
|
|
3984
|
+
* to cheap field reads.
|
|
3985
|
+
*
|
|
3986
|
+
* Painters that leave it undefined are treated as {@link DEFAULT_INK} —
|
|
3987
|
+
* the pre-`ink` behavior, where the whole silhouette interior is grabbable
|
|
3988
|
+
* and the outline adds nothing.
|
|
3989
|
+
*
|
|
3990
|
+
* `ctx.scale` carries the view scale so a `{ px }` stroke width resolves to
|
|
3991
|
+
* world units; without it a screen-pixel width is read as world units. */
|
|
3992
|
+
ink?(node: Node$1<TData, string, TPose>, pose: TPose, ctx?: NodeInkCtx): NodeInk | null;
|
|
3993
|
+
}
|
|
3994
|
+
/** How a painter inks its silhouette. See {@link NodeShapeEntry.ink}.
|
|
3995
|
+
*
|
|
3996
|
+
* Reach is per-side because `align` decides which side the ribbon lands on:
|
|
3997
|
+
* a centered stroke straddles the outline, `'inner'` puts nothing outside it,
|
|
3998
|
+
* `'outer'` nothing inside. */
|
|
3999
|
+
interface NodeInk {
|
|
4000
|
+
/** True when the silhouette's interior is painted, and so grabbable. */
|
|
4001
|
+
filled: boolean;
|
|
4002
|
+
/** How far the ink reaches outside the outline, world units. */
|
|
4003
|
+
outset: number;
|
|
4004
|
+
/** How far it reaches inside. */
|
|
4005
|
+
inset: number;
|
|
4006
|
+
}
|
|
4007
|
+
/** Per-call context for {@link NodeShapeEntry.silhouette}. */
|
|
4008
|
+
interface NodeSilhouetteCtx {
|
|
4009
|
+
/** The node's derived path, resolved by the caller — a painter has no scene
|
|
4010
|
+
* handle and deriving needs the dependencies' poses. Same convention as
|
|
4011
|
+
* {@link NodePaintCtx.derivedPath}: absent for a node that derives from
|
|
4012
|
+
* nothing, `null` when it derives but has nothing to draw. */
|
|
4013
|
+
derivedPath?: Path | null;
|
|
4014
|
+
}
|
|
4015
|
+
/** Per-call context for {@link NodeShapeEntry.ink}. */
|
|
4016
|
+
interface NodeInkCtx {
|
|
4017
|
+
/** View scale, for resolving `{ px }` stroke widths to world units. */
|
|
4018
|
+
scale?: number;
|
|
4019
|
+
}
|
|
4020
|
+
/** Options for `registerNodeShape`. */
|
|
4021
|
+
interface RegisterNodeShapeOptions {
|
|
4022
|
+
/** `'high'` puts the painter ahead of all normally-registered ones (so
|
|
4023
|
+
* it can win over a kit built-in). `'normal'` appends at the end. */
|
|
4024
|
+
priority?: 'high' | 'normal';
|
|
4025
|
+
}
|
|
4026
|
+
/** Register a shape painter. Returns a disposer that removes it. */
|
|
4027
|
+
declare function registerNodeShape<TData, TPose>(painter: NodeShapeEntry<TData, TPose>, opts?: RegisterNodeShapeOptions): () => void;
|
|
4028
|
+
/** Find the painter that will render `node` — first match in priority
|
|
4029
|
+
* order. Returns undefined if no painter (including the built-in
|
|
4030
|
+
* fallback) accepts the node. */
|
|
4031
|
+
declare function findNodeShape<TData, TPose>(node: Node$1<TData, string, TPose>): NodeShapeEntry<TData, TPose> | undefined;
|
|
4032
|
+
/** Find the painter for `node` and ask it for the node's silhouette path,
|
|
4033
|
+
* in **world** coords. Returns null if no painter matches, or the matching
|
|
4034
|
+
* painter has no `silhouette` method, or the method returns null. Used by
|
|
4035
|
+
* clipping, generic non-rect hit-testing and lasso/area-select — anywhere
|
|
4036
|
+
* the kit needs the "closed boundary" of whatever this kind of node draws as.
|
|
4037
|
+
*
|
|
4038
|
+
* Painters return their silhouette in the pose's local (unrotated) frame;
|
|
4039
|
+
* this bakes `pose.rotation` on top via the shared rotation convention, so
|
|
4040
|
+
* clips/area-select of a rotated node use the rotated boundary the renderer
|
|
4041
|
+
* draws. (`paint()` is unaffected — it applies rotation via the render wrap,
|
|
4042
|
+
* not the silhouette, so there is no double-rotation.) */
|
|
4043
|
+
declare function findShapeSilhouette<TData, TPose>(node: Node$1<TData, string, TPose>, pose: TPose, ctx?: NodeSilhouetteCtx): Path | null;
|
|
4044
|
+
/** Find the painter for `node` and ask how it inks its silhouette. Returns
|
|
4045
|
+
* the painter's declared {@link NodeInk}, or `null` when no painter matches
|
|
4046
|
+
* or it declares none — callers substitute {@link DEFAULT_INK}. */
|
|
4047
|
+
declare function findShapeInk<TData, TPose>(node: Node$1<TData, string, TPose>, pose: TPose, ctx?: NodeInkCtx): NodeInk | null;
|
|
4048
|
+
/** Options for {@link shapeCoversPoint}. */
|
|
4049
|
+
interface ShapeCoversPointOptions {
|
|
4050
|
+
/** Extra grab distance around the outline, in **world** units. Callers
|
|
4051
|
+
* derive it from a screen-pixel slop and the view scale, the same way
|
|
4052
|
+
* affordance hit radii work.
|
|
4053
|
+
*
|
|
4054
|
+
* Without slop a hairline is a mathematically zero-width target: the
|
|
4055
|
+
* stroke of a 1px outline is half a world unit wide at scale 1, which no
|
|
4056
|
+
* one can hit. Defaults to `0` so a caller that hasn't thought about the
|
|
4057
|
+
* view still gets exact geometry rather than a wrong guess. */
|
|
4058
|
+
tolerance?: number;
|
|
4059
|
+
/** View scale, passed to the painter's `ink` so a `{ px }` stroke width
|
|
4060
|
+
* resolves to world units. Defaults to 1. */
|
|
4061
|
+
scale?: number;
|
|
4062
|
+
/** The node's derived path — see {@link NodeSilhouetteCtx.derivedPath}.
|
|
4063
|
+
* Without it a derived node reports no silhouette and this answers `true`
|
|
4064
|
+
* everywhere, which degrades picking to the caller's AABB: for an edge,
|
|
4065
|
+
* a zero-sized pose. */
|
|
4066
|
+
derivedPath?: Path | null;
|
|
4067
|
+
}
|
|
4068
|
+
/**
|
|
4069
|
+
* Does the shape `node` actually paints cover the world point?
|
|
4070
|
+
*
|
|
4071
|
+
* The pose rect says a node covers its whole bounding box. That is wrong for
|
|
4072
|
+
* everything that is not a rectangle: the concave notch of a star, the corner
|
|
4073
|
+
* outside an ellipse, the blank right half of a text box. This asks the
|
|
4074
|
+
* painter's silhouette instead, which is the same boundary used for clipping
|
|
4075
|
+
* and area-select, so "what you can click" and "what is drawn" answer
|
|
4076
|
+
* together.
|
|
4077
|
+
*
|
|
4078
|
+
* "What is drawn" includes the *ink*, not just the boundary. A shape whose
|
|
4079
|
+
* interior isn't filled — an outlined rect, a pencil stroke, a bare line — is
|
|
4080
|
+
* grabbable along its outline and not through its empty middle, which is the
|
|
4081
|
+
* opposite of what a fill test alone answers. The outline's grab width is the
|
|
4082
|
+
* stroke's half-width plus `tolerance`.
|
|
4083
|
+
*
|
|
4084
|
+
* A painter with no `silhouette`, or one that returns `null` for this node
|
|
4085
|
+
* (`kit:text` does, for a node with no non-blank lines), reports `true` —
|
|
4086
|
+
* "no opinion", leaving the caller's own AABB test as the answer. Callers
|
|
4087
|
+
* should keep that AABB test as a cheap pre-filter; this is the refinement,
|
|
4088
|
+
* not a replacement.
|
|
4089
|
+
*
|
|
4090
|
+
* Rotation is already baked by `findShapeSilhouette`, so the point is in
|
|
4091
|
+
* plain world coordinates.
|
|
4092
|
+
*/
|
|
4093
|
+
declare function shapeCoversPoint<TData, TPose>(node: Node$1<TData, string, TPose>, pose: TPose, x: number, y: number, opts?: ShapeCoversPointOptions): boolean;
|
|
4094
|
+
/** Snapshot of the current painters in evaluation order — `'high'` tier
|
|
4095
|
+
* first, then `'normal'`. Useful for debugging which painter handles a
|
|
4096
|
+
* given node. */
|
|
4097
|
+
declare function getNodeShapes(): readonly NodeShapeEntry[];
|
|
4098
|
+
|
|
4099
|
+
/**
|
|
4100
|
+
* Selection overlay primitives — render layers for drawing selection
|
|
4101
|
+
* outlines and corner resize handles in world space.
|
|
4102
|
+
*
|
|
4103
|
+
* Three pieces:
|
|
4104
|
+
* - `composeSelectionPose` resolves the live pose for a selected id by
|
|
4105
|
+
* consulting the move overlay first, then the resize overlay, then the
|
|
4106
|
+
* stored pose. When `getChildren`/`isContainer` are supplied and the id
|
|
4107
|
+
* resolves to a container, the returned pose is the union AABB of all
|
|
4108
|
+
* transitive leaf poses (with the same precedence rules applied per leaf).
|
|
4109
|
+
* - `createSelectionOutlineLayer` draws the outline rect for each selected
|
|
4110
|
+
* id (container ids resolve to a union AABB via `getChildren`/`isContainer`).
|
|
4111
|
+
* - `createSelectionHandlesLayer` draws resize-handle rects (default 4
|
|
4112
|
+
* corners) for each selected id, with the same container-resolution rules.
|
|
4113
|
+
*
|
|
4114
|
+
* `createSelectionOverlayLayer` is a thin convenience that returns a single
|
|
4115
|
+
* `RenderLayer` whose draw runs the outline pass then the handles pass.
|
|
4116
|
+
*
|
|
4117
|
+
* **Pose shape:** TPose is generic; callers must supply `getBounds(pose)`
|
|
4118
|
+
* to project any pose into the AABB the renderer needs. For rect-shaped
|
|
4119
|
+
* poses (`{x, y, width, height}`) pass the identity. For `Path` poses pass
|
|
4120
|
+
* `boundsOfPath`. Container ids reduce via `unionAABB` over the projected
|
|
4121
|
+
* AABBs.
|
|
4122
|
+
*/
|
|
4123
|
+
|
|
4124
|
+
/** Options for `composeSelectionPose`. */
|
|
4125
|
+
interface ComposeSelectionPoseOpts<TPose> {
|
|
4126
|
+
/** Move overlay; when present its `poses` map wins over everything else. */
|
|
4127
|
+
moveOverlay?: {
|
|
4128
|
+
poses: Map<string, TPose>;
|
|
4129
|
+
} | null;
|
|
4130
|
+
/**
|
|
4131
|
+
* Resize overlay; consulted only when move overlay does not own the id.
|
|
4132
|
+
* For container resize, `leafPoses` (when present) maps each leaf id under
|
|
4133
|
+
* the container to its overlay pose. If absent the container falls back to
|
|
4134
|
+
* stored leaf poses (defensive — container-resize integration is in flight).
|
|
4135
|
+
*/
|
|
4136
|
+
resizeOverlay?: {
|
|
4137
|
+
id: string;
|
|
4138
|
+
currentPose: TPose;
|
|
4139
|
+
leafPoses?: Map<string, TPose>;
|
|
4140
|
+
} | null;
|
|
4141
|
+
/** Fallback pose lookup (typically the stored/committed pose). */
|
|
4142
|
+
getStoredPose: (id: string) => TPose;
|
|
4143
|
+
/**
|
|
4144
|
+
* Project a pose into its AABB. Used when reducing a group of leaf poses
|
|
4145
|
+
* into a single union AABB. Defaults to the identity — rect-shaped poses
|
|
4146
|
+
* (`{x, y, width, height}`) need no override. For `Path` poses pass
|
|
4147
|
+
* `boundsOfPath`.
|
|
4148
|
+
*/
|
|
4149
|
+
getBounds?: (pose: TPose) => Bounds;
|
|
4150
|
+
/**
|
|
4151
|
+
* Wrap an AABB back into a TPose. Called only when the resolver collapses
|
|
4152
|
+
* a container's leaves into a single union AABB. Defaults to the identity —
|
|
4153
|
+
* for `Path` poses pass `(b) => ({ kind: 'rect', ...b })`.
|
|
4154
|
+
*/
|
|
4155
|
+
fromBounds?: (bounds: Bounds) => TPose;
|
|
4156
|
+
/** Walk a container's direct children (e.g. `scene.childrenOf`). With
|
|
4157
|
+
* `isContainer`, a selected container resolves to the union AABB of its
|
|
4158
|
+
* transitive leaf poses instead of its own stored pose. */
|
|
4159
|
+
getChildren?: (id: string) => readonly string[];
|
|
4160
|
+
/** True when `id` is a structural container. */
|
|
4161
|
+
isContainer?: (id: string) => boolean;
|
|
4162
|
+
}
|
|
4163
|
+
/**
|
|
4164
|
+
* Build a pose resolver for a selection. Precedence per id:
|
|
4165
|
+
* move overlay > resize overlay > stored. When `getChildren`/`isContainer`
|
|
4166
|
+
* are supplied and the id resolves to a container, the resolver returns the
|
|
4167
|
+
* union AABB of all transitive leaf poses (each leaf still subject to the
|
|
4168
|
+
* precedence rules). Containers with no leaves resolve to `null`.
|
|
4169
|
+
*/
|
|
4170
|
+
declare function composeSelectionPose<TPose>(opts: ComposeSelectionPoseOpts<TPose>): (id: string) => TPose | null;
|
|
4171
|
+
/** Options every selection layer shares. `getSelection` and `getPose` are
|
|
4172
|
+
* declared on {@link SelectionOverlayLayerOpts}, which makes both optional —
|
|
4173
|
+
* omitted, they come off the draw envelope. */
|
|
4174
|
+
interface SelectionLayerCommon<TPose> {
|
|
4175
|
+
/**
|
|
4176
|
+
* Project a pose into its AABB. Defaults to the identity — rect-shaped
|
|
4177
|
+
* poses (`{x, y, width, height}`) need no override. For `Path` poses pass
|
|
4178
|
+
* `boundsOfPath`.
|
|
4179
|
+
*/
|
|
4180
|
+
getBounds?: (pose: TPose) => Bounds;
|
|
4181
|
+
/** Walk a container's direct children (e.g. `scene.childrenOf`). When
|
|
4182
|
+
* supplied with `isContainer`, any id that resolves to a container is
|
|
4183
|
+
* rendered using the union bounds of all its transitive leaves. */
|
|
4184
|
+
getChildren?: (id: string) => readonly string[];
|
|
4185
|
+
/** True when `id` is a structural container. */
|
|
4186
|
+
isContainer?: (id: string) => boolean;
|
|
4187
|
+
}
|
|
4188
|
+
/** Options for `createSelectionOutlineLayer`. The overlay layer's options
|
|
4189
|
+
* minus the handle visuals — the two run the same body. */
|
|
4190
|
+
type SelectionOutlineLayerOpts<TPose> = Omit<SelectionOverlayLayerOpts<TPose>, 'handles' | 'handlesOf' | 'rotationHandle'>;
|
|
4191
|
+
/** Options for `createSelectionHandlesLayer`. The overlay layer's options
|
|
4192
|
+
* minus the outline stroke — the two run the same body. */
|
|
4193
|
+
type SelectionHandlesLayerOpts<TPose> = Omit<SelectionOverlayLayerOpts<TPose>, 'outline'>;
|
|
4194
|
+
/** Options for `createSelectionOverlayLayer`. */
|
|
4195
|
+
interface SelectionOverlayLayerOpts<TPose> extends SelectionLayerCommon<TPose> {
|
|
4196
|
+
/**
|
|
4197
|
+
* Which ids to draw chrome for. Omit to take them from the `ChromeState` on
|
|
4198
|
+
* the draw envelope, which is what makes one canvas's several views each
|
|
4199
|
+
* outline their own selection — the layer is shared, the envelope is not.
|
|
4200
|
+
*
|
|
4201
|
+
* A multi-selection resolves to the synthetic union id, with the real
|
|
4202
|
+
* members going to the outline pass, exactly as the explicit form does.
|
|
4203
|
+
*/
|
|
4204
|
+
getSelection?: () => readonly NodeId[];
|
|
4205
|
+
/**
|
|
4206
|
+
* Resolve an id to the pose to draw chrome around. Return null to skip an
|
|
4207
|
+
* id. Omit to take bounds from the same envelope `getSelection` omitted
|
|
4208
|
+
* takes ids from — one cascade, the one the chrome state was built with,
|
|
4209
|
+
* rather than a second one here that has to agree with it.
|
|
4210
|
+
*
|
|
4211
|
+
* Takes `string` rather than `NodeId` because the container-aware resolver
|
|
4212
|
+
* walks expanded leaf ids via `getChildren`, which is generic over strings.
|
|
4213
|
+
*/
|
|
3710
4214
|
getPose?: (id: string) => TPose | null;
|
|
3711
4215
|
outline?: Stroke & {
|
|
3712
4216
|
pad?: number;
|
|
3713
4217
|
};
|
|
3714
4218
|
/** Pass `false` to render outlines only. */
|
|
3715
|
-
handles?:
|
|
3716
|
-
size?: number;
|
|
3717
|
-
fill?: FillStyle;
|
|
3718
|
-
outline?: Stroke;
|
|
3719
|
-
} | false;
|
|
4219
|
+
handles?: SelectionHandleStyle | false;
|
|
3720
4220
|
handlesOf?: (bounds: Bounds) => {
|
|
3721
4221
|
x: number;
|
|
3722
4222
|
y: number;
|
|
@@ -3737,10 +4237,16 @@ interface SelectionOverlayLayerOpts<TPose> extends Omit<SelectionLayerCommon<TPo
|
|
|
3737
4237
|
* per-anchor chrome takes over. */
|
|
3738
4238
|
getSuppressedIds?: () => ReadonlySet<string>;
|
|
3739
4239
|
}
|
|
4240
|
+
/** Handle visuals, as a consumer supplies them. */
|
|
4241
|
+
interface SelectionHandleStyle {
|
|
4242
|
+
size?: number;
|
|
4243
|
+
fill?: FillStyle;
|
|
4244
|
+
outline?: Stroke;
|
|
4245
|
+
}
|
|
3740
4246
|
/**
|
|
3741
4247
|
* `RenderLayer` that draws selection outlines only. Stack alongside
|
|
3742
|
-
* `createSelectionHandlesLayer` (or
|
|
3743
|
-
*
|
|
4248
|
+
* `createSelectionHandlesLayer` (or use `createSelectionOverlayLayer`, which
|
|
4249
|
+
* runs both passes in one layer) when both are wanted.
|
|
3744
4250
|
*/
|
|
3745
4251
|
declare function createSelectionOutlineLayer<TPose>(opts: SelectionOutlineLayerOpts<TPose>): RenderLayer<unknown>;
|
|
3746
4252
|
/**
|
|
@@ -3749,10 +4255,9 @@ declare function createSelectionOutlineLayer<TPose>(opts: SelectionOutlineLayerO
|
|
|
3749
4255
|
*/
|
|
3750
4256
|
declare function createSelectionHandlesLayer<TPose>(opts: SelectionHandlesLayerOpts<TPose>): RenderLayer<unknown>;
|
|
3751
4257
|
/**
|
|
3752
|
-
*
|
|
3753
|
-
*
|
|
3754
|
-
*
|
|
3755
|
-
* render outlines only.
|
|
4258
|
+
* Draws outlines then handles in a single layer. Exactly equivalent to
|
|
4259
|
+
* stacking `createSelectionOutlineLayer` and `createSelectionHandlesLayer` —
|
|
4260
|
+
* all three run the same body. Pass `handles: false` to render outlines only.
|
|
3756
4261
|
*/
|
|
3757
4262
|
declare function createSelectionOverlayLayer<TPose>(opts: SelectionOverlayLayerOpts<TPose>): RenderLayer<unknown>;
|
|
3758
4263
|
|
|
@@ -3830,8 +4335,15 @@ interface SceneSlotConfig<TNode extends {
|
|
|
3830
4335
|
objects?: TNode[];
|
|
3831
4336
|
/** Project an object to its committed pose. Defaults to `adapter.getPose(obj.id)`. */
|
|
3832
4337
|
toPose?: (obj: TNode) => TPose;
|
|
3833
|
-
/** Draw a single object as a `DrawCommand` tree.
|
|
3834
|
-
|
|
4338
|
+
/** Draw a single object as a `DrawCommand` tree. `ctx` carries what only a
|
|
4339
|
+
* scene-aware caller can supply (a node's derived path); `<SceneCanvas>`
|
|
4340
|
+
* fills it in, bare `<Canvas>` never does. */
|
|
4341
|
+
drawOne: (obj: TNode, pose: TPose, view: View, ctx?: NodePaintCtx) => DrawCommand[];
|
|
4342
|
+
/** The path a container derives from its dependencies' poses, for the clip
|
|
4343
|
+
* it imposes on its subtree. The other half of what only a scene-aware
|
|
4344
|
+
* caller can supply — `drawOne`'s `ctx` carries the derived path a node
|
|
4345
|
+
* *paints*, this one the clip it *imposes*. */
|
|
4346
|
+
derivedPathOf?: (obj: TNode, pose: TPose) => Path | null;
|
|
3835
4347
|
/** Default ghost alpha for the move-overlay slot. Default 0.85. */
|
|
3836
4348
|
ghostAlpha?: number;
|
|
3837
4349
|
/**
|
|
@@ -3930,6 +4442,20 @@ interface CanvasProps<TNode extends {
|
|
|
3930
4442
|
* same contract the headless `renderSceneToPixels` path follows (that
|
|
3931
4443
|
* path never reads ambient density at all). */
|
|
3932
4444
|
dpr?: number;
|
|
4445
|
+
/** The version of whatever content this canvas draws, sampled at paint time
|
|
4446
|
+
* and reported by {@link CanvasExtensionApi.getPaintedVersion}.
|
|
4447
|
+
* `<SceneCanvas>` wires this to `scene.getVersion`. Chrome that must not
|
|
4448
|
+
* show DOM ahead of pixels compares the two and defers a frame. */
|
|
4449
|
+
contentVersion?: () => number;
|
|
4450
|
+
/** Paint inside the React commit rather than on the next animation frame.
|
|
4451
|
+
* Costs a synchronous paint per commit and per redraw request; buys
|
|
4452
|
+
* single-commit consistency between React-rendered DOM and canvas pixels.
|
|
4453
|
+
* For consumers with DOM chrome pinned to canvas content that cannot
|
|
4454
|
+
* tolerate a frame of skew. Live: toggling it switches modes from the next
|
|
4455
|
+
* redraw on. A redraw requested from inside a layer's `draw`, or from a
|
|
4456
|
+
* `subscribeFrame` callback, still waits for a frame — painting it in place
|
|
4457
|
+
* would recurse. */
|
|
4458
|
+
syncPaint?: boolean;
|
|
3933
4459
|
/**
|
|
3934
4460
|
* Combined adapter for scene-slot rendering, bounds computation, and
|
|
3935
4461
|
* move/resize/rotate gesture math. Optional — bare-Canvas consumers that
|
|
@@ -3993,6 +4519,12 @@ interface CanvasProps<TNode extends {
|
|
|
3993
4519
|
className?: string;
|
|
3994
4520
|
style?: React__default.CSSProperties;
|
|
3995
4521
|
tabIndex?: number;
|
|
4522
|
+
/** Fired when the canvas element gains focus. The canvas is focusable by
|
|
4523
|
+
* default (`tabIndex` 0), so consumers driving focus-dependent chrome —
|
|
4524
|
+
* a focus ring, a "keyboard shortcuts active" hint — need to observe it. */
|
|
4525
|
+
onFocus?: React__default.FocusEventHandler<HTMLCanvasElement>;
|
|
4526
|
+
/** Fired when the canvas element loses focus. */
|
|
4527
|
+
onBlur?: React__default.FocusEventHandler<HTMLCanvasElement>;
|
|
3996
4528
|
/**
|
|
3997
4529
|
* When `true` (default), the canvas element receives focus on `pointerdown`
|
|
3998
4530
|
* so keyboard events (tool hotkeys, undo/redo) are captured without a
|
|
@@ -4101,7 +4633,9 @@ interface CanvasProps<TNode extends {
|
|
|
4101
4633
|
* Hand tool registration, wheel pan/zoom action descriptors, and keyboard
|
|
4102
4634
|
* zoom shortcuts are SceneCanvas-level concerns and are NOT owned by Canvas.
|
|
4103
4635
|
* Those belong with the tool registry and gesture dispatcher that live in
|
|
4104
|
-
* SceneCanvas
|
|
4636
|
+
* SceneCanvas — which is also why SceneCanvas does not pass this prop: it
|
|
4637
|
+
* drives pinch through the `viewport.pinchZoom` action instead, and both
|
|
4638
|
+
* paths at once would apply one gesture's zoom factor twice.
|
|
4105
4639
|
*
|
|
4106
4640
|
* When omitted, no pinch-zoom listener is attached.
|
|
4107
4641
|
*/
|
|
@@ -4196,448 +4730,6 @@ interface CanvasProps<TNode extends {
|
|
|
4196
4730
|
layerOrder?: string[];
|
|
4197
4731
|
}
|
|
4198
4732
|
|
|
4199
|
-
/** Which of a node's two per-anchor color arrays an override applies to. */
|
|
4200
|
-
type VertexColorChannel = 'fill' | 'stroke';
|
|
4201
|
-
/** Function-form override: receives the consumer-supplied base color
|
|
4202
|
-
* array and the current animation timestamp (ms, from the animator's
|
|
4203
|
-
* clock). Returns a flat RGBA float array (values in 0..1, matching
|
|
4204
|
-
* the renderer's `stroke.vertexColors` / `PathDrawCommand.vertexColors`
|
|
4205
|
-
* color space) of the same length as `base`. */
|
|
4206
|
-
type ColorOverrideFn = (base: readonly number[], tMs: number) => number[];
|
|
4207
|
-
/** Either a static per-anchor RGBA float array (0..1) or a function-form
|
|
4208
|
-
* override (see {@link ColorOverrideFn}). */
|
|
4209
|
-
type ColorOverride = readonly number[] | ColorOverrideFn;
|
|
4210
|
-
/** Per-node, per-channel store of color overrides consulted by `createPathLayer`
|
|
4211
|
-
* before falling back to the consumer's `getVertexColors` / `getStrokeVertexColors`
|
|
4212
|
-
* accessor. Attached to `useAnimator` as `animator.colorOverrides`. */
|
|
4213
|
-
declare class ColorOverrideRegistry {
|
|
4214
|
-
private readonly map;
|
|
4215
|
-
private _version;
|
|
4216
|
-
set(id: string, channel: VertexColorChannel, override: ColorOverride): void;
|
|
4217
|
-
clear(id: string, channel: VertexColorChannel): void;
|
|
4218
|
-
clearAll(): void;
|
|
4219
|
-
get(id: string, channel: VertexColorChannel): ColorOverride | undefined;
|
|
4220
|
-
version(): number;
|
|
4221
|
-
}
|
|
4222
|
-
|
|
4223
|
-
/** One keyframe. `easing` shapes the approach INTO this key from the previous
|
|
4224
|
-
* one, so the first key's easing is never consulted. */
|
|
4225
|
-
interface Keyframe<T> {
|
|
4226
|
-
/** Time within the track's timeline, in ms. */
|
|
4227
|
-
t: number;
|
|
4228
|
-
value: T;
|
|
4229
|
-
easing?: EasingFn;
|
|
4230
|
-
}
|
|
4231
|
-
/** A track sampled as a pure function of the playhead. Scrubbing one is free
|
|
4232
|
-
* and order-independent. */
|
|
4233
|
-
interface SampledTrack<T> {
|
|
4234
|
-
kind: 'sampled';
|
|
4235
|
-
label?: string;
|
|
4236
|
-
/** Sorted ascending by `t`. `sampleTrack` assumes this and does not sort. */
|
|
4237
|
-
keys: Keyframe<T>[];
|
|
4238
|
-
/** Required when T is not `number`; defaults to numeric lerp otherwise. */
|
|
4239
|
-
interpolate?: Interpolate<T>;
|
|
4240
|
-
/** Built once per segment and cached. Takes precedence over `interpolate`. */
|
|
4241
|
-
interpolator?: InterpolatorFactory<T>;
|
|
4242
|
-
onTick: (value: T) => void;
|
|
4243
|
-
}
|
|
4244
|
-
/** A track of edge crossings. Fires only when the playhead advances forward
|
|
4245
|
-
* under playback — never on `seek`. */
|
|
4246
|
-
interface EventTrack {
|
|
4247
|
-
kind: 'event';
|
|
4248
|
-
label?: string;
|
|
4249
|
-
/** Sorted ascending by `t`. */
|
|
4250
|
-
events: {
|
|
4251
|
-
t: number;
|
|
4252
|
-
fire: () => void;
|
|
4253
|
-
}[];
|
|
4254
|
-
}
|
|
4255
|
-
/** A nested timeline, evaluated at `playhead - at`. Children are NOT registered
|
|
4256
|
-
* with the animator separately; the parent evaluates them. */
|
|
4257
|
-
interface TimelineTrack {
|
|
4258
|
-
kind: 'timeline';
|
|
4259
|
-
label?: string;
|
|
4260
|
-
at: number;
|
|
4261
|
-
timeline: NestedTimeline;
|
|
4262
|
-
}
|
|
4263
|
-
type Track = SampledTrack<any> | EventTrack | TimelineTrack;
|
|
4264
|
-
/** What a child timeline may declare. The parent owns playback, so `loop`,
|
|
4265
|
-
* `autoplay`, `onDone` and `cancelKey` have no meaning below the root. */
|
|
4266
|
-
interface NestedTimeline {
|
|
4267
|
-
tracks: Track[];
|
|
4268
|
-
/** Defaults to the largest end time across `tracks`. */
|
|
4269
|
-
duration?: number;
|
|
4270
|
-
}
|
|
4271
|
-
interface TimelineOptions extends NestedTimeline {
|
|
4272
|
-
/** `true` loops forever, `n` loops n additional times. Default false. */
|
|
4273
|
-
loop?: boolean | number;
|
|
4274
|
-
/** Default true. When false the timeline registers but holds at t=0 until resumed. */
|
|
4275
|
-
autoplay?: boolean;
|
|
4276
|
-
onDone?: () => void;
|
|
4277
|
-
cancelKey?: string;
|
|
4278
|
-
}
|
|
4279
|
-
interface TimelineHandle extends AnimationHandle {
|
|
4280
|
-
/** Move the playhead. Never fires event tracks, at any depth. */
|
|
4281
|
-
seek(t: number): void;
|
|
4282
|
-
/** Current playhead in ms. */
|
|
4283
|
-
time(): number;
|
|
4284
|
-
duration(): number;
|
|
4285
|
-
tracks(): readonly Track[];
|
|
4286
|
-
/** Run `fn`, then recompute duration, drop cached interpolators, and notify.
|
|
4287
|
-
* Every mutation must go through this — an edited keyframe otherwise keeps
|
|
4288
|
-
* interpolating toward its old value with no visible error. */
|
|
4289
|
-
edit(fn: () => void): void;
|
|
4290
|
-
/** Notified after each `edit`. Returns an unsubscribe. */
|
|
4291
|
-
subscribe(cb: () => void): () => void;
|
|
4292
|
-
}
|
|
4293
|
-
|
|
4294
|
-
/** An easing curve: maps normalized progress `t ∈ [0, 1]` to eased progress.
|
|
4295
|
-
* Curves may leave the 0–1 range in the middle (back, elastic) but should
|
|
4296
|
-
* pass through 0 at 0 and 1 at 1. */
|
|
4297
|
-
type EasingFn = (t: number) => number;
|
|
4298
|
-
/** Blends two `T` values at eased progress `t`. Called once per frame; see
|
|
4299
|
-
* {@link InterpolatorFactory} when the blend has setup worth hoisting. */
|
|
4300
|
-
type Interpolate<T> = (from: T, to: T, t: number) => T;
|
|
4301
|
-
/** Factory interpolator: built ONCE at tween start with (from, to), the returned
|
|
4302
|
-
* function is called with `t ∈ [0, 1]` each frame. Use for interpolators with
|
|
4303
|
-
* expensive setup (color-space conversion, path-string parsing) — d3-interpolate's
|
|
4304
|
-
* shape exactly. For cheap interpolations the per-tick `Interpolate<T>` form is
|
|
4305
|
-
* fine; this is the escape hatch when setup-per-tick is wasteful. */
|
|
4306
|
-
type InterpolatorFactory<T> = (from: T, to: T) => (t: number) => T;
|
|
4307
|
-
/** A spring's physical parameters. Higher stiffness settles faster, higher
|
|
4308
|
-
* damping overshoots less, higher mass makes both sluggish. */
|
|
4309
|
-
interface SpringPreset {
|
|
4310
|
-
stiffness: number;
|
|
4311
|
-
damping: number;
|
|
4312
|
-
mass: number;
|
|
4313
|
-
}
|
|
4314
|
-
/** One of the tunings in `SPRING_PRESETS`. */
|
|
4315
|
-
type SpringPresetName = 'gentle' | 'wobbly' | 'stiff' | 'slow';
|
|
4316
|
-
/** A running animation. Cancel it, or bend its time — pausing and time-scaling
|
|
4317
|
-
* act on this animation's own virtual clock, independent of the animator's. */
|
|
4318
|
-
interface AnimationHandle {
|
|
4319
|
-
/** Monotonic id assigned by the animator. */
|
|
4320
|
-
id: number;
|
|
4321
|
-
/** Cancel this animation. Idempotent — no-op once already finished/canceled. */
|
|
4322
|
-
cancel(): void;
|
|
4323
|
-
/** Freeze this animation's virtual clock. Idempotent. */
|
|
4324
|
-
pause(): void;
|
|
4325
|
-
/** Resume this animation's virtual clock. Idempotent. */
|
|
4326
|
-
resume(): void;
|
|
4327
|
-
/** Multiply this animation's virtual-clock rate by `scale`. 1 = normal. */
|
|
4328
|
-
setTimeScale(scale: number): void;
|
|
4329
|
-
/** True iff this handle is currently paused. */
|
|
4330
|
-
isPaused(): boolean;
|
|
4331
|
-
}
|
|
4332
|
-
/** A duration-based animation from `from` to `to` over `ms`, shaped by an
|
|
4333
|
-
* easing curve. Reach for a spring instead when the motion should respond to
|
|
4334
|
-
* where the value already is rather than restart from a fixed duration. */
|
|
4335
|
-
interface TweenOptions<T> {
|
|
4336
|
-
from: T;
|
|
4337
|
-
to: T;
|
|
4338
|
-
ms: number;
|
|
4339
|
-
easing?: EasingFn;
|
|
4340
|
-
/** Required when T is not `number`. For T = number, defaults to linear numeric lerp.
|
|
4341
|
-
* Called per-tick with `(from, to, t)`. For interpolators with expensive setup,
|
|
4342
|
-
* prefer `interpolator` which is built once at tween start. */
|
|
4343
|
-
interpolate?: Interpolate<T>;
|
|
4344
|
-
/** Factory interpolator built once at tween start. Takes precedence over
|
|
4345
|
-
* `interpolate` when both are provided. Use this for d3-interpolate or any
|
|
4346
|
-
* `(from, to) => (t) => v` shape. */
|
|
4347
|
-
interpolator?: InterpolatorFactory<T>;
|
|
4348
|
-
onTick: (value: T) => void;
|
|
4349
|
-
onDone?: () => void;
|
|
4350
|
-
/** Any new animation passed the same cancelKey cancels the prior one in flight. */
|
|
4351
|
-
cancelKey?: string;
|
|
4352
|
-
}
|
|
4353
|
-
/** A spring animation: runs until the value settles on `to` rather than for a
|
|
4354
|
-
* set duration, so it absorbs an initial velocity naturally. Non-numeric `T`
|
|
4355
|
-
* needs the four vector helpers. */
|
|
4356
|
-
interface SpringOptions<T> {
|
|
4357
|
-
from: T;
|
|
4358
|
-
to: T;
|
|
4359
|
-
/** Initial velocity in T-units per second. Default: zero (T-shape-aware). */
|
|
4360
|
-
velocity?: T;
|
|
4361
|
-
preset?: SpringPresetName;
|
|
4362
|
-
stiffness?: number;
|
|
4363
|
-
damping?: number;
|
|
4364
|
-
mass?: number;
|
|
4365
|
-
interpolate?: Interpolate<T>;
|
|
4366
|
-
/** Vector helpers — required for non-numeric T. */
|
|
4367
|
-
add?: (a: T, b: T) => T;
|
|
4368
|
-
subtract?: (a: T, b: T) => T;
|
|
4369
|
-
scale?: (v: T, k: number) => T;
|
|
4370
|
-
magnitude?: (v: T) => number;
|
|
4371
|
-
/** Velocity magnitude below which the spring is considered settled. Default 0.01. */
|
|
4372
|
-
restThreshold?: number;
|
|
4373
|
-
onTick: (value: T) => void;
|
|
4374
|
-
onDone?: () => void;
|
|
4375
|
-
cancelKey?: string;
|
|
4376
|
-
}
|
|
4377
|
-
/** Spring and decay as one animation. With a `to`, a spring pulls toward it;
|
|
4378
|
-
* with `to: null`, the value coasts on its velocity. Either can become the
|
|
4379
|
-
* other mid-flight through the handle. */
|
|
4380
|
-
interface PhysicsOptions<T> {
|
|
4381
|
-
from: T;
|
|
4382
|
-
/** Target. `null` ⇒ no spring force (decay-mode). */
|
|
4383
|
-
to?: T | null;
|
|
4384
|
-
/** Initial velocity in T-units per second. */
|
|
4385
|
-
velocity?: T;
|
|
4386
|
-
preset?: SpringPresetName;
|
|
4387
|
-
stiffness?: number;
|
|
4388
|
-
damping?: number;
|
|
4389
|
-
mass?: number;
|
|
4390
|
-
restThreshold?: number;
|
|
4391
|
-
/** Vector helpers — required for non-numeric T. */
|
|
4392
|
-
add?: (a: T, b: T) => T;
|
|
4393
|
-
subtract?: (a: T, b: T) => T;
|
|
4394
|
-
scale?: (v: T, k: number) => T;
|
|
4395
|
-
magnitude?: (v: T) => number;
|
|
4396
|
-
onTick: (value: T) => void;
|
|
4397
|
-
onDone?: () => void;
|
|
4398
|
-
cancelKey?: string;
|
|
4399
|
-
}
|
|
4400
|
-
/** An `AnimationHandle` that can also be steered while it runs — the point of
|
|
4401
|
-
* the physics primitive. */
|
|
4402
|
-
interface PhysicsHandle<T = unknown> extends AnimationHandle {
|
|
4403
|
-
/** Retarget mid-flight. `null` ⇒ switch to decay-mode (no spring force). */
|
|
4404
|
-
setTarget(to: T | null): void;
|
|
4405
|
-
/** Replace the current velocity in T-units per second. */
|
|
4406
|
-
setVelocity(v: T): void;
|
|
4407
|
-
}
|
|
4408
|
-
/** Momentum: coast from `from` at `velocity`, slowing by `friction` each
|
|
4409
|
-
* second until below `threshold`. What a flick-to-pan leaves behind. */
|
|
4410
|
-
interface DecayOptions<T> {
|
|
4411
|
-
from: T;
|
|
4412
|
-
velocity: T;
|
|
4413
|
-
/** Per-second velocity multiplier in (0, 1). Default 0.95. */
|
|
4414
|
-
friction?: number;
|
|
4415
|
-
/** Velocity magnitude below which decay stops. Default 0.5. */
|
|
4416
|
-
threshold?: number;
|
|
4417
|
-
add: (a: T, b: T) => T;
|
|
4418
|
-
scale: (v: T, k: number) => T;
|
|
4419
|
-
magnitude: (v: T) => number;
|
|
4420
|
-
onTick: (value: T) => void;
|
|
4421
|
-
onDone?: () => void;
|
|
4422
|
-
cancelKey?: string;
|
|
4423
|
-
}
|
|
4424
|
-
/** Options for `useAnimator`. Everything here is an injection seam for tests;
|
|
4425
|
-
* the defaults are the real clock, rAF, and `setTimeout`. */
|
|
4426
|
-
interface UseAnimatorOptions {
|
|
4427
|
-
/** Optional clock injection for tests. Returns ms since some epoch. */
|
|
4428
|
-
now?: () => number;
|
|
4429
|
-
/** Optional rAF / cAF injection for tests. Defaults to window.requestAnimationFrame. */
|
|
4430
|
-
requestFrame?: (cb: (t: number) => void) => number;
|
|
4431
|
-
cancelFrame?: (handle: number) => void;
|
|
4432
|
-
/** Optional `setTimeout` injection used by `stagger` for per-item delays.
|
|
4433
|
-
* Defaults to the global `setTimeout`. Tests inject a virtual scheduler. */
|
|
4434
|
-
setTimer?: (cb: () => void, ms: number) => unknown;
|
|
4435
|
-
/** Companion to `setTimer`. Defaults to global `clearTimeout`. */
|
|
4436
|
-
clearTimer?: (handle: unknown) => void;
|
|
4437
|
-
}
|
|
4438
|
-
/**
|
|
4439
|
-
* Owns every running animation on a canvas and drives them from one rAF loop.
|
|
4440
|
-
* Beyond the primitives (`tween`, `spring`, `decay`, `physics`) it offers
|
|
4441
|
-
* composition — `loop`, `stagger` — and bulk control by handle, by cancel-key,
|
|
4442
|
-
* or over everything at once.
|
|
4443
|
-
*
|
|
4444
|
-
* An animator does not know about the scene: animations report values through
|
|
4445
|
-
* `onTick` and the caller decides what to do with them.
|
|
4446
|
-
*/
|
|
4447
|
-
interface Animator {
|
|
4448
|
-
tween<T>(opts: TweenOptions<T>): AnimationHandle;
|
|
4449
|
-
spring<T>(opts: SpringOptions<T>): AnimationHandle;
|
|
4450
|
-
decay<T>(opts: DecayOptions<T>): AnimationHandle;
|
|
4451
|
-
/** Unified spring/decay primitive. With `to` set, behaves as a spring;
|
|
4452
|
-
* with `to: null`, behaves as a velocity-driven decay. Supports
|
|
4453
|
-
* mid-flight retargeting via the returned handle's `setTarget`. */
|
|
4454
|
-
physics<T>(opts: PhysicsOptions<T>): PhysicsHandle<T>;
|
|
4455
|
-
/** Cancel a specific animation by handle. Pose stays at current value (no jump). */
|
|
4456
|
-
cancel(handle: AnimationHandle): void;
|
|
4457
|
-
/** Cancel every animation currently active under `key`. */
|
|
4458
|
-
cancelKey(key: string): void;
|
|
4459
|
-
/** Cancel everything. Useful from a destructor or "reset scene" path. */
|
|
4460
|
-
cancelAll(): void;
|
|
4461
|
-
/** True iff at least one animation is active. With `key`, scoped to that cancelKey. */
|
|
4462
|
-
isActive(key?: string): boolean;
|
|
4463
|
-
/**
|
|
4464
|
-
* True while the animator is currently executing an animation tick. Useful
|
|
4465
|
-
* for adapter wrappers (e.g. `animateOnSetPose`) that need to detect
|
|
4466
|
-
* "this `setPose` was called from inside another animation's onTick"
|
|
4467
|
-
* (momentum decay, in-flight tween, spring) and avoid recursively
|
|
4468
|
-
* scheduling a new wrap-animation that would fight the caller.
|
|
4469
|
-
*/
|
|
4470
|
-
isTicking(): boolean;
|
|
4471
|
-
/** Freeze every animation managed by this animator. */
|
|
4472
|
-
pause(): void;
|
|
4473
|
-
/** Resume every animation managed by this animator. */
|
|
4474
|
-
resume(): void;
|
|
4475
|
-
/** True iff the animator is currently globally paused. */
|
|
4476
|
-
isPaused(): boolean;
|
|
4477
|
-
/** Multiply every animation's virtual-clock rate by `scale`. 1 = normal. */
|
|
4478
|
-
setTimeScale(scale: number): void;
|
|
4479
|
-
/** Freeze every animation whose `cancelKey` matches. */
|
|
4480
|
-
pauseKey(key: string): void;
|
|
4481
|
-
/** Resume every animation whose `cancelKey` matches. */
|
|
4482
|
-
resumeKey(key: string): void;
|
|
4483
|
-
/** Set per-animation timeScale for every animation whose `cancelKey` matches. */
|
|
4484
|
-
setTimeScaleByKey(key: string, scale: number): void;
|
|
4485
|
-
/**
|
|
4486
|
-
* Loop primitive: repeatedly invoke `factory` to produce a child animation.
|
|
4487
|
-
* The factory must wire its returned handle's `onDone` to call `next` so
|
|
4488
|
-
* the loop advances. Returns a handle whose pause/resume/setTimeScale/cancel
|
|
4489
|
-
* delegate to the current in-flight child (and prevent future iterations
|
|
4490
|
-
* on cancel).
|
|
4491
|
-
*
|
|
4492
|
-
* The loop is registered with the animator under a supervisor entry so
|
|
4493
|
-
* `animator.cancel(handle)`, `animator.cancelKey(opts.cancelKey)`, and
|
|
4494
|
-
* `animator.isActive(opts.cancelKey)` all work for it.
|
|
4495
|
-
*/
|
|
4496
|
-
loop(factory: LoopFactory, opts?: LoopOptions): AnimationHandle;
|
|
4497
|
-
/** Sugar over `loop` for the common case of looping a tween between two
|
|
4498
|
-
* values with optional direction handling (`restart` | `reverse` |
|
|
4499
|
-
* `alternate`). Registered with the animator like `loop`. */
|
|
4500
|
-
tweenLoop<T>(opts: TweenLoopOptions<T>): AnimationHandle;
|
|
4501
|
-
/**
|
|
4502
|
-
* Stagger primitive: schedule a per-item animation, offset by `delay` ms
|
|
4503
|
-
* per index (or a custom function of the index). Two forms:
|
|
4504
|
-
* - Factory form: pass `factory` directly, returns a composite
|
|
4505
|
-
* `AnimationHandle`.
|
|
4506
|
-
* - Builder form: omit `factory`, get a `StaggerBuilder` for fluent
|
|
4507
|
-
* `.each` / `.tween` / `.springPose` calls.
|
|
4508
|
-
*
|
|
4509
|
-
* The composite handle's `cancel` cancels pending timers AND in-flight
|
|
4510
|
-
* children. `pause` / `resume` / `setTimeScale` propagate to in-flight
|
|
4511
|
-
* children; `pause`/`resume` also freeze and thaw pending per-item timers
|
|
4512
|
-
* (the remaining time before each pending fire is preserved across the
|
|
4513
|
-
* pause).
|
|
4514
|
-
*
|
|
4515
|
-
* The stagger is registered with the animator under a supervisor entry so
|
|
4516
|
-
* `animator.cancel(handle)`, `animator.cancelKey(opts.cancelKey)`, and
|
|
4517
|
-
* `animator.isActive(opts.cancelKey)` all work for it.
|
|
4518
|
-
*/
|
|
4519
|
-
stagger<TItem>(items: readonly TItem[], delay: StaggerDelay): StaggerBuilder<TItem>;
|
|
4520
|
-
stagger<TItem>(items: readonly TItem[], delay: StaggerDelay, factory: StaggerFactory<TItem>, opts?: StaggerOptions): AnimationHandle;
|
|
4521
|
-
/**
|
|
4522
|
-
* Keyframe timeline. Registered like any other animation, so its playhead
|
|
4523
|
-
* responds to `pause`, `setTimeScale` and `cancelKey`. Sampled tracks are a
|
|
4524
|
-
* pure function of the playhead; event tracks fire only on forward playback.
|
|
4525
|
-
*/
|
|
4526
|
-
timeline(opts: TimelineOptions): TimelineHandle;
|
|
4527
|
-
/** Per-node, per-channel color override registry consulted by the renderer's
|
|
4528
|
-
* path layer before reading consumer accessors. Used by `tweenVertexColors`,
|
|
4529
|
-
* `springVertexColors`, `cycleVertexColors`, `staggerVertexColors`. Cleared
|
|
4530
|
-
* automatically on animator unmount. */
|
|
4531
|
-
colorOverrides: ColorOverrideRegistry;
|
|
4532
|
-
/**
|
|
4533
|
-
* Subscribe to a callback fired once per RAF frame while any animation is
|
|
4534
|
-
* active. Returns an unsubscribe function. Used by consumers (typically
|
|
4535
|
-
* `<SceneCanvas>`) that need to repaint when an animation's side-effect
|
|
4536
|
-
* is read from a non-scene channel (e.g. `colorOverrides` consulted from
|
|
4537
|
-
* a custom `drawOne`) — scene mutations naturally trigger a repaint, but
|
|
4538
|
-
* `colorOverrides` writes do not.
|
|
4539
|
-
*
|
|
4540
|
-
* The callback fires AFTER the per-frame tick of each registered
|
|
4541
|
-
* animation, so by the time it runs `colorOverrides.get(...)` returns
|
|
4542
|
-
* the latest values. If no animations are active, no tick fires.
|
|
4543
|
-
*/
|
|
4544
|
-
onTick(cb: () => void): () => void;
|
|
4545
|
-
/**
|
|
4546
|
-
* Keep the animator's RAF loop running until the returned cancel
|
|
4547
|
-
* function is called. Use for animations whose effect is read on every
|
|
4548
|
-
* frame but which don't have a natural progress state (e.g.
|
|
4549
|
-
* `cycleVertexColors`, which expresses its current value as a function
|
|
4550
|
-
* of `performance.now()` rather than as a tween from `from` to `to`).
|
|
4551
|
-
* Without a keep-alive entry the loop would idle and `onTick` would
|
|
4552
|
-
* stop firing even though the override is still installed.
|
|
4553
|
-
*/
|
|
4554
|
-
keepAlive(): () => void;
|
|
4555
|
-
}
|
|
4556
|
-
/** Options for `Animator.loop`. */
|
|
4557
|
-
interface LoopOptions {
|
|
4558
|
-
/** Maximum number of iterations. Default Infinity. */
|
|
4559
|
-
count?: number;
|
|
4560
|
-
/** Invoked when the loop reaches `count` iterations naturally (not on cancel). */
|
|
4561
|
-
onDone?: () => void;
|
|
4562
|
-
/** Any new animation passed the same cancelKey cancels the prior one in flight.
|
|
4563
|
-
* Also enables `animator.cancelKey` / `animator.isActive(key)` for this loop. */
|
|
4564
|
-
cancelKey?: string;
|
|
4565
|
-
}
|
|
4566
|
-
/** Options for the top-level `Animator.stagger` factory form (third overload). */
|
|
4567
|
-
interface StaggerOptions {
|
|
4568
|
-
/** Cancel-key for the supervising registration. `animator.cancelKey(key)`
|
|
4569
|
-
* cancels the whole stagger; `animator.isActive(key)` returns true while
|
|
4570
|
-
* any timer or child is alive. */
|
|
4571
|
-
cancelKey?: string;
|
|
4572
|
-
}
|
|
4573
|
-
/** Produces one iteration of a loop. Must arrange for `next` to be called when
|
|
4574
|
-
* the animation it returns finishes, or the loop stalls after one pass. */
|
|
4575
|
-
type LoopFactory = (iteration: number, next: () => void) => AnimationHandle;
|
|
4576
|
-
/** Per-index delay schedule. Number ⇒ `index * delay` ms. Function ⇒ caller
|
|
4577
|
-
* decides the absolute delay for each index (e.g. `i => i * i * 30`). */
|
|
4578
|
-
type StaggerDelay = number | ((index: number) => number);
|
|
4579
|
-
/** Produces the animation for one staggered item. */
|
|
4580
|
-
type StaggerFactory<TItem> = (item: TItem, index: number) => AnimationHandle;
|
|
4581
|
-
/** A `T` value or a function that derives one from the per-item context. Used
|
|
4582
|
-
* by the fluent builder methods (`.tween`, `.springPose`) so each item can
|
|
4583
|
-
* vary an option (e.g. `to: (_item, i) => (i + 1) * 10`). */
|
|
4584
|
-
type StaggerPerItem<T, TItem> = T | ((item: TItem, index: number) => T);
|
|
4585
|
-
/** Options for the stagger builder's `.tween`: a tween per item, where
|
|
4586
|
-
* `from`, `to` and `ms` may each vary by item. */
|
|
4587
|
-
interface StaggerTweenOptions<T, TItem> {
|
|
4588
|
-
from: StaggerPerItem<T, TItem>;
|
|
4589
|
-
to: StaggerPerItem<T, TItem>;
|
|
4590
|
-
ms: StaggerPerItem<number, TItem>;
|
|
4591
|
-
easing?: EasingFn;
|
|
4592
|
-
interpolate?: Interpolate<T>;
|
|
4593
|
-
onTick: (value: T, item: TItem, index: number) => void;
|
|
4594
|
-
onDone?: (item: TItem, index: number) => void;
|
|
4595
|
-
}
|
|
4596
|
-
/** Options for the stagger builder's `.springPose`: the spring tuning, and
|
|
4597
|
-
* whether each item's settle is recorded as an undoable op. */
|
|
4598
|
-
interface StaggerSpringPoseOptions<TPose> {
|
|
4599
|
-
preset?: SpringPresetName;
|
|
4600
|
-
stiffness?: number;
|
|
4601
|
-
damping?: number;
|
|
4602
|
-
mass?: number;
|
|
4603
|
-
geometry?: PoseProjection<TPose>;
|
|
4604
|
-
recordOp?: boolean;
|
|
4605
|
-
opLabel?: string;
|
|
4606
|
-
}
|
|
4607
|
-
/** Fluent form of `Animator.stagger`: pick what to run per item after the
|
|
4608
|
-
* items and the delay schedule are already fixed. */
|
|
4609
|
-
interface StaggerBuilder<TItem> {
|
|
4610
|
-
/** Run an arbitrary per-item factory. */
|
|
4611
|
-
each(factory: StaggerFactory<TItem>): AnimationHandle;
|
|
4612
|
-
/** Sugar: per-item `animator.tween` with per-item-varying options. */
|
|
4613
|
-
tween<T>(opts: StaggerTweenOptions<T, TItem>): AnimationHandle;
|
|
4614
|
-
/** Sugar: per-item `springPose` against an adapter. `poseFn` returns the
|
|
4615
|
-
* target pose for each item. Each item must either be a primitive
|
|
4616
|
-
* (string/number) or expose a string `id` field — otherwise pose ids
|
|
4617
|
-
* would collide on `"[object Object]"` and successive tweens would
|
|
4618
|
-
* cancel each other. Throws on items that satisfy neither. */
|
|
4619
|
-
springPose<TPose>(adapter: SceneAdapter<{
|
|
4620
|
-
id: string;
|
|
4621
|
-
}, TPose>, poseFn: (item: TItem, index: number) => TPose, opts?: StaggerSpringPoseOptions<TPose>): AnimationHandle;
|
|
4622
|
-
}
|
|
4623
|
-
/** Options for `Animator.tweenLoop` — a tween's options plus how each
|
|
4624
|
-
* iteration relates to the last. */
|
|
4625
|
-
interface TweenLoopOptions<T> {
|
|
4626
|
-
from: T;
|
|
4627
|
-
to: T;
|
|
4628
|
-
ms: number;
|
|
4629
|
-
easing?: EasingFn;
|
|
4630
|
-
/** `restart` (default): from→to every iteration.
|
|
4631
|
-
* `reverse`: to→from every iteration.
|
|
4632
|
-
* `alternate`: even iterations from→to, odd iterations to→from. */
|
|
4633
|
-
direction?: 'restart' | 'reverse' | 'alternate';
|
|
4634
|
-
count?: number;
|
|
4635
|
-
interpolate?: Interpolate<T>;
|
|
4636
|
-
onTick: (value: T) => void;
|
|
4637
|
-
onDone?: () => void;
|
|
4638
|
-
cancelKey?: string;
|
|
4639
|
-
}
|
|
4640
|
-
|
|
4641
4733
|
/** Minimal selection contract `sceneToAdapter` needs to wire `getSelection` /
|
|
4642
4734
|
* `setSelection`. Matches `useSelection().adapterMethods` plus an imperative
|
|
4643
4735
|
* read; pass `useSelection()` itself or `selection.adapterMethods`. */
|
|
@@ -4838,21 +4930,6 @@ interface CanvasViewProps {
|
|
|
4838
4930
|
*/
|
|
4839
4931
|
declare function CanvasView(props: CanvasViewProps): null;
|
|
4840
4932
|
|
|
4841
|
-
/**
|
|
4842
|
-
* Built-in shape tool ids handled by `useBuiltinShapeTools`. Each maps to a
|
|
4843
|
-
* kit tool hook + a default `create` that produces a leaf node compatible
|
|
4844
|
-
* with `PATH_PAINTER`.
|
|
4845
|
-
*
|
|
4846
|
-
* Runtime mirror in `KIT_SHAPE_KINDS` below — keep the two in sync. The
|
|
4847
|
-
* `src/index.barrel.test.ts` parity gate enforces that every member of this
|
|
4848
|
-
* union is present in the exported tuple.
|
|
4849
|
-
*/
|
|
4850
|
-
type BuiltinShapeToolId = 'rect' | 'ellipse' | 'line' | 'polygon' | 'star' | 'pen' | 'pencil' | 'lasso' | 'text';
|
|
4851
|
-
/** Runtime, iterable list of the shape-tool ids in `BuiltinShapeToolId`.
|
|
4852
|
-
* Surfaced so consumers (e.g. the Bundle Inspector) can enumerate the
|
|
4853
|
-
* builtin shape kinds without re-encoding the union. */
|
|
4854
|
-
declare const KIT_SHAPE_KINDS: readonly ["rect", "ellipse", "line", "polygon", "star", "pen", "pencil", "lasso", "text"];
|
|
4855
|
-
|
|
4856
4933
|
/** Per-tool option overrides for the built-in shape/lasso tools.
|
|
4857
4934
|
* Each entry is a narrow subset of the underlying hook's options surface
|
|
4858
4935
|
* — just the knobs that need consumer control under the bundle pattern. */
|
|
@@ -4990,182 +5067,6 @@ declare function createNodeRouting(): NodeRouting;
|
|
|
4990
5067
|
* matches `poseRotationOf` (the shared rotation convention). */
|
|
4991
5068
|
declare function rotateAroundAABBCenter(x: number, y: number, width: number, height: number, rotation: number): Float32Array;
|
|
4992
5069
|
|
|
4993
|
-
/**
|
|
4994
|
-
* NodeShape — the **shape trait's** registry. Each trait of a node
|
|
4995
|
-
* (shape, routing, label, icon, affordances, …) is its own registry;
|
|
4996
|
-
* this one holds the per-kind `paint` + `silhouette` (and future
|
|
4997
|
-
* fields) used by `defaultDrawOne`, clipping, non-rect hit-testing,
|
|
4998
|
-
* lasso/area-select, and SVG export.
|
|
4999
|
-
*
|
|
5000
|
-
* Teaching the kit about a new kind of shape goes through this registry
|
|
5001
|
-
* rather than by overriding `drawOne`. Overrides are still possible but
|
|
5002
|
-
* shouldn't be the default seam: most consumers want the same dispatch
|
|
5003
|
-
* logic, just extended with their own shape kinds (images, custom paths,
|
|
5004
|
-
* SVG fragments, etc.).
|
|
5005
|
-
*
|
|
5006
|
-
* Built-in entries (`kit:text`, `kit:path`, `kit:rect-fallback`) are
|
|
5007
|
-
* registered at module load. Consumer entries added via
|
|
5008
|
-
* `registerNodeShape` join the chain; the first entry whose
|
|
5009
|
-
* `matches` predicate returns true paints the node.
|
|
5010
|
-
*
|
|
5011
|
-
* Two priority tiers:
|
|
5012
|
-
* - `'high'` — checked before all `'normal'` entries. Use this to
|
|
5013
|
-
* override a kit built-in for a specific data shape (e.g. a custom
|
|
5014
|
-
* text renderer that wins over `kit:text`).
|
|
5015
|
-
* - `'normal'` (default) — appended after the built-ins.
|
|
5016
|
-
*
|
|
5017
|
-
* Within a tier, entries run in registration order. Each
|
|
5018
|
-
* `registerNodeShape` call returns a disposer that removes the
|
|
5019
|
-
* entry — useful for tests, for plugin lifecycles, and for swapping
|
|
5020
|
-
* implementations at runtime.
|
|
5021
|
-
*
|
|
5022
|
-
* See `docs/superpowers/specs/2026-05-24-node-traits-reframe-design.md`
|
|
5023
|
-
* for the trait taxonomy.
|
|
5024
|
-
*/
|
|
5025
|
-
|
|
5026
|
-
/** Optional per-call paint context, threaded through `defaultDrawOne`'s third
|
|
5027
|
-
* argument. Lets a rendering entry point override ambient environment reads
|
|
5028
|
-
* — the headless `renderSceneToPixels` path supplies its own bitmap resolver
|
|
5029
|
-
* here so consumers reuse their own decode caches. Custom painters may
|
|
5030
|
-
* ignore it entirely. */
|
|
5031
|
-
interface NodePaintCtx {
|
|
5032
|
-
/** Override bitmap resolution for image nodes. When set it is authoritative:
|
|
5033
|
-
* the global `imageCache` is not consulted, and an `undefined` result
|
|
5034
|
-
* paints the deterministic grey placeholder outline (never the ambient
|
|
5035
|
-
* load-status error variant). */
|
|
5036
|
-
resolveImage?: (node: Node$1<unknown, string, unknown>) => ImageBitmap | undefined;
|
|
5037
|
-
}
|
|
5038
|
-
/** A painter for one kind of node: which nodes it claims, and the draw
|
|
5039
|
-
* commands it emits for them. Registering one is how a consumer teaches the
|
|
5040
|
-
* default renderer to draw its own node kinds. */
|
|
5041
|
-
interface NodeShapeEntry<TData = unknown, TPose = unknown> {
|
|
5042
|
-
/** Stable identifier — used for unregistration and debugging. Pick
|
|
5043
|
-
* something descriptive: `'kit:text'`, `'app:image'`, etc. */
|
|
5044
|
-
id: string;
|
|
5045
|
-
/** Returns true when this painter renders the node. The first matching
|
|
5046
|
-
* painter (`'high'` tier first, then `'normal'`) wins. */
|
|
5047
|
-
matches(node: Node$1<TData, string, TPose>): boolean;
|
|
5048
|
-
/** Emits the draw commands for the node's primary visual. `ctx` is an
|
|
5049
|
-
* optional per-call paint context (see `NodePaintCtx`); painters that
|
|
5050
|
-
* don't need it can keep a two-argument signature.
|
|
5051
|
-
*
|
|
5052
|
-
* **The returned array belongs to the painter.** Callers must treat it as
|
|
5053
|
-
* immutable and copy before appending — a painter is free to memoize its
|
|
5054
|
-
* command list (`kit:shape` and `kit:path` do), and an in-place `push`
|
|
5055
|
-
* would grow that list on every frame. `defaultDrawOne` copies before
|
|
5056
|
-
* adding its label overlay for exactly this reason. */
|
|
5057
|
-
paint(node: Node$1<TData, string, TPose>, pose: TPose, ctx?: NodePaintCtx): DrawCommand[];
|
|
5058
|
-
/** Optional: derive the node's silhouette path from its pose.
|
|
5059
|
-
* Used by clipping (when the container has no explicit
|
|
5060
|
-
* `clipFromPose`), by non-rect hit-testing, by lasso/area-select,
|
|
5061
|
-
* and by SVG export. Painters whose visual has no meaningful closed
|
|
5062
|
-
* silhouette (e.g. text) leave this undefined. */
|
|
5063
|
-
silhouette?(node: Node$1<TData, string, TPose>, pose: TPose): Path | null;
|
|
5064
|
-
/** Optional: how the silhouette is inked — whether the interior is filled,
|
|
5065
|
-
* and how wide the outline is. Read by picking, so that an unfilled shape
|
|
5066
|
-
* is grabbable by its outline rather than by its empty middle.
|
|
5067
|
-
*
|
|
5068
|
-
* This is declared separately from `paint` rather than read back off the
|
|
5069
|
-
* emitted draw commands because picking runs on every pointer move, and
|
|
5070
|
-
* `paint` is allowed to be expensive (`kit:text` lays out glyphs). Keep it
|
|
5071
|
-
* to cheap field reads.
|
|
5072
|
-
*
|
|
5073
|
-
* Painters that leave it undefined are treated as `{ filled: true,
|
|
5074
|
-
* strokeWidth: 0 }` — the pre-`ink` behavior, where the whole silhouette
|
|
5075
|
-
* interior is grabbable and the outline adds nothing. */
|
|
5076
|
-
ink?(node: Node$1<TData, string, TPose>, pose: TPose): NodeInk | null;
|
|
5077
|
-
}
|
|
5078
|
-
/** How a painter inks its silhouette. See {@link NodeShapeEntry.ink}. */
|
|
5079
|
-
interface NodeInk {
|
|
5080
|
-
/** True when the silhouette's interior is painted, and so grabbable. */
|
|
5081
|
-
filled: boolean;
|
|
5082
|
-
/** Stroke width in world units. `0` for no stroke. */
|
|
5083
|
-
strokeWidth: number;
|
|
5084
|
-
}
|
|
5085
|
-
/** Options for `registerNodeShape`. */
|
|
5086
|
-
interface RegisterNodeShapeOptions {
|
|
5087
|
-
/** `'high'` puts the painter ahead of all normally-registered ones (so
|
|
5088
|
-
* it can win over a kit built-in). `'normal'` appends at the end. */
|
|
5089
|
-
priority?: 'high' | 'normal';
|
|
5090
|
-
}
|
|
5091
|
-
/** Register a shape painter. Returns a disposer that removes it. */
|
|
5092
|
-
declare function registerNodeShape<TData, TPose>(painter: NodeShapeEntry<TData, TPose>, opts?: RegisterNodeShapeOptions): () => void;
|
|
5093
|
-
/** Find the painter that will render `node` — first match in priority
|
|
5094
|
-
* order. Returns undefined if no painter (including the built-in
|
|
5095
|
-
* fallback) accepts the node. */
|
|
5096
|
-
declare function findNodeShape<TData, TPose>(node: Node$1<TData, string, TPose>): NodeShapeEntry<TData, TPose> | undefined;
|
|
5097
|
-
/** Find the painter for `node` and ask it for the node's silhouette path,
|
|
5098
|
-
* in **world** coords. Returns null if no painter matches, or the matching
|
|
5099
|
-
* painter has no `silhouette` method, or the method returns null. Used by
|
|
5100
|
-
* clipping, generic non-rect hit-testing, lasso, and SVG export — anywhere
|
|
5101
|
-
* the kit needs the "closed boundary" of whatever this kind of node draws as.
|
|
5102
|
-
*
|
|
5103
|
-
* Painters return their silhouette in the pose's local (unrotated) frame;
|
|
5104
|
-
* this bakes `pose.rotation` on top via the shared rotation convention, so
|
|
5105
|
-
* clips/area-select of a rotated node use the rotated boundary the renderer
|
|
5106
|
-
* draws. (`paint()` is unaffected — it applies rotation via the render wrap,
|
|
5107
|
-
* not the silhouette, so there is no double-rotation.) */
|
|
5108
|
-
declare function findShapeSilhouette<TData, TPose>(node: Node$1<TData, string, TPose>, pose: TPose): Path | null;
|
|
5109
|
-
/** Find the painter for `node` and ask how it inks its silhouette. Returns
|
|
5110
|
-
* the painter's declared {@link NodeInk}, or `null` when no painter matches
|
|
5111
|
-
* or it declares none — callers substitute {@link DEFAULT_INK}. */
|
|
5112
|
-
declare function findShapeInk<TData, TPose>(node: Node$1<TData, string, TPose>, pose: TPose): NodeInk | null;
|
|
5113
|
-
/** Options for {@link shapeCoversPoint}. */
|
|
5114
|
-
interface ShapeCoversPointOptions {
|
|
5115
|
-
/** Extra grab distance around the outline, in **world** units. Callers
|
|
5116
|
-
* derive it from a screen-pixel slop and the view scale, the same way
|
|
5117
|
-
* affordance hit radii work.
|
|
5118
|
-
*
|
|
5119
|
-
* Without slop a hairline is a mathematically zero-width target: the
|
|
5120
|
-
* stroke of a 1px outline is half a world unit wide at scale 1, which no
|
|
5121
|
-
* one can hit. Defaults to `0` so a caller that hasn't thought about the
|
|
5122
|
-
* view still gets exact geometry rather than a wrong guess. */
|
|
5123
|
-
tolerance?: number;
|
|
5124
|
-
}
|
|
5125
|
-
/**
|
|
5126
|
-
* Does the shape `node` actually paints cover the world point?
|
|
5127
|
-
*
|
|
5128
|
-
* The pose rect says a node covers its whole bounding box. That is wrong for
|
|
5129
|
-
* everything that is not a rectangle: the concave notch of a star, the corner
|
|
5130
|
-
* outside an ellipse, the blank right half of a text box. This asks the
|
|
5131
|
-
* painter's silhouette instead, which is the same boundary used for clipping
|
|
5132
|
-
* and SVG export, so "what you can click" and "what is drawn" answer together.
|
|
5133
|
-
*
|
|
5134
|
-
* "What is drawn" includes the *ink*, not just the boundary. A shape whose
|
|
5135
|
-
* interior isn't filled — an outlined rect, a pencil stroke, a bare line — is
|
|
5136
|
-
* grabbable along its outline and not through its empty middle, which is the
|
|
5137
|
-
* opposite of what a fill test alone answers. The outline's grab width is the
|
|
5138
|
-
* stroke's half-width plus `tolerance`.
|
|
5139
|
-
*
|
|
5140
|
-
* A painter with no `silhouette`, or one that returns `null` for this node
|
|
5141
|
-
* (`kit:text` does, for a node with no non-blank lines), reports `true` —
|
|
5142
|
-
* "no opinion", leaving the caller's own AABB test as the answer. Callers
|
|
5143
|
-
* should keep that AABB test as a cheap pre-filter; this is the refinement,
|
|
5144
|
-
* not a replacement.
|
|
5145
|
-
*
|
|
5146
|
-
* Rotation is already baked by `findShapeSilhouette`, so the point is in
|
|
5147
|
-
* plain world coordinates.
|
|
5148
|
-
*/
|
|
5149
|
-
declare function shapeCoversPoint<TData, TPose>(node: Node$1<TData, string, TPose>, pose: TPose, x: number, y: number, opts?: ShapeCoversPointOptions): boolean;
|
|
5150
|
-
/** Snapshot of the current painters in evaluation order — `'high'` tier
|
|
5151
|
-
* first, then `'normal'`. Useful for debugging which painter handles a
|
|
5152
|
-
* given node. */
|
|
5153
|
-
declare function getNodeShapes(): readonly NodeShapeEntry[];
|
|
5154
|
-
/**
|
|
5155
|
-
* What a node's `data.fill` means to the built-in painters.
|
|
5156
|
-
*
|
|
5157
|
-
* A string is a color, `'none'` skips the fill, and an object is a
|
|
5158
|
-
* {@link FillStyle} used as-is — which is how a gradient or a pattern reaches
|
|
5159
|
-
* the renderer without a consumer registering a painter of its own. The
|
|
5160
|
-
* renderer has taken every `FillStyle` variant since the paint model landed;
|
|
5161
|
-
* only these two painters were narrower than it.
|
|
5162
|
-
*
|
|
5163
|
-
* `undefined` falls back to `data.color`, then to a default fill — but only
|
|
5164
|
-
* when there is no stroke, since a stroke-only path (pencil) should not
|
|
5165
|
-
* acquire one.
|
|
5166
|
-
*/
|
|
5167
|
-
type NodeFill = string | FillStyle;
|
|
5168
|
-
|
|
5169
5070
|
/**
|
|
5170
5071
|
* `defaultDrawOne` — the kit's default per-node draw function.
|
|
5171
5072
|
*
|
|
@@ -5195,7 +5096,7 @@ type NodeFill = string | FillStyle;
|
|
|
5195
5096
|
/** Paint one node the way the kit does by default: dispatch to the first
|
|
5196
5097
|
* registered node-shape painter that matches, then draw its `data.label` on
|
|
5197
5098
|
* top when it has one. Consumers replace or wrap this via `drawOne`. */
|
|
5198
|
-
declare function defaultDrawOne<TData, TLayer extends string, TPose>(node: Node$1<TData, TLayer, TPose>, pose: TPose, ctx?: NodePaintCtx): DrawCommand[];
|
|
5099
|
+
declare function defaultDrawOne<TData, TLayer extends string, TPose>(node: Node$1<TData, TLayer, TPose>, pose: TPose, _view?: View, ctx?: NodePaintCtx): DrawCommand[];
|
|
5199
5100
|
|
|
5200
5101
|
/** Default size in CSS pixels for selection corner-handles AND their
|
|
5201
5102
|
* hit-test radius, at `targetScale = 1`. Used by the SceneCanvas defaults;
|
|
@@ -5205,10 +5106,13 @@ declare function defaultDrawOne<TData, TLayer extends string, TPose>(node: Node$
|
|
|
5205
5106
|
* Deliberately unscaled: consumers reading this constant keep getting the
|
|
5206
5107
|
* number they always got. Kit-internal use sites multiply by
|
|
5207
5108
|
* `DeviceProfile.targetScale`. */
|
|
5208
|
-
declare const DEFAULT_HANDLE_SIZE
|
|
5109
|
+
declare const DEFAULT_HANDLE_SIZE: 8;
|
|
5110
|
+
/** Built-in tool ids that aren't shape tools — the ones with no entry in
|
|
5111
|
+
* the `core/shapeKinds` table. */
|
|
5112
|
+
declare const NON_SHAPE_BUILTIN_TOOLS: readonly ["select", "rotate", "hand"];
|
|
5209
5113
|
/** Built-in tool ids SceneCanvas knows how to mount when no `tools` prop
|
|
5210
5114
|
* is supplied. Pass a subset via `defaultTools` to slim the registered set. */
|
|
5211
|
-
type BuiltinToolId =
|
|
5115
|
+
type BuiltinToolId = (typeof NON_SHAPE_BUILTIN_TOOLS)[number] | BuiltinShapeToolId;
|
|
5212
5116
|
/** Named preset tool collections for the `toolBundle` prop. Maps to a
|
|
5213
5117
|
* `BuiltinToolId[]` consumed by SceneCanvas's internal `useTools`. */
|
|
5214
5118
|
type ToolBundle = 'minimal' | 'standard' | 'exhaustive';
|
|
@@ -5227,7 +5131,7 @@ interface SceneCanvasHit {
|
|
|
5227
5131
|
/** Props for `<SceneCanvas>`. Most are optional: a scene is the only thing it
|
|
5228
5132
|
* truly needs, and everything else — tools, layers, selection handling,
|
|
5229
5133
|
* layouts, animation — layers onto sensible defaults. */
|
|
5230
|
-
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' | 'geometry' | 'layers' | 'onBackgroundClick' | 'getIsVisible'> & {
|
|
5134
|
+
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' | 'geometry' | 'layers' | 'onBackgroundClick' | 'getIsVisible' | 'contentVersion'> & {
|
|
5231
5135
|
/** A `Scene` (typically from `useScene`) — or a `SerializedScene`
|
|
5232
5136
|
* JSON object, which SceneCanvas bakes into a Scene internally on
|
|
5233
5137
|
* first render. The serialized form is read once; subsequent
|
|
@@ -5483,17 +5387,19 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5483
5387
|
ambient?: AnyTool[];
|
|
5484
5388
|
/** Viewport feature wiring.
|
|
5485
5389
|
*
|
|
5486
|
-
* - `inertia
|
|
5487
|
-
*
|
|
5488
|
-
* - `pan` (wheel pan)
|
|
5489
|
-
* on by default; pass `false` to
|
|
5490
|
-
* the kit's `viewport
|
|
5491
|
-
* the actions registry — disabling via the
|
|
5492
|
-
* (`actions: { 'viewport.wheelPan': null }`) also works
|
|
5390
|
+
* - `inertia` and `animatedZoom` are opt-in: pass `true` for defaults or
|
|
5391
|
+
* an object to tune. Omitted means off.
|
|
5392
|
+
* - `pan` (wheel pan), `zoom` (Cmd+wheel + Cmd+=/-/0) and `pinchZoom`
|
|
5393
|
+
* (two-finger pinch) are opt-OUT: on by default; pass `false` to
|
|
5394
|
+
* disable. All three are wired by registering the kit's `viewport.*`
|
|
5395
|
+
* action descriptors with the actions registry — disabling via the
|
|
5396
|
+
* `actions` prop (`actions: { 'viewport.wheelPan': null }`) also works
|
|
5397
|
+
* and runs after this.
|
|
5493
5398
|
*
|
|
5494
|
-
* When omitted entirely, no hand
|
|
5495
|
-
*
|
|
5496
|
-
* default). Pass `{ pan: false, zoom: false }` to opt
|
|
5399
|
+
* When omitted entirely, no hand tool is registered but the default wheel
|
|
5400
|
+
* pan, Cmd+wheel/key zoom and pinch zoom remain wired (canvas-first
|
|
5401
|
+
* default). Pass `{ pan: false, zoom: false, pinchZoom: false }` to opt
|
|
5402
|
+
* out entirely. */
|
|
5497
5403
|
viewport?: {
|
|
5498
5404
|
inertia?: boolean | {
|
|
5499
5405
|
friction?: number;
|
|
@@ -5501,15 +5407,14 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5501
5407
|
boundary?: 'stop' | 'bounce' | 'spring';
|
|
5502
5408
|
bounds?: PanBounds;
|
|
5503
5409
|
};
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
};
|
|
5410
|
+
/** Two-finger pinch zoom. `true`/omitted = on with the kit's 0.1–8
|
|
5411
|
+
* clamp; `false` disables. An object sets the scale clamp. */
|
|
5412
|
+
pinchZoom?: boolean | PinchZoomOptions;
|
|
5413
|
+
/** Glide Cmd+=/-/0 instead of jumping. `true` uses the kit defaults
|
|
5414
|
+
* (250 ms, ease-out-cubic); a {@link ViewportZoomAnimateOptions} tunes
|
|
5415
|
+
* duration, easing, interpolator and the reset-branch duration. Wheel
|
|
5416
|
+
* and pinch are unaffected — their input already samples every frame. */
|
|
5417
|
+
animatedZoom?: boolean | ViewportZoomAnimateOptions;
|
|
5513
5418
|
pan?: boolean;
|
|
5514
5419
|
/** Wheel/keyboard zoom. `true`/omitted = default Cmd+wheel zoom with the
|
|
5515
5420
|
* kit's 0.1–8 clamp; `false` disables. Pass a {@link ViewportZoomOptions}
|
|
@@ -5518,10 +5423,11 @@ type SceneCanvasProps<TData, TLayer extends string, TPose> = Omit<CanvasProps<No
|
|
|
5518
5423
|
zoom?: boolean | ViewportZoomOptions;
|
|
5519
5424
|
/** Callback invoked by Cmd-0 (`viewport.zoom` action's `reset` branch).
|
|
5520
5425
|
* When supplied, replaces the default reset-to-identity behavior —
|
|
5521
|
-
* consumers typically refit the document page into the workspace
|
|
5522
|
-
*
|
|
5523
|
-
*
|
|
5524
|
-
|
|
5426
|
+
* consumers typically refit the document page into the workspace via
|
|
5427
|
+
* `fitViewToBounds`. Return the target `View` to let the kit animate
|
|
5428
|
+
* there when `animatedZoom` is on; return nothing to dispatch it
|
|
5429
|
+
* yourself, which is what a controlled canvas does. */
|
|
5430
|
+
recenter?: () => View | void;
|
|
5525
5431
|
};
|
|
5526
5432
|
/**
|
|
5527
5433
|
* @experimental
|
|
@@ -5933,17 +5839,6 @@ declare const inferredNodeProperties: readonly NodePropertiesEntry[];
|
|
|
5933
5839
|
* in sync by hand where it matters (DPR handling, viewToMat3 wrap).
|
|
5934
5840
|
*/
|
|
5935
5841
|
|
|
5936
|
-
/**
|
|
5937
|
-
* Per-node draw function. Mirrors the scene-slot `drawOne` signature on
|
|
5938
|
-
* `<SceneCanvas>` (`SceneSlotConfig.drawOne`) so consumers can reuse the
|
|
5939
|
-
* same callback (or a simplified variant) between a main canvas and a
|
|
5940
|
-
* detached scene-view canvas.
|
|
5941
|
-
*
|
|
5942
|
-
* The function is called once per node in `scene.renderOrder()`. Returned
|
|
5943
|
-
* commands are in world coords; the caller's `view` is applied at the
|
|
5944
|
-
* group level (see `renderSceneToCanvas`'s implementation).
|
|
5945
|
-
*/
|
|
5946
|
-
type SceneViewDrawOne<TData, TLayer extends string, TPose> = (node: Node$1<TData, TLayer, TPose>, pose: TPose, view: View) => DrawCommand[];
|
|
5947
5842
|
/** What to draw into an existing canvas: the scene, the view, and the same
|
|
5948
5843
|
* painting hooks `<SceneCanvas>` takes. */
|
|
5949
5844
|
interface RenderSceneToCanvasArgs<TData, TLayer extends string, TPose> {
|
|
@@ -6101,12 +5996,16 @@ interface UseSceneTrivialOptions<TItem extends {
|
|
|
6101
5996
|
items: readonly TItem[];
|
|
6102
5997
|
historyLimit?: number;
|
|
6103
5998
|
generateId?: () => NodeId;
|
|
5999
|
+
/** Re-render the host on every scene mutation. Default `true`. See
|
|
6000
|
+
* {@link UseSceneOptions.subscribe}. */
|
|
6001
|
+
subscribe?: boolean;
|
|
6104
6002
|
}
|
|
6105
6003
|
declare const DEFAULT_LAYER: "default";
|
|
6106
6004
|
type DefaultLayer = typeof DEFAULT_LAYER;
|
|
6107
6005
|
/** React hook returning a kit-owned `Scene`. The Scene is constructed once
|
|
6108
6006
|
* per host component and tracked via `useSyncExternalStore`, so React re-
|
|
6109
|
-
* renders on every Scene mutation (including undo/redo)
|
|
6007
|
+
* renders on every Scene mutation (including undo/redo) unless
|
|
6008
|
+
* `subscribe: false` opts out.
|
|
6110
6009
|
*
|
|
6111
6010
|
* Two call shapes:
|
|
6112
6011
|
* - **Trivial**: `useScene({ items })` — one auto-registered system layer
|
|
@@ -6224,7 +6123,12 @@ interface MinimapCanvasProps<TData, TLayer extends string, TPose> {
|
|
|
6224
6123
|
* can reuse it (typically simplified — just colored AABBs). */
|
|
6225
6124
|
drawOne: SceneViewDrawOne<TData, TLayer, TPose>;
|
|
6226
6125
|
/** Fit policy. Defaults to `"scene"` (AABB union of leaf poses). See
|
|
6227
|
-
* `MinimapFit` for the full shape.
|
|
6126
|
+
* `MinimapFit` for the full shape.
|
|
6127
|
+
*
|
|
6128
|
+
* Framing is derived from **document** poses, not `scene.overrides` — a
|
|
6129
|
+
* node moved by an override paints where the override puts it, outside the
|
|
6130
|
+
* frame if it goes there, rather than making the whole minimap rescale on
|
|
6131
|
+
* every frame of a drag or a settle. */
|
|
6228
6132
|
fit?: MinimapFit<TData, TLayer, TPose>;
|
|
6229
6133
|
/** Pose → AABB. Defaults to identity (`pose as Bounds`), matching
|
|
6230
6134
|
* `sceneAdapter` / `useSelectTool`. */
|
|
@@ -6283,9 +6187,10 @@ interface RenderSceneToPixelsArgs<TData, TLayer extends string, TPose> {
|
|
|
6283
6187
|
y: number;
|
|
6284
6188
|
};
|
|
6285
6189
|
/** Per-node draw callback. Default: `defaultDrawOne` with `resolveImage`
|
|
6286
|
-
*
|
|
6287
|
-
* want resolver injection should call
|
|
6288
|
-
* themselves
|
|
6190
|
+
* merged into the `NodePaintCtx` the scene walk supplies. Custom `drawOne`
|
|
6191
|
+
* callers that still want resolver injection should call
|
|
6192
|
+
* `defaultDrawOne(node, pose, view, { ...ctx, resolveImage })` themselves —
|
|
6193
|
+
* dropping the walk's `ctx` drops derived geometry with it. */
|
|
6289
6194
|
drawOne?: SceneViewDrawOne<TData, TLayer, TPose>;
|
|
6290
6195
|
/** Bitmap resolver for image nodes — lets consumers reuse their own decode
|
|
6291
6196
|
* caches. `undefined` results paint the deterministic grey placeholder
|
|
@@ -6766,8 +6671,6 @@ declare const PATH_ANCHOR_CHROME_ID = "path-edit.anchors";
|
|
|
6766
6671
|
*/
|
|
6767
6672
|
declare function createPathAnchorAffordances(getAnchorState: () => AnchorState | null, opts?: PathAnchorAffordanceOptions): Affordance[];
|
|
6768
6673
|
|
|
6769
|
-
/** Pluggable text-painting strategy. The default fills white at `(x, y)`; markdown renderers replace this. */
|
|
6770
|
-
type TextRenderer = (ctx: CanvasRenderingContext2D, text: string, x: number, y: number) => void;
|
|
6771
6674
|
/** Visual options for `renderLabel`. */
|
|
6772
6675
|
interface LabelOptions {
|
|
6773
6676
|
align?: 'center' | 'left';
|
|
@@ -6789,112 +6692,6 @@ declare function renderLabel(ctx: CanvasRenderingContext2D, text: string, x: num
|
|
|
6789
6692
|
/** Default `TextRenderer` used by `renderLabel`: white fill, no styling. */
|
|
6790
6693
|
declare const defaultLabelTextRenderer: TextRenderer;
|
|
6791
6694
|
|
|
6792
|
-
/** Width-measurement strategy for `layoutMarkdown`; canvas-backed default supplied by `createMarkdownRenderer`. */
|
|
6793
|
-
type MeasureFn = (text: string, fontSize: number, bold: boolean, italic: boolean) => number;
|
|
6794
|
-
/** A `StyledRun` with its computed x-offset relative to the start of its line. */
|
|
6795
|
-
interface PositionedRun extends StyledRun {
|
|
6796
|
-
x: number;
|
|
6797
|
-
}
|
|
6798
|
-
/** A single laid-out line of text: its positioned runs, total width, and computed line height. */
|
|
6799
|
-
interface LayoutLine {
|
|
6800
|
-
runs: PositionedRun[];
|
|
6801
|
-
width: number;
|
|
6802
|
-
height: number;
|
|
6803
|
-
}
|
|
6804
|
-
/** Output of `layoutMarkdown`: per-line breakdown plus overall block dimensions. */
|
|
6805
|
-
interface LayoutResult {
|
|
6806
|
-
lines: LayoutLine[];
|
|
6807
|
-
width: number;
|
|
6808
|
-
height: number;
|
|
6809
|
-
}
|
|
6810
|
-
/** Word-wrap parsed runs into lines bounded by `maxWidth`; pass `Infinity` for single-line layout. */
|
|
6811
|
-
declare function layoutMarkdown(runs: StyledRun[], maxWidth: number, fontSize: number, measure: MeasureFn, lineHeightFactor?: number): LayoutResult;
|
|
6812
|
-
|
|
6813
|
-
/** Font styling options threaded through `createMarkdownRenderer`. */
|
|
6814
|
-
interface MarkdownFontOptions {
|
|
6815
|
-
/** Font-family spec (e.g. `'"Iowan Old Style", Georgia, serif'`). Defaults to `sans-serif`. */
|
|
6816
|
-
family?: string;
|
|
6817
|
-
/** Numeric weight applied to non-bold runs. Bold runs always use `bold`. Default `normal`. */
|
|
6818
|
-
weight?: string | number;
|
|
6819
|
-
/** Override fill color. When set, used for all runs (italic and bold). */
|
|
6820
|
-
color?: string;
|
|
6821
|
-
/** Multiplier applied to font size for line height. Default 1.3. */
|
|
6822
|
-
lineHeight?: number;
|
|
6823
|
-
}
|
|
6824
|
-
/** Build a fill+stroke `TextRenderer` pair for a markdown string at the given size; pre-computes layout once. */
|
|
6825
|
-
declare function createMarkdownRenderer(ctx: CanvasRenderingContext2D, text: string, fontSize: number, maxWidth?: number, fontOpts?: MarkdownFontOptions): {
|
|
6826
|
-
renderer: TextRenderer;
|
|
6827
|
-
strokeRenderer: TextRenderer;
|
|
6828
|
-
width: number;
|
|
6829
|
-
height: number;
|
|
6830
|
-
};
|
|
6831
|
-
|
|
6832
|
-
/**
|
|
6833
|
-
* Wrap-aware text measurement. Greedy word-wrap against `maxWidth` using
|
|
6834
|
-
* `ctx.measureText`. Lines explicitly broken by `\n` are preserved; long
|
|
6835
|
-
* single words that exceed `maxWidth` are emitted on their own line without
|
|
6836
|
-
* mid-word breaking (caller can decide to clip).
|
|
6837
|
-
*
|
|
6838
|
-
* Returns the laid-out lines, the total block height in world units
|
|
6839
|
-
* (`lines.length * fontSize * lineHeight`), and per-line `lineStarts` —
|
|
6840
|
-
* the offset of each line's first character in the original `text`. The
|
|
6841
|
-
* starts are used by `caretIndexAt` to map a clicked (x, y) back to a
|
|
6842
|
-
* character offset in the source string. Trailing whitespace consumed by
|
|
6843
|
-
* the wrap is not included in `lines[i]` but is implicit in the gap
|
|
6844
|
-
* between `lineStarts[i] + lines[i].length` and `lineStarts[i + 1]`.
|
|
6845
|
-
*
|
|
6846
|
-
* The caller owns the `ctx.font` setup — pass a context whose `font`
|
|
6847
|
-
* already matches `style` (use `fontString(style)`).
|
|
6848
|
-
*/
|
|
6849
|
-
|
|
6850
|
-
/**
|
|
6851
|
-
* Advance width of `text` in world units, tracking included.
|
|
6852
|
-
*
|
|
6853
|
-
* `letter-spacing` is not part of the CSS `font` shorthand, so a context
|
|
6854
|
-
* whose `font` was set from `fontString(style)` measures glyphs only. The
|
|
6855
|
-
* GL path (`layoutRuns`) adds `letterSpacing` after **every** code point
|
|
6856
|
-
* including the last, matching CSS, so this does too — and every 2D-side
|
|
6857
|
-
* width has to go through here or the two paths disagree about where a line
|
|
6858
|
-
* breaks.
|
|
6859
|
-
*/
|
|
6860
|
-
declare function measuredWidth(ctx: CanvasRenderingContext2D, text: string, style: ResolvedTextStyle): number;
|
|
6861
|
-
/** Result of `measureText`: wrapped lines, per-line source offsets, and total block height. */
|
|
6862
|
-
interface MeasuredText {
|
|
6863
|
-
lines: string[];
|
|
6864
|
-
lineStarts: number[];
|
|
6865
|
-
height: number;
|
|
6866
|
-
}
|
|
6867
|
-
/** Greedy word-wrap text measurement against `maxWidth`; preserves explicit `\n` breaks. */
|
|
6868
|
-
declare function measureText(ctx: CanvasRenderingContext2D, text: string, maxWidth: number, style: ResolvedTextStyle): MeasuredText;
|
|
6869
|
-
|
|
6870
|
-
/** Options for `measureTextBounds`. */
|
|
6871
|
-
interface MeasureTextBoundsOpts {
|
|
6872
|
-
/** Wrap width; words exceeding it start a new line. Default `Infinity` (no wrap). */
|
|
6873
|
-
maxWidth?: number;
|
|
6874
|
-
/** Overrides `style`'s `lineHeight` multiplier for this measurement. */
|
|
6875
|
-
lineHeight?: number;
|
|
6876
|
-
}
|
|
6877
|
-
/**
|
|
6878
|
-
* Measure how the GL/MSDF renderer will lay out a single plain-text string,
|
|
6879
|
-
* using the registered font atlas metrics. Mirrors {@link textCommand} exactly
|
|
6880
|
-
* (`resolveTextStyle` → `resolveRuns` → `layoutRuns`), so the returned bounds
|
|
6881
|
-
* match what actually gets drawn — use it to size backgrounds/pills, place
|
|
6882
|
-
* labels, or test overlap without guessing widths.
|
|
6883
|
-
*
|
|
6884
|
-
* Pass `opts.maxWidth` to measure word-wrapped height (e.g. for a fixed-width
|
|
6885
|
-
* text box); omitting it measures the unwrapped single-line width. `opts.lineHeight`
|
|
6886
|
-
* overrides the style's multiplier without changing `style` itself.
|
|
6887
|
-
*
|
|
6888
|
-
* Returns `{ width, height }` in the same units as `style.fontSize`. The font
|
|
6889
|
-
* must already be registered via `registerFont`; an unregistered family falls
|
|
6890
|
-
* back to the atlas fallback glyph (and warns), so register fonts at app boot
|
|
6891
|
-
* before measuring.
|
|
6892
|
-
*/
|
|
6893
|
-
declare function measureTextBounds(text: string, style?: TextStyle, opts?: MeasureTextBoundsOpts): {
|
|
6894
|
-
width: number;
|
|
6895
|
-
height: number;
|
|
6896
|
-
};
|
|
6897
|
-
|
|
6898
6695
|
/**
|
|
6899
6696
|
* Text RenderLayer. Emits one TextDrawCommand per text node carrying the
|
|
6900
6697
|
* node's resolved runs and bounding rect. Word wrap and multi-line layout
|
|
@@ -6907,135 +6704,70 @@ declare function measureTextBounds(text: string, style?: TextStyle, opts?: Measu
|
|
|
6907
6704
|
* `TextDrawCommand`'s contract).
|
|
6908
6705
|
*/
|
|
6909
6706
|
|
|
6910
|
-
/** Pose for a text node: bounding rect plus the text and optional style. */
|
|
6911
|
-
interface TextPose {
|
|
6912
|
-
x: number;
|
|
6913
|
-
y: number;
|
|
6914
|
-
width: number;
|
|
6915
|
-
height: number;
|
|
6916
|
-
text: string;
|
|
6917
|
-
/** Rich-text runs. When present, `runsToPlainText(runs)` must equal `text`. */
|
|
6918
|
-
runs?: StyledRun[];
|
|
6919
|
-
style?: TextStyle;
|
|
6920
|
-
/** Box vertical alignment within `[y, y+height]`. Default 'top'. */
|
|
6921
|
-
verticalAlign?: TextVerticalAlign;
|
|
6922
|
-
}
|
|
6923
6707
|
/** Options for `createTextLayer`. */
|
|
6924
6708
|
interface CreateTextLayerOpts<T> {
|
|
6925
6709
|
id?: string;
|
|
6926
6710
|
label?: string;
|
|
6927
|
-
getTexts: () => readonly T[];
|
|
6928
|
-
getPose: (node: T) => TextPose;
|
|
6929
|
-
/** Optional per-node hide hook (e.g., suppress while editing). */
|
|
6930
|
-
isHidden?: (node: T) => boolean;
|
|
6931
|
-
/** When `true`, each text command is wrapped in a clipped group so any
|
|
6932
|
-
* overflow beyond the pose's `(width × height)` is hidden. Default
|
|
6933
|
-
* `false` (legacy: text can spill outside the declared bounds). Opt-in
|
|
6934
|
-
* so existing consumers who rely on overflow keep working. */
|
|
6935
|
-
clipToBounds?: boolean;
|
|
6936
|
-
}
|
|
6937
|
-
/** Build a `RenderLayer` that emits one `TextDrawCommand` per text node. */
|
|
6938
|
-
declare function createTextLayer<T>(opts: CreateTextLayerOpts<T>): RenderLayer<unknown>;
|
|
6939
|
-
|
|
6940
|
-
/**
|
|
6941
|
-
* Hit-testing for text nodes.
|
|
6942
|
-
*
|
|
6943
|
-
* `pointInTextPose` does a coarse pose-rect test — suitable for click-to-edit
|
|
6944
|
-
* where the pose rect is the authoritative bounding box (selection outline,
|
|
6945
|
-
* drag target).
|
|
6946
|
-
*
|
|
6947
|
-
* `caretIndexAt` does the finer test: given a world-space (x, y) inside the
|
|
6948
|
-
* pose, returns the corresponding character offset in `pose.text` so the
|
|
6949
|
-
* consumer can place the caret on click. Re-runs the wrap to map the click
|
|
6950
|
-
* back through `lineStarts`; respects `style.align` for line anchoring.
|
|
6951
|
-
*/
|
|
6952
|
-
|
|
6953
|
-
/** Options for `pointInTextPose`. */
|
|
6954
|
-
interface PointInTextPoseOpts {
|
|
6955
|
-
/** Extra padding (world units) added to the rect on all sides. Default 0. */
|
|
6956
|
-
padding?: number;
|
|
6957
|
-
}
|
|
6958
|
-
/** Coarse pose-rect hit-test for a text node — suitable for click-to-edit dispatch. */
|
|
6959
|
-
declare function pointInTextPose(x: number, y: number, pose: TextPose, opts?: PointInTextPoseOpts): boolean;
|
|
6960
|
-
/**
|
|
6961
|
-
* Map a world-space point inside `pose` to a character offset into
|
|
6962
|
-
* `pose.text` (0..text.length). Clicks above the first line clamp to 0;
|
|
6963
|
-
* clicks below the last line clamp to `text.length`. Within a line, the
|
|
6964
|
-
* caret lands between two glyphs at whichever side of the glyph midpoint
|
|
6965
|
-
* `x` falls on — the standard "snap caret to nearest character boundary"
|
|
6966
|
-
* rule.
|
|
6967
|
-
*
|
|
6968
|
-
* The `ctx` is used only for `measureText`; its `font` is set internally
|
|
6969
|
-
* to match the resolved text style. Pass any 2D context (the same one used
|
|
6970
|
-
* to render is fine).
|
|
6971
|
-
*/
|
|
6972
|
-
declare function caretIndexAt(ctx: CanvasRenderingContext2D, x: number, y: number, pose: TextPose): number;
|
|
6973
|
-
|
|
6974
|
-
/**
|
|
6975
|
-
* Polygon-vs-axis-aligned-rect tests. Pure functions; no React/kit deps.
|
|
6976
|
-
*
|
|
6977
|
-
* `polygon` is a closed polyline given as an ordered vertex array; the
|
|
6978
|
-
* closing edge from `polygon[N-1]` to `polygon[0]` is implicit. Even-odd
|
|
6979
|
-
* fill rule (matches `pointInPath`).
|
|
6980
|
-
*/
|
|
6981
|
-
/** A 2D point or vector. */
|
|
6982
|
-
interface Vec2 {
|
|
6983
|
-
x: number;
|
|
6984
|
-
y: number;
|
|
6985
|
-
}
|
|
6986
|
-
/** An axis-aligned rectangle. */
|
|
6987
|
-
interface Rect {
|
|
6988
|
-
x: number;
|
|
6989
|
-
y: number;
|
|
6990
|
-
width: number;
|
|
6991
|
-
height: number;
|
|
6711
|
+
getTexts: () => readonly T[];
|
|
6712
|
+
getPose: (node: T) => TextPose;
|
|
6713
|
+
/** Optional per-node hide hook (e.g., suppress while editing). */
|
|
6714
|
+
isHidden?: (node: T) => boolean;
|
|
6715
|
+
/** When `true`, each text command is wrapped in a clipped group so any
|
|
6716
|
+
* overflow beyond the pose's `(width × height)` is hidden. Default
|
|
6717
|
+
* `false` (legacy: text can spill outside the declared bounds). Opt-in
|
|
6718
|
+
* so existing consumers who rely on overflow keep working. */
|
|
6719
|
+
clipToBounds?: boolean;
|
|
6992
6720
|
}
|
|
6721
|
+
/** Build a `RenderLayer` that emits one `TextDrawCommand` per text node. */
|
|
6722
|
+
declare function createTextLayer<T>(opts: CreateTextLayerOpts<T>): RenderLayer<unknown>;
|
|
6993
6723
|
|
|
6994
6724
|
/**
|
|
6995
|
-
*
|
|
6996
|
-
*
|
|
6997
|
-
* A text pose is a *wrap box*, not a bounding box: `"Away"` in a 309-unit-wide
|
|
6998
|
-
* box leaves most of the box empty, and anything that treats the pose as the
|
|
6999
|
-
* node's extent — picking, lasso, clipping, SVG export — claims that empty
|
|
7000
|
-
* space. `textLineBoxes` returns the per-line rectangles instead.
|
|
6725
|
+
* Hit-testing for text nodes.
|
|
7001
6726
|
*
|
|
7002
|
-
*
|
|
7003
|
-
*
|
|
7004
|
-
*
|
|
7005
|
-
* particular they honor `align` (a centered line reports its own span, not the
|
|
7006
|
-
* wrap width) and `verticalAlign` (the block shifts inside `[y, y + height]`
|
|
7007
|
-
* exactly as `drawText` shifts the quads).
|
|
6727
|
+
* `pointInTextPose` does a coarse pose-rect test — suitable for click-to-edit
|
|
6728
|
+
* where the pose rect is the authoritative bounding box (selection outline,
|
|
6729
|
+
* drag target).
|
|
7008
6730
|
*
|
|
7009
|
-
*
|
|
7010
|
-
*
|
|
7011
|
-
*
|
|
7012
|
-
*
|
|
7013
|
-
*
|
|
6731
|
+
* `caretIndexAt` does the finer test: given a world-space (x, y) inside the
|
|
6732
|
+
* pose, returns the corresponding character offset so the consumer can place
|
|
6733
|
+
* the caret on click. It reads the caret stops off the same
|
|
6734
|
+
* `cachedLayoutRuns` result the renderer paints and `textLineBoxes` picks
|
|
6735
|
+
* against, so the caret cannot land on a different line — or between
|
|
6736
|
+
* different glyphs — than the one under the pointer.
|
|
7014
6737
|
*/
|
|
7015
6738
|
|
|
7016
|
-
/** Options for
|
|
7017
|
-
interface
|
|
7018
|
-
/**
|
|
7019
|
-
* Picking wants a little slack so a single hairline row of text is still
|
|
7020
|
-
* grabbable; clipping and export want none. */
|
|
6739
|
+
/** Options for `pointInTextPose`. */
|
|
6740
|
+
interface PointInTextPoseOpts {
|
|
6741
|
+
/** Extra padding (world units) added to the rect on all sides. Default 0. */
|
|
7021
6742
|
padding?: number;
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
6743
|
+
}
|
|
6744
|
+
/** Coarse pose-rect hit-test for a text node — suitable for click-to-edit dispatch. */
|
|
6745
|
+
declare function pointInTextPose(x: number, y: number, pose: TextPose, opts?: PointInTextPoseOpts): boolean;
|
|
6746
|
+
/** Options for `caretIndexAt`. */
|
|
6747
|
+
interface CaretIndexAtOpts {
|
|
7026
6748
|
/**
|
|
7027
6749
|
* Wrap width. Default `pose.width`, which is what `createTextLayer` passes
|
|
7028
6750
|
* and what `TextPose` means by its box.
|
|
7029
6751
|
*
|
|
7030
6752
|
* Pass `Infinity` for a node painted by the built-in `kit:text` painter:
|
|
7031
|
-
* that painter deliberately does
|
|
7032
|
-
*
|
|
7033
|
-
*
|
|
6753
|
+
* that painter deliberately does not forward `maxWidth`, so its text does
|
|
6754
|
+
* not wrap, and a caret mapped through a finite width would answer for a
|
|
6755
|
+
* line break the paint never made. Mirrors `textLineBoxes`.
|
|
7034
6756
|
*/
|
|
7035
6757
|
maxWidth?: number;
|
|
7036
6758
|
}
|
|
7037
|
-
/**
|
|
7038
|
-
|
|
6759
|
+
/**
|
|
6760
|
+
* Map a world-space point inside `pose` to a character offset into the pose's
|
|
6761
|
+
* text (0..length). Clicks above the first line clamp to 0; clicks below the
|
|
6762
|
+
* last line clamp to the end. Within a line, the caret lands between two
|
|
6763
|
+
* glyphs at whichever side of the advance cell's midpoint `x` falls on — the
|
|
6764
|
+
* standard "snap caret to nearest character boundary" rule.
|
|
6765
|
+
*
|
|
6766
|
+
* Honors `pose.runs` (a mixed-size line snaps on the cells each run actually
|
|
6767
|
+
* produced) and `pose.verticalAlign`. The offset is into the runs'
|
|
6768
|
+
* concatenated text, which `TextPose` requires to equal `pose.text`.
|
|
6769
|
+
*/
|
|
6770
|
+
declare function caretIndexAt(x: number, y: number, pose: TextPose, opts?: CaretIndexAtOpts): number;
|
|
7039
6771
|
|
|
7040
6772
|
/**
|
|
7041
6773
|
* Resize a text node's pose to fit its content. Pure helper — does not own
|
|
@@ -7069,7 +6801,60 @@ interface FitTextPoseOptions {
|
|
|
7069
6801
|
};
|
|
7070
6802
|
}
|
|
7071
6803
|
/** Recompute a `TextPose`'s `width`/`height` to fit its content; pure helper, doesn't mutate scene state. */
|
|
7072
|
-
declare function fitTextPose(
|
|
6804
|
+
declare function fitTextPose(pose: TextPose, opts?: FitTextPoseOptions): TextPose;
|
|
6805
|
+
|
|
6806
|
+
/**
|
|
6807
|
+
* Turning a run-level flag **off** inside a node that sets it.
|
|
6808
|
+
*
|
|
6809
|
+
* Run flags are additive over the node's `TextStyle` — a run turns `bold` /
|
|
6810
|
+
* `italic` / `underline` / `strikethrough` on, never off (see the contract at
|
|
6811
|
+
* the top of `rangeStyle.ts`). So "select a word inside an underlined node and
|
|
6812
|
+
* hit U" is unrepresentable by the stored shape, and the character bar can
|
|
6813
|
+
* only refuse.
|
|
6814
|
+
*
|
|
6815
|
+
* This resolves it by rewriting rather than by widening the model: clear the
|
|
6816
|
+
* flag on the node, and set it on every run *outside* the range. The rendered
|
|
6817
|
+
* result is identical and the edit becomes expressible, with `StyledRun`
|
|
6818
|
+
* unchanged — so nothing a document can already contain changes meaning, which
|
|
6819
|
+
* matters while the flags are heading for a persisted format.
|
|
6820
|
+
*
|
|
6821
|
+
* The alternative was a tri-state run flag (`true` / `false` / inherit). It
|
|
6822
|
+
* cannot cover `bold` or `italic`: those are booleans on a run but
|
|
6823
|
+
* `fontWeight` and `fontStyle` on the node, so a run's `false` has no node-level
|
|
6824
|
+
* boolean to override. Tri-state fixes two of the five flags; this fixes all
|
|
6825
|
+
* five.
|
|
6826
|
+
*/
|
|
6827
|
+
|
|
6828
|
+
/** The additive run flags. */
|
|
6829
|
+
type FlagKey = 'bold' | 'italic' | 'underline' | 'strikethrough' | 'overline';
|
|
6830
|
+
/** The result of toggling a style flag over a text range: the rewritten runs
|
|
6831
|
+
* and node style, and whether the change could be made at all. */
|
|
6832
|
+
interface SetFlagResult {
|
|
6833
|
+
runs: StyledRun[];
|
|
6834
|
+
style: TextStyle;
|
|
6835
|
+
/**
|
|
6836
|
+
* False when the node flag could not be lowered without changing what is
|
|
6837
|
+
* drawn, and nothing was written. The only case is a `fontWeight` the run
|
|
6838
|
+
* boolean cannot express: `run.bold` resolves to exactly 700 everywhere, so
|
|
6839
|
+
* a node at 900 cannot have its weight pushed onto its runs. Callers should
|
|
6840
|
+
* disable the control rather than apply a silent downgrade.
|
|
6841
|
+
*/
|
|
6842
|
+
applied: boolean;
|
|
6843
|
+
}
|
|
6844
|
+
/** Does the node style carry this flag? */
|
|
6845
|
+
declare function nodeHasFlag(style: TextStyle, key: FlagKey): boolean;
|
|
6846
|
+
/**
|
|
6847
|
+
* Set `key` to `value` over `[start, end)`.
|
|
6848
|
+
*
|
|
6849
|
+
* Turning a flag **on**, or off in a node that doesn't set it, is the ordinary
|
|
6850
|
+
* additive write and leaves `style` alone. Turning it off in a node that *does*
|
|
6851
|
+
* set it takes the rewrite: the node flag is cleared and the flag is written
|
|
6852
|
+
* onto the complement of the range.
|
|
6853
|
+
*
|
|
6854
|
+
* `runs` is normalized on every path, so the complement collapses back to one
|
|
6855
|
+
* run when the range is empty and the whole array coalesces as usual.
|
|
6856
|
+
*/
|
|
6857
|
+
declare function setFlagOverRange(runs: readonly StyledRun[], style: TextStyle, start: number, end: number, key: FlagKey, value: boolean): SetFlagResult;
|
|
7073
6858
|
|
|
7074
6859
|
/**
|
|
7075
6860
|
* The kit-wide "these values disagree" sentinel. Used wherever a value is
|
|
@@ -7160,6 +6945,13 @@ declare function applyStyleToRange(runs: readonly StyledRun[], start: number, en
|
|
|
7160
6945
|
* (`isHidden: (n) => n.id === editingId`) so the overlay isn't drawn twice.
|
|
7161
6946
|
*/
|
|
7162
6947
|
|
|
6948
|
+
type StyleFlag = FlagKey;
|
|
6949
|
+
/**
|
|
6950
|
+
* A styling a shortcut or a control toggles. The additive booleans, plus the
|
|
6951
|
+
* two `script` values — which are exclusive rather than additive, so they
|
|
6952
|
+
* toggle against one enum rather than each owning a boolean.
|
|
6953
|
+
*/
|
|
6954
|
+
type StyleToggle = StyleFlag | 'super' | 'sub';
|
|
7163
6955
|
/**
|
|
7164
6956
|
* The caret's character range within the text being edited. Half-open
|
|
7165
6957
|
* `[start, end)` over the concatenated run text, normalized so `start <= end`
|
|
@@ -7214,6 +7006,13 @@ interface UseTextEditOptions {
|
|
|
7214
7006
|
getText: (id: string) => string;
|
|
7215
7007
|
/** Read style for `id` (used for font setup on the overlay). */
|
|
7216
7008
|
getStyle: (id: string) => TextStyle | undefined;
|
|
7009
|
+
/**
|
|
7010
|
+
* Read the node's paint for `id` — its `data.fill` / `data.stroke`. The
|
|
7011
|
+
* overlay paints its text and caret from the fill, so omitting this
|
|
7012
|
+
* renders every node's editor in the default black however the node
|
|
7013
|
+
* itself is painted.
|
|
7014
|
+
*/
|
|
7015
|
+
getPaint?: (id: string) => TextPaint | undefined;
|
|
7217
7016
|
/**
|
|
7218
7017
|
* Write style back for `id`. Optional; needed only to turn a flag **off**
|
|
7219
7018
|
* inside a node whose own `TextStyle` sets it. Run flags are additive, so
|
|
@@ -7278,8 +7077,8 @@ interface UseTextEditReturn {
|
|
|
7278
7077
|
/**
|
|
7279
7078
|
* The caret's character range, or `null` when nothing is being edited. A
|
|
7280
7079
|
* collapsed caret reports `{ start: n, end: n }`, so `null` and "caret at
|
|
7281
|
-
* n" stay distinguishable — a
|
|
7282
|
-
*
|
|
7080
|
+
* n" stay distinguishable — a styling written at a collapsed caret arms
|
|
7081
|
+
* {@link UseTextEditReturn.pendingStyle} instead of restyling a range.
|
|
7283
7082
|
*
|
|
7284
7083
|
* Follows the DOM selection, which browsers (and jsdom) report from a task
|
|
7285
7084
|
* rather than synchronously; anything this hook writes itself updates it
|
|
@@ -7293,33 +7092,82 @@ interface UseTextEditReturn {
|
|
|
7293
7092
|
/**
|
|
7294
7093
|
* The styling shared by every run in `selection` — a concrete value where
|
|
7295
7094
|
* the range agrees, `MIXED` where it doesn't. `null` exactly when
|
|
7296
|
-
* `selection` is `null`. A collapsed caret reports
|
|
7297
|
-
*
|
|
7298
|
-
* what
|
|
7095
|
+
* `selection` is `null`. A collapsed caret reports the styling *at* the
|
|
7096
|
+
* caret (the run to its left, or the run to its right at offset 0), which
|
|
7097
|
+
* is what the next typed character inherits.
|
|
7098
|
+
*
|
|
7099
|
+
* This does not include {@link UseTextEditReturn.pendingStyle}. A control
|
|
7100
|
+
* showing what the next character will look like wants both, merged in
|
|
7101
|
+
* that order; one showing what is already written wants only this.
|
|
7299
7102
|
*/
|
|
7300
7103
|
rangeStyle: RangeStyle | null;
|
|
7301
7104
|
/**
|
|
7302
|
-
*
|
|
7303
|
-
*
|
|
7304
|
-
* `
|
|
7305
|
-
*
|
|
7306
|
-
*
|
|
7105
|
+
* Styling armed at a collapsed caret, applied to the next character typed
|
|
7106
|
+
* and then dropped. `{}` when nothing is armed — which is always the case
|
|
7107
|
+
* while `selection` covers a real range, since a range is styled directly.
|
|
7108
|
+
*
|
|
7109
|
+
* Moving the caret abandons it, as in any other editor.
|
|
7110
|
+
*/
|
|
7111
|
+
pendingStyle: RunStylePatch;
|
|
7112
|
+
/**
|
|
7113
|
+
* Write `patch` over `selection`. A no-op with no active edit or an empty
|
|
7114
|
+
* patch. Over a real range this restyles the runs under it; at a collapsed
|
|
7115
|
+
* caret it merges into `pendingStyle` instead, so the styling lands on
|
|
7116
|
+
* what gets typed next rather than on text the user didn't select.
|
|
7117
|
+
*
|
|
7118
|
+
* Lowering a flag the *node* sets is neither of those — a run cannot say
|
|
7119
|
+
* "not bold" — so it rewrites instead: the node flag is cleared and raised
|
|
7120
|
+
* on every run outside the range. That path can decline (a node at
|
|
7121
|
+
* `fontWeight: 900` has no run boolean to move it to), in which case
|
|
7122
|
+
* nothing is written.
|
|
7123
|
+
*
|
|
7124
|
+
* The caret survives, so a second style can be applied without
|
|
7125
|
+
* re-selecting, and `rangeStyle` reflects the write before this returns.
|
|
7307
7126
|
*/
|
|
7308
7127
|
applyStyleToSelection: (patch: RunStylePatch) => void;
|
|
7128
|
+
/**
|
|
7129
|
+
* Toggle one styling over `selection` — set it if the range doesn't
|
|
7130
|
+
* uniformly carry it, clear it if it does. The shape a B / I / x² control
|
|
7131
|
+
* or a keyboard shortcut wants, and what this hook's own shortcuts call.
|
|
7132
|
+
*/
|
|
7133
|
+
toggleStyle: (toggle: StyleToggle) => void;
|
|
7309
7134
|
}
|
|
7310
7135
|
/** In-place text editing via a contenteditable overlay positioned over the text node's screen-space pose. */
|
|
7311
7136
|
declare function useTextEdit(opts: UseTextEditOptions): UseTextEditReturn;
|
|
7312
7137
|
|
|
7313
7138
|
/**
|
|
7314
|
-
*
|
|
7139
|
+
* Union math over rect-shaped poses.
|
|
7315
7140
|
*
|
|
7316
|
-
*
|
|
7317
|
-
*
|
|
7318
|
-
*
|
|
7141
|
+
* Two answers, deliberately distinct. `unionBounds` folds the *unrotated*
|
|
7142
|
+
* boxes and is what commit-time actions want, because they go on to write
|
|
7143
|
+
* poses back in that same frame. `unionAABB` expands each rotated member to
|
|
7144
|
+
* the extent of its ink first, and is what anything a user looks at or clicks
|
|
7145
|
+
* wants — selection chrome, gesture bounds, an export viewBox. Folding the
|
|
7146
|
+
* unrotated box there under-reports the extent of a rotated member exactly
|
|
7147
|
+
* when the consumer is watching it move.
|
|
7319
7148
|
*/
|
|
7320
7149
|
|
|
7321
|
-
/** Compute the AABB envelope of a set of rect-shaped poses
|
|
7150
|
+
/** Compute the AABB envelope of a set of rect-shaped poses, ignoring any
|
|
7151
|
+
* rotation they carry. See the module docstring before reaching for this
|
|
7152
|
+
* over {@link unionAABB}. */
|
|
7322
7153
|
declare function unionBounds<TPose extends RectPose>(poses: Iterable<TPose>): RectPose | null;
|
|
7154
|
+
/**
|
|
7155
|
+
* Axis-align a pose that carries a `rotation`: returns the AABB of the
|
|
7156
|
+
* rotated rectangle, with `rotation` dropped. Follows the kit's rotation
|
|
7157
|
+
* convention (`poseRotationOf`): rotate about the unrotated AABB center.
|
|
7158
|
+
*
|
|
7159
|
+
* Unrotated input is returned as-is.
|
|
7160
|
+
*/
|
|
7161
|
+
declare function axisAlignedBounds<TPose extends RectPose>(b: TPose): RectPose;
|
|
7162
|
+
/**
|
|
7163
|
+
* Fold every part into one world-space AABB, skipping `null` / `undefined`
|
|
7164
|
+
* entries. Rotated parts are expanded via {@link axisAlignedBounds} first;
|
|
7165
|
+
* the result never carries a `rotation` (a union of several oriented boxes
|
|
7166
|
+
* has no single orientation to report).
|
|
7167
|
+
*
|
|
7168
|
+
* Returns `null` when nothing was contributed.
|
|
7169
|
+
*/
|
|
7170
|
+
declare function unionAABB<TPose extends RectPose>(parts: Iterable<TPose | null | undefined>): RectPose | null;
|
|
7323
7171
|
|
|
7324
7172
|
/**
|
|
7325
7173
|
* `useSceneTextEdit` — scene-aware wrapper around `useTextEdit`.
|
|
@@ -7352,6 +7200,8 @@ interface DefaultTextData {
|
|
|
7352
7200
|
text?: string;
|
|
7353
7201
|
style?: TextStyle;
|
|
7354
7202
|
runs?: readonly StyledRun[];
|
|
7203
|
+
fill?: FillStyle | null;
|
|
7204
|
+
stroke?: Stroke | null;
|
|
7355
7205
|
}
|
|
7356
7206
|
/** All-optional projections + fontSize fallback. */
|
|
7357
7207
|
interface UseSceneTextEditOptions<TData> {
|
|
@@ -7359,6 +7209,8 @@ interface UseSceneTextEditOptions<TData> {
|
|
|
7359
7209
|
getText?: (data: TData) => string;
|
|
7360
7210
|
/** Read style from `data`. Default: `data.style`. */
|
|
7361
7211
|
getStyle?: (data: TData) => TextStyle | undefined;
|
|
7212
|
+
/** Read the node's paint from `data`. Default: `data.fill` / `data.stroke`. */
|
|
7213
|
+
getPaint?: (data: TData) => TextPaint | undefined;
|
|
7362
7214
|
/** Read rich-text runs from `data`. Default: `data.runs`. */
|
|
7363
7215
|
getRuns?: (data: TData) => readonly StyledRun[] | undefined;
|
|
7364
7216
|
/** Produce updated data with new text. Default: `{ ...data, text }`. */
|
|
@@ -7386,8 +7238,13 @@ interface UseSceneTextEditOptions<TData> {
|
|
|
7386
7238
|
* The overlay takes a single scale factor, so a non-uniform view scale is
|
|
7387
7239
|
* represented by its `scale.x`; text under `scale.x !== scale.y` will not
|
|
7388
7240
|
* match the canvas.
|
|
7241
|
+
*
|
|
7242
|
+
* A thunk is re-read on every projection, which is what an uncontrolled
|
|
7243
|
+
* `SceneCanvas` needs — its camera lives in a ref and moves without a
|
|
7244
|
+
* render, so pass the handle's `getView`. A plain `View` is the value from
|
|
7245
|
+
* the render that supplied it, which is correct for a controlled consumer.
|
|
7389
7246
|
*/
|
|
7390
|
-
view?: View;
|
|
7247
|
+
view?: View | (() => View);
|
|
7391
7248
|
/**
|
|
7392
7249
|
* Forwarded to `useTextEdit`: is `el` part of the editor's own chrome?
|
|
7393
7250
|
* Focus moving into it does not end the edit. Wire it to whatever renders
|
|
@@ -7410,59 +7267,6 @@ interface UseSceneTextEditReturn extends UseTextEditReturn {
|
|
|
7410
7267
|
* over the node being edited and writes the result back as an undoable op. */
|
|
7411
7268
|
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;
|
|
7412
7269
|
|
|
7413
|
-
/**
|
|
7414
|
-
* Turning a run-level flag **off** inside a node that sets it.
|
|
7415
|
-
*
|
|
7416
|
-
* Run flags are additive over the node's `TextStyle` — a run turns `bold` /
|
|
7417
|
-
* `italic` / `underline` / `strikethrough` on, never off (see the contract at
|
|
7418
|
-
* the top of `rangeStyle.ts`). So "select a word inside an underlined node and
|
|
7419
|
-
* hit U" is unrepresentable by the stored shape, and the character bar can
|
|
7420
|
-
* only refuse.
|
|
7421
|
-
*
|
|
7422
|
-
* This resolves it by rewriting rather than by widening the model: clear the
|
|
7423
|
-
* flag on the node, and set it on every run *outside* the range. The rendered
|
|
7424
|
-
* result is identical and the edit becomes expressible, with `StyledRun`
|
|
7425
|
-
* unchanged — so nothing a document can already contain changes meaning, which
|
|
7426
|
-
* matters while the flags are heading for a persisted format.
|
|
7427
|
-
*
|
|
7428
|
-
* The alternative was a tri-state run flag (`true` / `false` / inherit). It
|
|
7429
|
-
* cannot cover `bold` or `italic`: those are booleans on a run but
|
|
7430
|
-
* `fontWeight` and `fontStyle` on the node, so a run's `false` has no node-level
|
|
7431
|
-
* boolean to override. Tri-state fixes two of the four flags; this fixes all
|
|
7432
|
-
* four.
|
|
7433
|
-
*/
|
|
7434
|
-
|
|
7435
|
-
/** The additive run flags. */
|
|
7436
|
-
type FlagKey = 'bold' | 'italic' | 'underline' | 'strikethrough';
|
|
7437
|
-
/** The result of toggling a style flag over a text range: the rewritten runs
|
|
7438
|
-
* and node style, and whether the change could be made at all. */
|
|
7439
|
-
interface SetFlagResult {
|
|
7440
|
-
runs: StyledRun[];
|
|
7441
|
-
style: TextStyle;
|
|
7442
|
-
/**
|
|
7443
|
-
* False when the node flag could not be lowered without changing what is
|
|
7444
|
-
* drawn, and nothing was written. The only case is a `fontWeight` the run
|
|
7445
|
-
* boolean cannot express: `run.bold` resolves to exactly 700 everywhere, so
|
|
7446
|
-
* a node at 900 cannot have its weight pushed onto its runs. Callers should
|
|
7447
|
-
* disable the control rather than apply a silent downgrade.
|
|
7448
|
-
*/
|
|
7449
|
-
applied: boolean;
|
|
7450
|
-
}
|
|
7451
|
-
/** Does the node style carry this flag? */
|
|
7452
|
-
declare function nodeHasFlag(style: TextStyle, key: FlagKey): boolean;
|
|
7453
|
-
/**
|
|
7454
|
-
* Set `key` to `value` over `[start, end)`.
|
|
7455
|
-
*
|
|
7456
|
-
* Turning a flag **on**, or off in a node that doesn't set it, is the ordinary
|
|
7457
|
-
* additive write and leaves `style` alone. Turning it off in a node that *does*
|
|
7458
|
-
* set it takes the rewrite: the node flag is cleared and the flag is written
|
|
7459
|
-
* onto the complement of the range.
|
|
7460
|
-
*
|
|
7461
|
-
* `runs` is normalized on every path, so the complement collapses back to one
|
|
7462
|
-
* run when the range is empty and the whole array coalesces as usual.
|
|
7463
|
-
*/
|
|
7464
|
-
declare function setFlagOverRange(runs: readonly StyledRun[], style: TextStyle, start: number, end: number, key: FlagKey, value: boolean): SetFlagResult;
|
|
7465
|
-
|
|
7466
7270
|
/**
|
|
7467
7271
|
* Build a `TextDrawCommand`. `textCommand` takes a plain string and wraps it
|
|
7468
7272
|
* in one run; `textCommandFromRuns` takes the styled runs directly. Both
|
|
@@ -7470,12 +7274,16 @@ declare function setFlagOverRange(runs: readonly StyledRun[], style: TextStyle,
|
|
|
7470
7274
|
* text command derives `align` and per-run resolution the same way — a
|
|
7471
7275
|
* caller that assembles the command by hand is one field away from a
|
|
7472
7276
|
* silently different result.
|
|
7277
|
+
*
|
|
7278
|
+
* `paint` is the node's `data.fill` / `data.stroke`. A caller with no node —
|
|
7279
|
+
* a HUD widget, a debug overlay — states its color on the run instead.
|
|
7473
7280
|
*/
|
|
7474
7281
|
|
|
7282
|
+
declare function textCommandFromRuns(x: number, y: number, runs: readonly StyledRun[], style?: TextStyle, maxWidth?: number, height?: number, verticalAlign?: TextVerticalAlign, paint?: TextPaint): DrawCommand;
|
|
7475
7283
|
/** Build a draw command for a single unstyled string. Text is laid out with
|
|
7476
7284
|
* the registered font's metrics, wrapped at `maxWidth` and aligned within
|
|
7477
7285
|
* `height` when both are given. */
|
|
7478
|
-
declare function textCommand(x: number, y: number, text: string, style?: TextStyle, maxWidth?: number, height?: number, verticalAlign?: TextVerticalAlign): DrawCommand;
|
|
7286
|
+
declare function textCommand(x: number, y: number, text: string, style?: TextStyle, maxWidth?: number, height?: number, verticalAlign?: TextVerticalAlign, paint?: TextPaint): DrawCommand;
|
|
7479
7287
|
|
|
7480
7288
|
/**
|
|
7481
7289
|
* Pure DOM ↔ `StyledRun[]` serializers for the contenteditable overlay
|
|
@@ -7517,7 +7325,7 @@ declare function domPositionToCharOffset(parent: HTMLElement, node: Node, offset
|
|
|
7517
7325
|
/**
|
|
7518
7326
|
* Tile-pattern primitive — a small helper for building repeating texture
|
|
7519
7327
|
* tiles from a draw callback. The result plugs into a `FillStyle` of
|
|
7520
|
-
* `{ fill: 'pattern', pattern }` (see
|
|
7328
|
+
* `{ fill: 'pattern', pattern }` (see `@weasel-js/paint`).
|
|
7521
7329
|
*
|
|
7522
7330
|
* GL-backed: the tile is rendered to an `OffscreenCanvas` (with a 2D fallback
|
|
7523
7331
|
* to a regular `<canvas>` for environments without `OffscreenCanvas`),
|
|
@@ -7579,13 +7387,16 @@ declare function resolveFillPattern(fill: FillStyle): FillStyle | null;
|
|
|
7579
7387
|
* `withGradientKind` exists to translate.
|
|
7580
7388
|
*/
|
|
7581
7389
|
|
|
7390
|
+
/** Narrow a paint to the gradient members of `FillStyle`. The three
|
|
7391
|
+
* discriminants are the union's own definition of `GradientFill`, so every
|
|
7392
|
+
* consumer that reaches for gradient geometry starts here. */
|
|
7393
|
+
declare function isGradientFill(fill: FillStyle | null | undefined): fill is GradientFill;
|
|
7582
7394
|
/**
|
|
7583
|
-
* Color at position `t` (0..1) along a stop list,
|
|
7584
|
-
*
|
|
7585
|
-
*
|
|
7395
|
+
* Color at position `t` (0..1) along a stop list, as a hex string — the same
|
|
7396
|
+
* sampling the GL ramp texture bakes, so an editor track and the painted
|
|
7397
|
+
* gradient cannot disagree.
|
|
7586
7398
|
*
|
|
7587
|
-
* Returns transparent black for an empty list.
|
|
7588
|
-
* a stop list fading to `transparent` samples correctly.
|
|
7399
|
+
* Returns transparent black for an empty list.
|
|
7589
7400
|
*/
|
|
7590
7401
|
declare function sampleGradientStops(stops: readonly GradStop[], t: number): string;
|
|
7591
7402
|
/**
|
|
@@ -7622,9 +7433,10 @@ declare function gradientGeometry(fill: GradientFill): {
|
|
|
7622
7433
|
angle: number;
|
|
7623
7434
|
};
|
|
7624
7435
|
/**
|
|
7625
|
-
* A gradient spanning a box
|
|
7626
|
-
* (radial / conic) — the sensible starting
|
|
7627
|
-
* solid fill into a gradient and has only
|
|
7436
|
+
* A gradient spanning a box left edge to right edge through its vertical
|
|
7437
|
+
* center (linear) or filling it (radial / conic) — the sensible starting
|
|
7438
|
+
* geometry when a consumer turns a solid fill into a gradient and has only
|
|
7439
|
+
* the shape's bounds to go on.
|
|
7628
7440
|
*/
|
|
7629
7441
|
declare function gradientForBounds(kind: GradientKind, bounds: {
|
|
7630
7442
|
x: number;
|
|
@@ -7710,16 +7522,40 @@ interface TransformArgs<TPose> {
|
|
|
7710
7522
|
* coalesce window. Pass an explicit key (or a unique one) to opt out. */
|
|
7711
7523
|
declare function createTransformOp<TPose>(args: TransformArgs<TPose>): Op;
|
|
7712
7524
|
|
|
7525
|
+
interface Slot {
|
|
7526
|
+
/** Ordinal among the siblings. `-1` means "nowhere in particular". */
|
|
7527
|
+
index: number;
|
|
7528
|
+
/** Id of the sibling that followed at capture time; `null` when the node
|
|
7529
|
+
* was last. Absent when nothing observed it — `null` survives JSON and
|
|
7530
|
+
* `undefined` does not, so the two stay distinguishable across a
|
|
7531
|
+
* serialize/restore round trip. */
|
|
7532
|
+
before?: string | null;
|
|
7533
|
+
}
|
|
7534
|
+
|
|
7713
7535
|
/** @internal */
|
|
7714
7536
|
interface ReparentArgs {
|
|
7715
7537
|
id: string;
|
|
7716
7538
|
fromParentId: string | null;
|
|
7717
7539
|
toParentId: string | null;
|
|
7540
|
+
/** Sibling ordinal under the old parent. Sugar for `fromSlot: { index }`,
|
|
7541
|
+
* and only a seed: `apply` re-observes the node's full slot through the
|
|
7542
|
+
* adapter and that observation supersedes this. */
|
|
7543
|
+
fromIndex?: number;
|
|
7544
|
+
/** Sibling ordinal under the new parent. Sugar for `toSlot: { index }`.
|
|
7545
|
+
* Omit to append. */
|
|
7546
|
+
toIndex?: number;
|
|
7547
|
+
/** Slot under the old parent, anchor included. `invert()` forwards it as
|
|
7548
|
+
* the destination slot; without it undo re-parents with no position and
|
|
7549
|
+
* the node lands last, quietly changing paint order. */
|
|
7550
|
+
fromSlot?: Slot;
|
|
7551
|
+
/** Slot under the new parent, anchor included. Omit to append. */
|
|
7552
|
+
toSlot?: Slot;
|
|
7718
7553
|
label?: string;
|
|
7719
7554
|
coalesceKey?: string;
|
|
7720
7555
|
}
|
|
7721
7556
|
/**
|
|
7722
|
-
* Op: change `id`'s parent, inverting back to the prior
|
|
7557
|
+
* Op: change `id`'s parent and sibling slot, inverting back to the prior
|
|
7558
|
+
* parent and slot.
|
|
7723
7559
|
*
|
|
7724
7560
|
* `coalesceKey` defaults to `reparent:${id}` so successive reparents of the
|
|
7725
7561
|
* same id batch-merge cleanly.
|
|
@@ -7735,32 +7571,46 @@ interface InsertArgs<TNode extends {
|
|
|
7735
7571
|
}> {
|
|
7736
7572
|
node: TNode;
|
|
7737
7573
|
label?: string;
|
|
7738
|
-
/**
|
|
7739
|
-
*
|
|
7740
|
-
* batch restores paint order instead of reversing it. Optional — adapters
|
|
7741
|
-
* that don't honor it still work. */
|
|
7574
|
+
/** Sibling ordinal to insert at. Sugar for `slot: { index }` — the weaker
|
|
7575
|
+
* of the two forms, and all a fresh-insert callsite can know. */
|
|
7742
7576
|
index?: number;
|
|
7577
|
+
/** Full slot, anchor included. Produced only by `captureSlot` (via a
|
|
7578
|
+
* delete op's `invert`), and supersedes `index` when present. */
|
|
7579
|
+
slot?: Slot;
|
|
7743
7580
|
}
|
|
7744
7581
|
/** Op: insert `node` into the scene; inverts to a delete of the same id. */
|
|
7745
7582
|
declare function createInsertOp<TNode extends {
|
|
7746
7583
|
id: string;
|
|
7747
7584
|
}>(args: InsertArgs<TNode>): InsertOp;
|
|
7748
7585
|
|
|
7586
|
+
/** A captured node plus its slot in its own parent's child list. */
|
|
7587
|
+
interface Placed<TNode> {
|
|
7588
|
+
node: TNode;
|
|
7589
|
+
index: number;
|
|
7590
|
+
}
|
|
7749
7591
|
/** @internal */
|
|
7750
7592
|
interface DeleteArgs<TNode extends {
|
|
7751
7593
|
id: string;
|
|
7752
7594
|
}> {
|
|
7753
7595
|
node: TNode;
|
|
7754
7596
|
label?: string;
|
|
7755
|
-
/**
|
|
7756
|
-
*
|
|
7757
|
-
*
|
|
7758
|
-
* the
|
|
7759
|
-
*
|
|
7760
|
-
|
|
7761
|
-
index
|
|
7762
|
-
|
|
7763
|
-
/**
|
|
7597
|
+
/** Sibling ordinal the node occupies at the moment of delete. Sugar for
|
|
7598
|
+
* `slot: { index }`, and only a seed: `apply` re-observes the node's full
|
|
7599
|
+
* slot through the adapter and that observation supersedes this. Kept
|
|
7600
|
+
* because it is the whole story for a flat adapter with no `getChildren`,
|
|
7601
|
+
* where nothing can be observed. */
|
|
7602
|
+
index?: number;
|
|
7603
|
+
/** Full slot, anchor included. Written by `apply`; supersedes `index`. */
|
|
7604
|
+
slot?: Slot;
|
|
7605
|
+
/** Descendants of `node`, preorder (parents before children). `removeNode`
|
|
7606
|
+
* cascades the whole subtree, so an inverse that re-inserts `node` alone
|
|
7607
|
+
* brings the container back empty and drops every child on the floor.
|
|
7608
|
+
* Captured on apply; mirrored into the serialized args so a rebuilt op
|
|
7609
|
+
* can invert without having run. */
|
|
7610
|
+
descendants?: Placed<TNode>[];
|
|
7611
|
+
}
|
|
7612
|
+
/** Op: remove `node` and its subtree from the scene; inverts to a re-insert
|
|
7613
|
+
* of the whole subtree at its captured slots. */
|
|
7764
7614
|
declare function createDeleteOp<TNode extends {
|
|
7765
7615
|
id: string;
|
|
7766
7616
|
}>(args: DeleteArgs<TNode>): Op;
|
|
@@ -7903,6 +7753,10 @@ declare function registerOpFactory<A>(name: string, build: (args: A) => Op): voi
|
|
|
7903
7753
|
* `name` isn't registered — callers handle this (typically by substituting
|
|
7904
7754
|
* a no-op placeholder so stack ordering survives across kit version skew). */
|
|
7905
7755
|
declare function rebuildOp(name: string, args: unknown): Op | null;
|
|
7756
|
+
/** Every op name currently registered, in registration order. The kit's
|
|
7757
|
+
* built-ins self-register at module init, so importing the barrel is enough
|
|
7758
|
+
* to see all of them; consumer factories appear once their module has run. */
|
|
7759
|
+
declare function registeredOpNames(): readonly string[];
|
|
7906
7760
|
|
|
7907
7761
|
/** @internal */
|
|
7908
7762
|
interface HitAdapter<TNode extends {
|
|
@@ -8121,6 +7975,20 @@ interface PointInPathOptions {
|
|
|
8121
7975
|
/** Filled-region hit-test for a `Path`. Rect short-circuits to AABB; polygons run ray-cast / winding per `fillRule`. */
|
|
8122
7976
|
declare function pointInPath(path: Path, x: number, y: number, opts?: PointInPathOptions): boolean;
|
|
8123
7977
|
|
|
7978
|
+
/**
|
|
7979
|
+
* Polygon-vs-axis-aligned-rect tests. Pure functions; no React/kit deps.
|
|
7980
|
+
*
|
|
7981
|
+
* `polygon` is a closed polyline given as an ordered vertex array; the
|
|
7982
|
+
* closing edge from `polygon[N-1]` to `polygon[0]` is implicit. Even-odd
|
|
7983
|
+
* fill rule (matches `pointInPath`).
|
|
7984
|
+
*/
|
|
7985
|
+
|
|
7986
|
+
/** A 2D point or vector. */
|
|
7987
|
+
interface Vec2 {
|
|
7988
|
+
x: number;
|
|
7989
|
+
y: number;
|
|
7990
|
+
}
|
|
7991
|
+
|
|
8124
7992
|
/**
|
|
8125
7993
|
* Path-vs-geometry hit-test helpers. Five pure functions covering all
|
|
8126
7994
|
* combinations of path-vs-point, path-vs-rect, and path-vs-polygon.
|
|
@@ -8272,22 +8140,6 @@ declare function worldEditToStorage<P extends PathInWorldPose>(pose: P, worldPat
|
|
|
8272
8140
|
path: PolygonPath;
|
|
8273
8141
|
};
|
|
8274
8142
|
|
|
8275
|
-
/**
|
|
8276
|
-
* The kit's single encoding of the pose-rotation convention: "rotate about the
|
|
8277
|
-
* pose's unrotated AABB center by `pose.rotation` (radians)."
|
|
8278
|
-
*
|
|
8279
|
-
* Every consumer that needs to apply rotation — the render-tree wrap
|
|
8280
|
-
* (`canvas/poseRotation.ts`), the world coordinate bake (`pathInWorld`), the
|
|
8281
|
-
* silhouette/clip bake (`findShapeSilhouette`), the hit-test inverse
|
|
8282
|
-
* (`poseContainsRotated`), and selection chrome — derives its pivot + angle
|
|
8283
|
-
* from `poseRotationOf` rather than re-inlining the `if (rotation && x != null
|
|
8284
|
-
* …)` gate. If the convention ever changes (different pivot, a transform
|
|
8285
|
-
* field, etc.), it changes here.
|
|
8286
|
-
*
|
|
8287
|
-
* Lives in `features/paths` (the low layer) so both `features` and `canvas`
|
|
8288
|
-
* can share it without `features` importing `canvas`.
|
|
8289
|
-
*/
|
|
8290
|
-
|
|
8291
8143
|
/** Pivot (`cx`, `cy`) and angle resolved from a pose's rotation convention. */
|
|
8292
8144
|
interface PoseRotation {
|
|
8293
8145
|
cx: number;
|
|
@@ -8568,8 +8420,9 @@ declare function createPenPreviewLayer(opts: CreatePenPreviewLayerOptions): Rend
|
|
|
8568
8420
|
* but a human user needs to see what's hittable.
|
|
8569
8421
|
*
|
|
8570
8422
|
* The layer reads the live edit target each frame via the supplied
|
|
8571
|
-
* `getEditingId()` + `getPose(
|
|
8572
|
-
*
|
|
8423
|
+
* `getEditingId()` + `getPose(...)` thunks, resolving the path against the
|
|
8424
|
+
* drawing view's own previews. Returns `[]` when no editing target is set or
|
|
8425
|
+
* the target isn't a polygon — the layer never throws.
|
|
8573
8426
|
*
|
|
8574
8427
|
* Anchors render as small white-filled stroked squares — filled solid
|
|
8575
8428
|
* when selected; control points as small filled circles connected to
|
|
@@ -8589,9 +8442,15 @@ interface CreatePathEditingOverlayLayerOptions {
|
|
|
8589
8442
|
* when no node is being edited. Read each frame so live selection /
|
|
8590
8443
|
* edit-target changes show up without re-creating the layer. */
|
|
8591
8444
|
getEditingId(): string | null;
|
|
8592
|
-
/**
|
|
8593
|
-
*
|
|
8594
|
-
|
|
8445
|
+
/**
|
|
8446
|
+
* Returns the pose for an id, or null if the node has been deleted.
|
|
8447
|
+
* Non-polygon poses are tolerated (the layer no-ops on them).
|
|
8448
|
+
*
|
|
8449
|
+
* `previews` are the drawing view's in-flight preview surfaces, so an
|
|
8450
|
+
* anchor dragged in one panel does not move in the others. Resolve against
|
|
8451
|
+
* them before falling back to the committed pose.
|
|
8452
|
+
*/
|
|
8453
|
+
getPose(id: string, previews: readonly GesturePreviewSource[]): Path | null;
|
|
8595
8454
|
/** Flat indices of the selected anchors. Selected anchors render
|
|
8596
8455
|
* filled; unselected ones hollow — the standard vector-editor cue for
|
|
8597
8456
|
* "these are what the arrow keys and Delete will act on". Omit when
|
|
@@ -8605,12 +8464,6 @@ interface CreatePathEditingOverlayLayerOptions {
|
|
|
8605
8464
|
width: number;
|
|
8606
8465
|
height: number;
|
|
8607
8466
|
} | null;
|
|
8608
|
-
/** Chrome-caps predicate. The layer asks `'path-edit.anchors'` before
|
|
8609
|
-
* drawing anything, so paint and the anchor hit-test in
|
|
8610
|
-
* `affordanceAt` consult the same rule — otherwise a consumer that
|
|
8611
|
-
* hides the chrome still gets grabbable invisible anchors, or vice
|
|
8612
|
-
* versa. Omit to always draw when an edit target is set. */
|
|
8613
|
-
isVisible?(chromeId: string): boolean;
|
|
8614
8467
|
/** Optional styling overrides. */
|
|
8615
8468
|
style?: PathEditingOverlayStyle;
|
|
8616
8469
|
}
|
|
@@ -8791,6 +8644,301 @@ declare function withAlpha01(color: string, alpha01: number): string;
|
|
|
8791
8644
|
* strips the alpha channel and returns a bare 6-char hex. */
|
|
8792
8645
|
declare function mergeAlphaFromPrev(picked: string, prev: string): string;
|
|
8793
8646
|
|
|
8647
|
+
/**
|
|
8648
|
+
* The paint-kind registry — what makes `FillStyle` open.
|
|
8649
|
+
*
|
|
8650
|
+
* A consumer registers a sixth kind and it renders, converts between the
|
|
8651
|
+
* bounds and pose frames, and serializes, with no kit edits. The five built-in
|
|
8652
|
+
* kinds are registered here at module load so an editor's kind bar can
|
|
8653
|
+
* enumerate every kind through one list.
|
|
8654
|
+
*
|
|
8655
|
+
* Each kit layer consults this registry for a kind it does not recognize and
|
|
8656
|
+
* otherwise runs its own built-in branch. That split is not laziness: a built-in
|
|
8657
|
+
* kind's render slot lives in the GL renderer, its serialize slot lives in
|
|
8658
|
+
* `@weasel-js/svg`, and neither can be imported from here without inverting a
|
|
8659
|
+
* package dependency.
|
|
8660
|
+
*/
|
|
8661
|
+
|
|
8662
|
+
/** A compiled GL program. A paint kind gets one from
|
|
8663
|
+
* {@link PaintBindContext.program} and hands it back from `bind`. */
|
|
8664
|
+
type PaintProgram = ShaderProgram;
|
|
8665
|
+
/**
|
|
8666
|
+
* `FillStyle`'s discriminant, open on the string the way `ChromeId` is: the
|
|
8667
|
+
* five kinds the kit ships, plus whatever a consumer registers.
|
|
8668
|
+
*/
|
|
8669
|
+
type PaintKind = 'solid' | 'linear-gradient' | 'radial-gradient' | 'conic-gradient' | 'pattern' | (string & {});
|
|
8670
|
+
/** What a registered kind's editor renders. `PaintInput` in `@weasel-js/ui`
|
|
8671
|
+
* is the control that mounts it. */
|
|
8672
|
+
interface PaintKindEditorProps {
|
|
8673
|
+
value: FillStyle;
|
|
8674
|
+
onInput?(next: FillStyle): void;
|
|
8675
|
+
onChange(next: FillStyle): void;
|
|
8676
|
+
}
|
|
8677
|
+
/**
|
|
8678
|
+
* The renderer surface a paint kind binds against, narrowed to what a paint
|
|
8679
|
+
* needs. The full `DrawContext` is not consumer surface.
|
|
8680
|
+
*/
|
|
8681
|
+
interface PaintBindContext {
|
|
8682
|
+
readonly gl: WebGL2RenderingContext;
|
|
8683
|
+
/** The group alpha this draw inherits — multiply it into the paint's own. */
|
|
8684
|
+
readonly alpha: number;
|
|
8685
|
+
/**
|
|
8686
|
+
* The compiled program for a `registerProgram` id, compiled against this
|
|
8687
|
+
* renderer on first use. `null` when no source is registered under `id` or
|
|
8688
|
+
* compilation failed.
|
|
8689
|
+
*/
|
|
8690
|
+
program(id: string): PaintProgram | null;
|
|
8691
|
+
/** Send `u_proj` and `u_model`, which every kit vertex shader takes. */
|
|
8692
|
+
setProjAndModel(program: PaintProgram): void;
|
|
8693
|
+
/**
|
|
8694
|
+
* `u_worldInv` for a paint declaring `units` — the inverse of the transform
|
|
8695
|
+
* from the paint's space to the frame the geometry arrives in. Paired with
|
|
8696
|
+
* the vertex shader's `v_world` varying this is *the* paint-space
|
|
8697
|
+
* convention; it is not gradient-specific.
|
|
8698
|
+
*/
|
|
8699
|
+
spaceInverse(units: GradientUnits | undefined): Mat3$1;
|
|
8700
|
+
/** Upload a stop ramp and bind it to a texture unit. */
|
|
8701
|
+
bindRamp(stops: GradStop[], unit: number): void;
|
|
8702
|
+
}
|
|
8703
|
+
/**
|
|
8704
|
+
* One paint kind.
|
|
8705
|
+
*
|
|
8706
|
+
* `seed`, `label` and `colorOf` are the editor's slots and every kind has
|
|
8707
|
+
* them. The rest are optional because a kind may not need them — but
|
|
8708
|
+
* `inPoseFrame` and `toBoundsFrame` come as a pair or not at all: a kind that
|
|
8709
|
+
* converts one direction and not the other paints correctly once and then
|
|
8710
|
+
* drifts on the next resize.
|
|
8711
|
+
*/
|
|
8712
|
+
interface PaintKindEntry {
|
|
8713
|
+
id: string;
|
|
8714
|
+
label: string;
|
|
8715
|
+
/** Glyph naming this kind in an editor's kind bar, as an icon name the UI
|
|
8716
|
+
* layer resolves — the same indirection `ToolPrefBase.icon` uses. A kind
|
|
8717
|
+
* without one is named by its `label`. */
|
|
8718
|
+
icon?: string;
|
|
8719
|
+
/** A paint of this kind seeded from a color — what an editor writes when a
|
|
8720
|
+
* consumer switches a solid to this kind. */
|
|
8721
|
+
seed(fromColor: string): FillStyle;
|
|
8722
|
+
/** The single color this paint shows, or `undefined` when it has none. */
|
|
8723
|
+
colorOf(paint: FillStyle): string | undefined;
|
|
8724
|
+
/** Editor slot. */
|
|
8725
|
+
Editor?: ComponentType<PaintKindEditorProps>;
|
|
8726
|
+
/**
|
|
8727
|
+
* Render slot: bind program, uniforms and textures for `fill` and return the
|
|
8728
|
+
* bound program; `null` declines the paint.
|
|
8729
|
+
*
|
|
8730
|
+
* Binding is split from drawing on purpose — a caller owning its own stencil
|
|
8731
|
+
* state (an inner/outer-aligned stroke, an even-odd fill) must issue its own
|
|
8732
|
+
* draw call, and the kit's draw wrapper would clobber that state. Shader
|
|
8733
|
+
* output must be premultiplied: `outColor = vec4(rgb * a, a)`.
|
|
8734
|
+
*/
|
|
8735
|
+
bind?(ctx: PaintBindContext, fill: FillStyle): PaintProgram | null;
|
|
8736
|
+
/** Bounds frame → the frame the node is painted in. */
|
|
8737
|
+
inPoseFrame?(fill: FillStyle, box: FillPoseBox): FillStyle;
|
|
8738
|
+
/** The inverse. Required whenever `inPoseFrame` is supplied. */
|
|
8739
|
+
toBoundsFrame?(fill: FillStyle, box: FillPoseBox): FillStyle;
|
|
8740
|
+
/** The `<defs>` entry backing a `url(#id)` reference. */
|
|
8741
|
+
toSvg?(id: string, fill: FillStyle): string;
|
|
8742
|
+
}
|
|
8743
|
+
/**
|
|
8744
|
+
* A consumer's own paint, typed as a `FillStyle`.
|
|
8745
|
+
*
|
|
8746
|
+
* `FillStyle` stays a closed union: opening its discriminant would widen every
|
|
8747
|
+
* built-in member and break the narrowing the kit's own branches depend on.
|
|
8748
|
+
* A registered kind declares its own interface instead and passes it through
|
|
8749
|
+
* here — the kit reads only `fill` and hands the whole object back to that
|
|
8750
|
+
* kind's slots.
|
|
8751
|
+
*/
|
|
8752
|
+
declare function asPaint<T extends {
|
|
8753
|
+
fill: string;
|
|
8754
|
+
}>(paint: T): FillStyle;
|
|
8755
|
+
/** Register a paint kind. Returns a disposer that removes it. */
|
|
8756
|
+
declare function registerPaintKind(entry: PaintKindEntry): () => void;
|
|
8757
|
+
/** The entry for `kind`, or `undefined`. */
|
|
8758
|
+
declare function getPaintKind(kind: string | undefined): PaintKindEntry | undefined;
|
|
8759
|
+
/** Every registered kind, built-ins first, in registration order. */
|
|
8760
|
+
declare function listPaintKinds(): readonly PaintKindEntry[];
|
|
8761
|
+
/** The registry entry for a paint, or `undefined` when its kind is unknown. */
|
|
8762
|
+
declare function paintKindOf(fill: FillStyle): PaintKindEntry | undefined;
|
|
8763
|
+
/** @internal Test helper — do not call from product code. */
|
|
8764
|
+
declare function _resetPaintKindsForTests(): void;
|
|
8765
|
+
|
|
8766
|
+
/**
|
|
8767
|
+
* The stroke-marker registry — arrowheads and other line terminators.
|
|
8768
|
+
*
|
|
8769
|
+
* Keyed by string, because a key is what sits in `stroke.markerEnd`. That is
|
|
8770
|
+
* the difference from `registerNodeShape`, which resolves by first-matching
|
|
8771
|
+
* predicate and whose `id` is only a label.
|
|
8772
|
+
*
|
|
8773
|
+
* A built-in's SVG slot lives in `@weasel-js/svg` and cannot be imported here
|
|
8774
|
+
* without inverting a package dependency, so an entry carries `toSvg` for that
|
|
8775
|
+
* package to consume — the same split `PaintKindEntry` uses.
|
|
8776
|
+
*/
|
|
8777
|
+
|
|
8778
|
+
/** What an entry's `path` is given. Entries that ignore it may return a
|
|
8779
|
+
* constant path. */
|
|
8780
|
+
interface MarkerCtx {
|
|
8781
|
+
/** One geometry unit, in the same world units the ribbon is tessellated in.
|
|
8782
|
+
* Defaults to the resolved stroke width. */
|
|
8783
|
+
readonly size: number;
|
|
8784
|
+
/** The stroke this marker belongs to, already width-resolved. */
|
|
8785
|
+
readonly stroke: Stroke;
|
|
8786
|
+
}
|
|
8787
|
+
/** `'line'` means the stroke's own paint — SVG 2's `context-stroke`, as the
|
|
8788
|
+
* default rather than an opt-in. */
|
|
8789
|
+
type MarkerPaint = FillStyle | 'line' | 'none';
|
|
8790
|
+
interface MarkerEntry {
|
|
8791
|
+
/** `'kit:'`-free for built-ins so the key matches the SVG attribute value;
|
|
8792
|
+
* consumers should prefix (`'app-my-head'`). A key becomes the `id` of the
|
|
8793
|
+
* emitted `<marker>` def, so it must be a valid XML name — no colons. */
|
|
8794
|
+
id: MarkerKey;
|
|
8795
|
+
/** Geometry with its anchor at the origin, pointing +X, in units of
|
|
8796
|
+
* `ctx.size`. An arbitrary anchor is expressed by where the geometry is
|
|
8797
|
+
* drawn, which is why there is no `refX`/`refY`. */
|
|
8798
|
+
path(ctx: MarkerCtx): Path;
|
|
8799
|
+
/** Default `'line'`. */
|
|
8800
|
+
fill?: MarkerPaint;
|
|
8801
|
+
/** Outline width is in the same units as `path`. `false` (the default)
|
|
8802
|
+
* means no outline. */
|
|
8803
|
+
outline?: {
|
|
8804
|
+
width: number;
|
|
8805
|
+
paint?: MarkerPaint;
|
|
8806
|
+
} | false;
|
|
8807
|
+
/** How far back along the line the stroke stops, in units of `ctx.size`.
|
|
8808
|
+
* Default 0. A property of the shape, not a setting on the stroke: an open
|
|
8809
|
+
* V needs 0 or its arms stop meeting the line. */
|
|
8810
|
+
inset?: number;
|
|
8811
|
+
/** `'auto'` (default) follows the line; a number is a fixed angle in
|
|
8812
|
+
* radians, ignoring the line — SVG's `orient="<angle>"`. */
|
|
8813
|
+
orient?: 'auto' | number;
|
|
8814
|
+
/** Emits the `<marker>` def. Consumed by `@weasel-js/svg`. */
|
|
8815
|
+
toSvg?(id: string, entry: MarkerEntry): string;
|
|
8816
|
+
}
|
|
8817
|
+
/** Register a marker. Returns a disposer. Re-registering a built-in id is an
|
|
8818
|
+
* override; disposing it restores the built-in rather than deleting the key. */
|
|
8819
|
+
declare function registerMarker(entry: MarkerEntry): () => void;
|
|
8820
|
+
/** The entry for `key`, or `undefined`. */
|
|
8821
|
+
declare function getMarker(key: string | undefined): MarkerEntry | undefined;
|
|
8822
|
+
/** Every registered marker, built-ins first, in registration order. */
|
|
8823
|
+
declare function listMarkers(): readonly MarkerEntry[];
|
|
8824
|
+
/** Test helper. Do not call from product code. */
|
|
8825
|
+
declare function _resetMarkersForTests(): void;
|
|
8826
|
+
|
|
8827
|
+
/**
|
|
8828
|
+
* Resolving a `MarkerRef` to the distance the ribbon must stop short.
|
|
8829
|
+
*
|
|
8830
|
+
* The tessellation layer takes these as plain numbers and knows nothing about
|
|
8831
|
+
* the registry — keeping that layer free of upward dependencies is deliberate.
|
|
8832
|
+
* The ribbon cache, the SVG serializer and `inkReach` all resolve through here,
|
|
8833
|
+
* so the ribbon, the export and the hit region cannot disagree about where the
|
|
8834
|
+
* line ends.
|
|
8835
|
+
*/
|
|
8836
|
+
|
|
8837
|
+
/** The size of one marker unit, in the same world units as `strokeWidth`. */
|
|
8838
|
+
declare function resolveMarkerSize(ref: MarkerRef, strokeWidth: number): number;
|
|
8839
|
+
declare function markerKeyOf(ref: MarkerRef): string;
|
|
8840
|
+
/**
|
|
8841
|
+
* How far back the ribbon stops for `ref`, in world units. Zero for an absent
|
|
8842
|
+
* marker, an unregistered key, or an open head — never throws, because an
|
|
8843
|
+
* unknown key is a data problem and dropping the head is the graceful answer.
|
|
8844
|
+
*/
|
|
8845
|
+
declare function markerInset(ref: MarkerRef | undefined, strokeWidth: number): number;
|
|
8846
|
+
/** The start and end insets a stroke asks for. `markerMid` never insets —
|
|
8847
|
+
* trimming at an interior vertex would cut the line in two. */
|
|
8848
|
+
declare function strokeInsets(stroke: Stroke, strokeWidth: number): {
|
|
8849
|
+
start: number;
|
|
8850
|
+
end: number;
|
|
8851
|
+
};
|
|
8852
|
+
|
|
8853
|
+
interface Polyline {
|
|
8854
|
+
/** Interleaved x,y vertices (length = 2 × point count). */
|
|
8855
|
+
points: number[];
|
|
8856
|
+
/** Whether the contour was closed (ends with Z, or is a RectPath). */
|
|
8857
|
+
closed: boolean;
|
|
8858
|
+
/** For each point, the previous anchor index. Anchor-aligned points set A === B. */
|
|
8859
|
+
anchorA?: Uint32Array;
|
|
8860
|
+
/** For each point, the next anchor index. */
|
|
8861
|
+
anchorB?: Uint32Array;
|
|
8862
|
+
/** For each point, the arc-length fraction along (A, B). 0 at anchor A; for anchor-aligned, set to 0. */
|
|
8863
|
+
anchorT?: Float32Array;
|
|
8864
|
+
/** Per-point stroke width, populated by the tessellator when the Stroke
|
|
8865
|
+
* carries `vertexWidths`. Undefined means uniform `Stroke.width`. */
|
|
8866
|
+
widths?: Float32Array;
|
|
8867
|
+
}
|
|
8868
|
+
|
|
8869
|
+
/**
|
|
8870
|
+
* Where a stroke's markers sit and which way they point.
|
|
8871
|
+
*
|
|
8872
|
+
* Computed from the *untrimmed* polyline: trimming moves the endpoint, and a
|
|
8873
|
+
* marker anchors to where the line was authored to end, not to where the
|
|
8874
|
+
* ribbon was cut.
|
|
8875
|
+
*/
|
|
8876
|
+
|
|
8877
|
+
interface MarkerSite {
|
|
8878
|
+
x: number;
|
|
8879
|
+
y: number;
|
|
8880
|
+
/** Radians. The direction the marker's +X axis should point — outward at a
|
|
8881
|
+
* start or end, along the bisector at an interior vertex. */
|
|
8882
|
+
angle: number;
|
|
8883
|
+
role: 'start' | 'mid' | 'end';
|
|
8884
|
+
}
|
|
8885
|
+
interface MarkerSiteRequest {
|
|
8886
|
+
start: boolean;
|
|
8887
|
+
mid: boolean;
|
|
8888
|
+
end: boolean;
|
|
8889
|
+
}
|
|
8890
|
+
declare function markerSites(pl: Polyline, want: MarkerSiteRequest): MarkerSite[];
|
|
8891
|
+
|
|
8892
|
+
/**
|
|
8893
|
+
* Turning a stroke's markers into draw commands.
|
|
8894
|
+
*
|
|
8895
|
+
* Separate `PathDrawCommand`s rather than triangles appended to the stroke
|
|
8896
|
+
* ribbon: an entry may carry a fill and an outline at once, or a paint that
|
|
8897
|
+
* differs from the line's, neither of which one mesh can express — and folding
|
|
8898
|
+
* them in would drag the whole marker vocabulary into the ribbon cache key.
|
|
8899
|
+
*/
|
|
8900
|
+
|
|
8901
|
+
/**
|
|
8902
|
+
* Every marker command for `path` under `stroke`. `strokeWidth` is the already
|
|
8903
|
+
* width-resolved stroke width; `flattenTolerance` matches what the ribbon used,
|
|
8904
|
+
* so markers land on the same flattened vertices the stroke did.
|
|
8905
|
+
*/
|
|
8906
|
+
declare function markerDrawCommands(path: Path, stroke: Stroke, strokeWidth: number, flattenTolerance: number | undefined): PathDrawCommand[];
|
|
8907
|
+
|
|
8908
|
+
/**
|
|
8909
|
+
* The kit's built-in stroke-marker vocabulary.
|
|
8910
|
+
*
|
|
8911
|
+
* Every entry is authored with its anchor at the origin and pointing +X, so
|
|
8912
|
+
* the line arrives from -X and no geometry sits at positive X. Coordinates are
|
|
8913
|
+
* in units of `MarkerCtx.size`, which defaults to the resolved stroke width —
|
|
8914
|
+
* one definition is therefore correct at any line weight.
|
|
8915
|
+
*
|
|
8916
|
+
* Not to be confused with `features/paths/markers.ts`, which builds
|
|
8917
|
+
* decorative chrome shapes and is unrelated.
|
|
8918
|
+
*/
|
|
8919
|
+
|
|
8920
|
+
declare const BUILTIN_MARKERS: readonly MarkerEntry[];
|
|
8921
|
+
|
|
8922
|
+
/**
|
|
8923
|
+
* Shortening a flattened subpath so a filled marker is not speared by its own
|
|
8924
|
+
* line. SVG has no equivalent — it paints the marker over a full-length
|
|
8925
|
+
* stroke — so this is the one place our rendering deliberately differs.
|
|
8926
|
+
*
|
|
8927
|
+
* Runs before dash splitting, so a dash pattern fits the visible line rather
|
|
8928
|
+
* than running off under the head. The anchor-param interpolation matches
|
|
8929
|
+
* `splitForDash`'s rule for a boundary landing mid-segment.
|
|
8930
|
+
*/
|
|
8931
|
+
|
|
8932
|
+
/**
|
|
8933
|
+
* Shorten `pl` by `startInset` from its first point and `endInset` from its
|
|
8934
|
+
* last, both in the same world units as the points.
|
|
8935
|
+
*
|
|
8936
|
+
* Returns `pl` itself when there is nothing to do (both insets zero, or the
|
|
8937
|
+
* subpath is closed and so has no free ends), and `null` when the insets
|
|
8938
|
+
* consume the whole run — a caller should then draw no ribbon at all.
|
|
8939
|
+
*/
|
|
8940
|
+
declare function trimPolyline(pl: Polyline, startInset: number, endInset: number): Polyline | null;
|
|
8941
|
+
|
|
8794
8942
|
/** Kit-shipped default paint constants.
|
|
8795
8943
|
*
|
|
8796
8944
|
* Single source of truth for the colors the built-in tools and the default
|
|
@@ -8801,6 +8949,7 @@ declare function mergeAlphaFromPrev(picked: string, prev: string): string;
|
|
|
8801
8949
|
* All values are `#rrggbbaa` so they round-trip through the kit's hex8 alpha
|
|
8802
8950
|
* helpers (`util/color`) without ambiguity.
|
|
8803
8951
|
*/
|
|
8952
|
+
|
|
8804
8953
|
/** Default fill paint for shapes and the fill action — opaque white. */
|
|
8805
8954
|
declare const DEFAULT_FILL_COLOR = "#ffffffff";
|
|
8806
8955
|
/** Default stroke paint for shapes and the stroke action — opaque black. */
|
|
@@ -8812,6 +8961,41 @@ declare const DEFAULT_PALETTE: readonly string[];
|
|
|
8812
8961
|
* selected-anchor highlight. Derived from the first palette entry so the
|
|
8813
8962
|
* preview chrome matches the default insert color. */
|
|
8814
8963
|
declare const GHOST_STROKE: string;
|
|
8964
|
+
/**
|
|
8965
|
+
* A solid paint from a color string — the authoring shorthand for the one
|
|
8966
|
+
* shape a node's `data.fill` (and a `Stroke.paint`) may take.
|
|
8967
|
+
*
|
|
8968
|
+
* An alpha channel in `color` moves to `opacity`, because that is where every
|
|
8969
|
+
* paint kind carries its alpha; leaving it in the hex too would multiply the
|
|
8970
|
+
* two in the renderer.
|
|
8971
|
+
*/
|
|
8972
|
+
declare function solid(color: string): FillStyle;
|
|
8973
|
+
/** A solid stroke of `color` at `width` world units. Authoring shorthand for
|
|
8974
|
+
* `{ paint: solid(color), width }`. */
|
|
8975
|
+
declare function strokeOf(color: string, width?: number): Stroke;
|
|
8976
|
+
/** A stroke painted with `paint` at `width` world units — `strokeOf`'s sibling
|
|
8977
|
+
* for a gradient or pattern, which has no color to pass. */
|
|
8978
|
+
declare function strokeWith(paint: FillStyle, width?: number): Stroke;
|
|
8979
|
+
/** The kit's default node paint — what a shape with no declared fill paints. */
|
|
8980
|
+
declare const DEFAULT_SHAPE_FILL: FillStyle;
|
|
8981
|
+
/**
|
|
8982
|
+
* The 0..1 alpha a paint paints at.
|
|
8983
|
+
*
|
|
8984
|
+
* Every paint kind carries its alpha in `opacity` — that is the one slot a
|
|
8985
|
+
* gradient or a pattern has, so it is the slot all of them use.
|
|
8986
|
+
*/
|
|
8987
|
+
declare function paintAlpha(paint: FillStyle | undefined): number;
|
|
8988
|
+
/** `paint` painting at `alpha01` (clamped to 0..1). */
|
|
8989
|
+
declare function paintWithAlpha(paint: FillStyle, alpha01: number): FillStyle;
|
|
8990
|
+
/**
|
|
8991
|
+
* `paint` recolored to `color`, keeping everything else about it.
|
|
8992
|
+
*
|
|
8993
|
+
* A solid paint takes the new color; a gradient or a pattern has no single
|
|
8994
|
+
* color to replace, so it is superseded by a solid one — picking a color off
|
|
8995
|
+
* a swatch means "paint this color". An alpha channel in `color` wins;
|
|
8996
|
+
* without one, the paint's existing opacity carries over.
|
|
8997
|
+
*/
|
|
8998
|
+
declare function paintWithColor(paint: FillStyle | undefined, color: string): FillStyle;
|
|
8815
8999
|
|
|
8816
9000
|
/**
|
|
8817
9001
|
* Build an op-batched undo/redo `History`, defaulting restore-time op
|
|
@@ -8845,7 +9029,9 @@ interface ArrayAdapterConfig<TNode extends {
|
|
|
8845
9029
|
getParent?: (id: string) => string | null;
|
|
8846
9030
|
/** Optional reparent mutator. Default is a noop. */
|
|
8847
9031
|
setParent?: (id: string, parentId: string | null) => void;
|
|
8848
|
-
/** Optional children lookup.
|
|
9032
|
+
/** Optional children lookup for a node id. The adapter answers the root
|
|
9033
|
+
* itself, from `ref` and `getParent` in array order, so this is never
|
|
9034
|
+
* called with `null`. Default omits the method entirely. */
|
|
8849
9035
|
getChildren?: (id: string) => string[] | undefined;
|
|
8850
9036
|
/** Live ref to the current selection. Default: empty array. */
|
|
8851
9037
|
selectionRef?: MutableRefObject<string[]>;
|
|
@@ -9041,7 +9227,8 @@ interface GuidesLayerOpts {
|
|
|
9041
9227
|
* screen space, projected from world offsets via the active view. */
|
|
9042
9228
|
declare function createGuidesLayer(opts: GuidesLayerOpts): RenderLayer<unknown>;
|
|
9043
9229
|
|
|
9044
|
-
/** Axis-aligned bounding box.
|
|
9230
|
+
/** Axis-aligned bounding box. Alignment matches AABBs throughout; a rotated
|
|
9231
|
+
* pose enters as the AABB of its ink (see `AlignBoundsProjection.boundsOf`). */
|
|
9045
9232
|
interface AlignBounds {
|
|
9046
9233
|
x: number;
|
|
9047
9234
|
y: number;
|
|
@@ -9064,18 +9251,27 @@ interface AlignMatchResult {
|
|
|
9064
9251
|
* and translates a pose. The rect default handles `{x,y,width,height}` poses;
|
|
9065
9252
|
* non-rect poses (Path, polygon) supply their own. */
|
|
9066
9253
|
interface AlignBoundsProjection<TPose> {
|
|
9254
|
+
/** The pose's *visual* AABB — a rotated pose reports the extent of its ink,
|
|
9255
|
+
* not the box it was posed in. Guides and matching both read this, so an
|
|
9256
|
+
* implementation that returns the stored box makes a rotated shape snap to
|
|
9257
|
+
* lines nothing is drawn at. */
|
|
9067
9258
|
boundsOf(pose: TPose): AlignBounds;
|
|
9259
|
+
/** Move the pose, preserving every other field it carries — nothing
|
|
9260
|
+
* downstream re-derives rotation or style from anywhere else. */
|
|
9068
9261
|
translate(pose: TPose, dx: number, dy: number): TPose;
|
|
9069
9262
|
}
|
|
9070
|
-
/** Which candidate lines to derive from a set of
|
|
9263
|
+
/** Which candidate lines to derive from a set of poses — edges, centers, or
|
|
9071
9264
|
* both, and whether the page box contributes its own. */
|
|
9072
|
-
interface DeriveAlignmentGuidesOptions {
|
|
9265
|
+
interface DeriveAlignmentGuidesOptions<TPose = AlignBounds> {
|
|
9073
9266
|
/** Include the document/page box's edges + center as candidates. */
|
|
9074
9267
|
page?: AlignBounds;
|
|
9075
9268
|
/** Emit left/right (x) and top/bottom (y) edge guides. Default true. */
|
|
9076
9269
|
edges?: boolean;
|
|
9077
9270
|
/** Emit centerX (x) and centerY (y) guides. Default true. */
|
|
9078
9271
|
centers?: boolean;
|
|
9272
|
+
/** Reads each target's AABB. Defaults to `RECT_ALIGN_PROJECTION`. Pass the
|
|
9273
|
+
* same projection `alignMoveBehavior` gets, or the two sides disagree. */
|
|
9274
|
+
projection?: AlignBoundsProjection<TPose>;
|
|
9079
9275
|
}
|
|
9080
9276
|
/** Common options shared by the three alignment behavior factories. */
|
|
9081
9277
|
interface AlignmentBehaviorBase {
|
|
@@ -9092,18 +9288,23 @@ interface AlignmentBehaviorBase {
|
|
|
9092
9288
|
bypassKey?: keyof ModifierState;
|
|
9093
9289
|
}
|
|
9094
9290
|
|
|
9095
|
-
/** Derive candidate alignment lines from a set of
|
|
9291
|
+
/** Derive candidate alignment lines from a set of sibling poses plus an
|
|
9096
9292
|
* optional page box. Each box contributes up to 3 guides per axis: the two
|
|
9097
|
-
* edges and the center. Overlapping offsets collapse to one candidate.
|
|
9098
|
-
|
|
9293
|
+
* edges and the center. Overlapping offsets collapse to one candidate.
|
|
9294
|
+
* Poses go through the same projection `alignMoveBehavior` matches with, so
|
|
9295
|
+
* a rotated sibling advertises its ink edges rather than its stored box. */
|
|
9296
|
+
declare function deriveAlignmentGuides<TPose = AlignBounds>(targets: readonly TPose[], opts?: DeriveAlignmentGuidesOptions<TPose>): Guide[];
|
|
9099
9297
|
|
|
9100
9298
|
/** Move/insert test all three features per axis. */
|
|
9101
9299
|
declare const MOVE_ANCHORS: {
|
|
9102
9300
|
x: readonly AlignAnchor[];
|
|
9103
9301
|
y: readonly AlignAnchor[];
|
|
9104
9302
|
};
|
|
9105
|
-
/** Default projection for rect-shaped poses (`{x,y,width,height}`).
|
|
9106
|
-
|
|
9303
|
+
/** Default projection for rect-shaped poses (`{x,y,width,height,rotation?}`).
|
|
9304
|
+
* A rotated pose reports the AABB of its ink, so guides derived from a
|
|
9305
|
+
* stationary sibling and the box a dragged selection matches with are the
|
|
9306
|
+
* same measurement. */
|
|
9307
|
+
declare const RECT_ALIGN_PROJECTION: AlignBoundsProjection<RectPose>;
|
|
9107
9308
|
/**
|
|
9108
9309
|
* Match a moving box's selected edge/center features against candidate guide
|
|
9109
9310
|
* lines. Returns the per-axis snap delta and the matched candidate line(s).
|
|
@@ -9170,7 +9371,7 @@ declare function pointInRotatedRect(pose: RotatedPose, worldX: number, worldY: n
|
|
|
9170
9371
|
* handle's center. Matches the demo's visual default; consumers can
|
|
9171
9372
|
* override per-call. Unscaled — kit-internal use sites multiply by
|
|
9172
9373
|
* `DeviceProfile.targetScale`. */
|
|
9173
|
-
declare const DEFAULT_ROTATION_HANDLE_DISTANCE
|
|
9374
|
+
declare const DEFAULT_ROTATION_HANDLE_DISTANCE: 24;
|
|
9174
9375
|
/** Rotation handle position in world coords. */
|
|
9175
9376
|
interface RotationHandle {
|
|
9176
9377
|
/** Handle center in world coords. */
|
|
@@ -9506,7 +9707,8 @@ interface SelectFromLassoOptions {
|
|
|
9506
9707
|
* preserve, with shift). */
|
|
9507
9708
|
declare function selectFromLasso(opts?: SelectFromLassoOptions): LassoSelectBehavior;
|
|
9508
9709
|
|
|
9509
|
-
/** Edge or center the selection should align to within the selection's
|
|
9710
|
+
/** Edge or center the selection should align to within the selection's visual
|
|
9711
|
+
* union AABB (rotated members contribute their ink extent). */
|
|
9510
9712
|
type AlignEdge = 'left' | 'right' | 'top' | 'bottom' | 'center-x' | 'center-y';
|
|
9511
9713
|
/** Adapter for `useAlign`. */
|
|
9512
9714
|
interface AlignAdapter<TPose> {
|
|
@@ -9528,6 +9730,17 @@ interface UseAlignReturn {
|
|
|
9528
9730
|
/** Imperative trigger. No-op when fewer than 2 items selected. */
|
|
9529
9731
|
align(edge: AlignEdge): void;
|
|
9530
9732
|
}
|
|
9733
|
+
/**
|
|
9734
|
+
* The pose's *visual* bounds: its descriptor bounds expanded to cover the
|
|
9735
|
+
* rotated rectangle, so a turned shape reports the extent of its ink rather
|
|
9736
|
+
* than the box it was posed in. Align, distribute and flip all fold these.
|
|
9737
|
+
*
|
|
9738
|
+
* Both ends of an align must use it — a visual union measured against
|
|
9739
|
+
* unrotated member boxes misplaces every rotated member. The expanded box
|
|
9740
|
+
* shares its centre with the stored one, so the delta stays a translation of
|
|
9741
|
+
* the stored pose and no re-posing is needed.
|
|
9742
|
+
*/
|
|
9743
|
+
declare function visualBoundsViaDescriptor<TPose>(pose: TPose, geometry: PoseProjection<TPose>): ResizePose;
|
|
9531
9744
|
/** Compute the (dx, dy) translation that moves AABB `b` so that the requested
|
|
9532
9745
|
* `edge`/center matches the corresponding feature of the union AABB `u`. */
|
|
9533
9746
|
declare function alignDeltaFor(b: ResizePose, u: ResizePose, edge: AlignEdge): {
|
|
@@ -9544,8 +9757,9 @@ declare function useAlign<TPose>(adapter: AlignAdapter<TPose>, options?: UseAlig
|
|
|
9544
9757
|
|
|
9545
9758
|
/** Axis along which selection is distributed. `'x'` spreads horizontally. */
|
|
9546
9759
|
type DistributeAxis = 'x' | 'y';
|
|
9547
|
-
/** `'centers'` spaces
|
|
9548
|
-
* consecutive
|
|
9760
|
+
/** `'centers'` spaces centers equally; `'gaps'` makes the gap between
|
|
9761
|
+
* consecutive items equal. Both measure a rotated item by its ink extent.
|
|
9762
|
+
* Endpoints stay put in both modes. */
|
|
9549
9763
|
type DistributeMode = 'centers' | 'gaps';
|
|
9550
9764
|
/** Adapter for `useDistribute`. */
|
|
9551
9765
|
interface DistributeAdapter<TPose> {
|
|
@@ -10345,6 +10559,10 @@ declare function RectIcon({ className, size }: IconProps): react_jsx_runtime.JSX
|
|
|
10345
10559
|
/** Outlined ellipse. Used for the ellipse insertion tool. */
|
|
10346
10560
|
declare function EllipseIcon({ className, size }: IconProps): react_jsx_runtime.JSX.Element;
|
|
10347
10561
|
|
|
10562
|
+
/** Framed picture with a sun and mountain — the conventional "image" glyph.
|
|
10563
|
+
* Used for the image insertion tool (`useImageTool`). */
|
|
10564
|
+
declare function ImageIcon({ className, size }: IconProps): react_jsx_runtime.JSX.Element;
|
|
10565
|
+
|
|
10348
10566
|
/** Eyedropper — diagonal stem running from upper-right (bulb) to
|
|
10349
10567
|
* lower-left (tip), with a small squared bulb cap at the top. Used
|
|
10350
10568
|
* for the eyedropper / color-picker tool. */
|
|
@@ -10438,4 +10656,4 @@ interface InsertOverlayStyle {
|
|
|
10438
10656
|
lineWidth?: number;
|
|
10439
10657
|
}
|
|
10440
10658
|
|
|
10441
|
-
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, type AnimateToBoundsOptions, type AnimationHandle, type Animator, AnyTool, AreaSelectAdapter, type ArrayAdapter, type ArrayAdapterConfig, BUNDLE_TOOLS, BindingScope, BooleansAdapter, Bounds, BoundsConstraint, type BuildChromeCtxArgs, type 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 CellHighlightLayerOpts, ChromeCtx, ChromeId, ChromeState, type ClampBounds, ClipboardSnapshot, type CoalescedCtx, type ColorInterpolate, type ColorOverride, type ColorOverrideFn, 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_PALETTE, DEFAULT_ROTATION_HANDLE_DISTANCE, DEFAULT_STROKE_COLOR, DEFAULT_VELOCITY_DECAY, DebugConfig, DebugSink, DebugSnapshot, DebugStrokes, DebugTheme, type DecayLoopConfig, type DecayOptions, 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 DragPayload, type DragRadialController, type DragRadialCtx, type DragRadialEndCtx, type DragRadialPoint, type DragRadialState, type DragRectBounds, type DragRectController, type DragRectCtx, type DragRectEndCtx, type DragRectPoint, DrawCommand, type DropZoneOptions, EASINGS, type EasingFn, type EasingName, Eligibility, type EligibilityState, EllipseIcon, type EventTrack, ExcludeIcon, EyedropperIcon, FALLBACK_FIT_VIEW, type FillPoseBox, FillStyle, type FitTextPoseOptions, FitViewToBoundsOptions, type FlagKey, type FreeformOptions, GHOST_STROKE, type GateLayerOptions, GeometryProjection, type GestureSource, GradStop, GradientFill, GradientKind, type GridLayerOpts, type GridSlotConfig, Guide, type GuideSnapOptions, type GuidesLayerOpts, HANDLE_BASE_PX, HandIcon, type InertiaConfig as HandToolInertiaConfig, type HandleDragPoint, type HeadlessCanvasLike, HotkeyTrigger, IDENTITY_JOINT, type IconProps, type ImageNodeData, type ImageStatus, type IndicatorStyle, InsertAdapter, InsertBehavior, InsertExtras, type InsertNodeFactory, type InsertOp, type InsertOverlayStyle, type Interpolate, type InterpolatorFactory, IntersectIcon, type Joint, type JointTransform, KIT_SHAPE_KINDS, type Keyframe, type LabelOptions, LassoHitMode, LassoIcon, LassoSelectAdapter, LassoSelectBehavior, LayerEnumerableAdapter, LayerHit, type LayerSlotValue, type LayersMap, type LayoutLine, type LayoutResult, LayoutSnap, LayoutStrategy, type LifecycleAnimation, LineIcon, type LinePoint, type LoopFactory, type LoopOptions, MIXED, MOVE_ANCHORS, type MarkdownFontOptions, Mat3$1 as Mat3, type MeasureFn, type MeasureTextBoundsOpts, type MeasuredText, MinimapCanvas, type MinimapCanvasProps, type MinimapFit, type Mixed, ModifierState, type MomentumOptions, MoveAdapter, MoveBehavior, type NestedHitOpts, type NestedHitTester, type NestedTimeline, type NodeClientRect, type NodeFill, NodeId, type NodeInk, type NodePaintCtx, type NodeProperties, type NodePropertiesEntry, type NodeRouting, type NodeRoutingEntry, type NodeShapeEntry, type OpenFilePickerOptions, OrderedAdapter, OriginProjection, OverlayPosition, PATH_ANCHOR_CHROME_ID, type 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, type PhysicsHandle, type PhysicsOptions, PickHud, type PickHudProps, type PickTopMostHitAdapter, type PinchZoomToolOpts, type PixelRenderPlan, type PointInPathOptions, type PointInTextPoseOpts, PointSnapBehavior, PointerProviderIfRoot, type PointerSample, type PointerStylusState, PolygonIcon, PolygonPath, type PolygonPoint, type Pose, PoseProjection, type PoseRotation, type PositionedRun, type PressureToWidthOptions, type Pt, RECT_ALIGN_PROJECTION, ROTATION_HANDLE_BASE_PX, type RangeStyle, type RasterImage, type Rect, RectIcon, RectPath, RectPose, type RegisterNodeShapeOptions, RegisteredOp, RenderLayer, type RenderSceneToCanvasArgs, type RenderSceneToPixelsArgs, type ReorderDirection, ResizeAdapter, ResizeAnchor, ResizePose, type ResolvableView, ResolvedTextStyle, RotateAdapter, RotateBehavior, type RotateGeometry, RotatedPose, type RotationAffordanceOptions, type RotationHandle, type RotationScratch, Rule, RuleCtx, type RunStylePatch, SPRING_PRESETS, type 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 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 SpringOptions, type SpringPoseOptions, type SpringPreset, type SpringPresetName, type SpringVertexColorsOptions, type StaggerBuilder, type StaggerDelay, type StaggerFactory, type StaggerOptions, type StaggerPerItem, type StaggerSpringPoseOptions, type StaggerTweenOptions, type StaggerVertexColorsOptions, type StandardSlotConfig, type StandardSlotName, StarIcon, type StarPoint, type StartEditOptions, Stroke, type StyleKey, StyledRun, type StylusData, SubtractIcon, SvgIngestOptions, type TextEditScreenPose, type TextEditSelection, TextIcon, type TextLineBoxesOpts, type TextPose, type TextRenderer, TextStyle, TextVerticalAlign, TextureHandle, type ThresholdDragHandle, type ThresholdDragOptions, type TileGridOptions, type TilePatternOpts, TilePatternSpec, type TimelineHandle, type TimelineOptions, type TimelineTrack, Tool, type ToolBundle, ToolDef, ToolKeybinding, type ToolPref, type ToolPrefBoolean, type ToolPrefBooleanControl, type ToolPrefColor, type ToolPrefCustom, type ToolPrefEnum, type ToolPrefEnumControl, type ToolPrefGroup, type ToolPrefKind, type ToolPrefLeaf, type ToolPrefNumber, type ToolPrefNumberControl, type ToolPrefNumberUnit, type ToolPrefPaint, type ToolPrefString, type ToolPrefStringControl, type ToolsApi, type Track, type TweenLoopOptions, type TweenOptions, type TweenPoseOptions, type TweenVertexColorsOptions, UnionIcon, UnitSystem, UnitValue, UnknownIcon, type UseAlignOptions, type UseAlignReturn, type 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 UseHoverTrackingArgs, type UseImageToolOptions, type UseKeybindingsOptions, type UseLassoSelectOptions, type UseLassoToolOptions, UseMoveOptions, 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, type UseZoomOptions, type UseZoomReturn, VERSION, type Vec2, type VertexColorChannel, View, type ViewRect, type ViewResolver, type ViewTarget, ViewTransform, type ViewportConfig, ViewportDims, type ViewportLayer, ViewportToolDef, type ViewportZoomOptions, VisibilityRules, WeaselProvider, type WheelInput, type WheelState, ZoomBound, type ZoomBounds, type ZoomClampOpts, ZoomFactor, aabbCenter, actionIs, actionShortcuts, alignDeltaFor, alignInsertBehavior, alignMoveBehavior, alignResizeBehavior, always, and, animateLifecycle, animateOnSetPose, annulusSemiAxes, applyOpsTo, applyStyleToRange, areaSelectAction, arrayAdapter, 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, createMarkdownRenderer, createMoveToIndexOp, createNodeProperties, createNodeRouting, createParallaxLayer, createPathAnchorAffordances, createPathEditingOverlayLayer, createPathLayer, createPenPreviewLayer, createReorderOp, createReparentOp, createRotationAffordance, createScene, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, createSetDataOp, createSetLayerOp, createSetPathOp, createSetSelectionOp, createSetTextOp, createTextLayer, createTilePattern, createTransformOp, createViewResolver, createViewportLayer, cycleVertexColors, decomposePath, defaultCommitAdapter, defaultDrawOne, defaultLabelTextRenderer, defaultNodeProperties, defaultNodeRouting, defaultVisibilityRules, defineTool, defineViewportTool, deleteScratch, deriveAlignmentGuides, deriveParallaxView, dispatchApplyBatch, dlog, domPositionToCharOffset, domToRuns, dwarn, easeIn, easeInBack, easeInBounce, easeInCirc, easeInCubic, easeInElastic, easeInExpo, easeInOut, easeInOutBack, easeInOutBounce, easeInOutCirc, easeInOutCubic, easeInOutElastic, easeInOutExpo, easeInOutQuad, easeInOutQuart, easeInOutQuint, easeInOutSine, easeInQuad, easeInQuart, easeInQuint, easeInSine, easeOut, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, editAnchorsAction, ellipsePath, enumerateAnchors, fillInPoseFrame, fillToBoundsFrame, findNodeShape, findShapeInk, findShapeSilhouette, fitTextPose, fitToBounds, fitZoom, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, focused, forEachCoalesced, freeform, gateLayer, gesturing, getAlpha01, getImageBitmap, getNodeShapes, getScratch, getStylusData, gradientForBounds, gradientGeometry, guideSnapStrategy, hexToRgba, hitAffordanceRegions, hitAnchor, hitRotationHandle, hovering, hoveringSelected, imageStatus, inferredNodeProperties, inferredNodeRouting, insertAction, isDebugEnabled, isEditableTarget, isPatternSpec, keySpecShortcut, lassoSelectAction, layoutMarkdown, lerpColorArray, lerpOklab, lerpOklch, linePath, linear, liveScope, makeViewportZoomAction, matchAlignment, matchesKeyBinding, meanScale, measureText, measureTextBounds, measuredWidth, mergeAlphaFromPrev, mergeContributions, modeIn, modeIs, modeNot, modifierHeld, momentum, moveAction, multiActive, nearest, nearestWithin, nestedHitTester, never, nodeHasFlag, none, normalizeHex, not, nurbs, oklabToOklch, oklabToSrgbU8, oklchToOklab, openFilePicker, or, 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, poseRotationOf, pressureToWidth, pxExtent, rainbowVertexColors, rebuildOp, rectCorners, rectPath, registerNodeShape, registerOpFactory, regularPolygonPath, renderLabel, renderSceneToCanvas, renderSceneToPixels, resizeAction, resolveColor, resolveDeviceProfile, resolveFillPattern, 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, solidVertexColors, spiro, splitPathByLine, splitSubpaths, springPose, springVertexColors, srgbU8ToOklab, staggerVertexColors, starPath, startThresholdDrag, styleAtRange, subscribeImageReady, textCommand, textLineBoxes, tileGrid, toHex8, transformPath, translatePath, translatePolygonInPlace, translatePoseViaDescriptor, tweenPose, tweenVertexColors, unionBounds, unionBoundsPath, useAlign, useAnimator, useArrayAdapter, useAutoCenter, useBooleans, useBooleansAdapter, useCanvasFocus, useCanvasSize, useDecayLoop, useDeviceProfile, useDistribute, useDragGesture, useDragHandle, useDragRadial, useDragRect, useDropZone, useEllipseTool, useEyedropperTool, useGestureDispatcher, useGridCellHover, useGuides, useHandTool, useHandleDrag, useHoverTracking, useImageTool, useKeybindings, useLassoTool, useLineTool, usePenTool, usePencilTool, usePinchGesture, usePinchZoomTool, usePointerStylus, usePolygonTool, usePublishSelection, useRectTool, useResizePolicy, useRotateTool, useScene, useSceneAdapter, useSceneTextEdit, useSelectTool, useSelectionContext, useSimulation, useSliceDep, useStandardActions, useStarTool, useTextEdit, useTextTool, useTools, useVelocityTracker, useViewAnimation, useViewTween, useZoom, viewportDragPanAction, viewportZoomAction, viewportsAt, when, withAlpha01, withCoord, withGradientKind, withinPxBox, withinPxRadius, worldEditToStorage, zoomAt, zoomAtLeast };
|
|
10659
|
+
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, 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_PALETTE, DEFAULT_ROTATION_HANDLE_DISTANCE, DEFAULT_SHAPE_FILL, DEFAULT_STROKE_COLOR, DEFAULT_VELOCITY_DECAY, DebugConfig, DebugSink, DebugSnapshot, DebugStrokes, DebugTheme, type DecayLoopConfig, 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 DragPayload, type DragRadialController, type DragRadialCtx, type DragRadialEndCtx, type DragRadialPoint, type DragRadialState, type DragRectBounds, type DragRectController, type DragRectCtx, type DragRectEndCtx, type DragRectPoint, DrawCommand, type DropZoneOptions, EASINGS, EasingFn, type EasingName, 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, type InertiaConfig as HandToolInertiaConfig, type HandleDragPoint, type HeadlessCanvasLike, HotkeyTrigger, IDENTITY_JOINT, type IconProps, ImageIcon, type ImageNodeData, type ImageStatus, type IndicatorStyle, InsertAdapter, InsertBehavior, InsertExtras, type InsertNodeFactory, type InsertOp, type InsertOverlayStyle, IntersectIcon, type Joint, type JointTransform, type LabelOptions, LassoHitMode, LassoIcon, LassoSelectAdapter, LassoSelectBehavior, LayerEnumerableAdapter, 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, PATH_ANCHOR_CHROME_ID, type PaintBindContext, type PaintKind, type PaintKindEditorProps, type PaintKindEntry, type PaintProgram, type 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 PinchZoomToolOpts, type PixelRenderPlan, type PointInPathOptions, type PointInTextPoseOpts, PointSnapBehavior, PointerProviderIfRoot, type PointerSample, 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, SPRING_PRESETS, 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, SpringPreset, 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 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, type UseZoomOptions, type UseZoomReturn, VERSION, type Vec2, VertexColorChannel, View, ViewAnimationOptions, type ViewRect, type ViewResolver, type ViewTarget, ViewTransform, type ViewportConfig, ViewportDims, type ViewportLayer, ViewportToolDef, type ViewportZoomAnimateOptions, type ViewportZoomOptions, VisibilityRules, type VisibleRaf, type VisibleRafOptions, type VisibleRafTarget, WeaselProvider, type WheelInput, type WheelState, ZoomBound, type ZoomBounds, 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, createParallaxLayer, createPathAnchorAffordances, createPathEditingOverlayLayer, createPathLayer, createPenPreviewLayer, createReorderOp, createReparentOp, createRotationAffordance, createScene, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, createSetDataOp, createSetLayerOp, createSetPathOp, createSetSelectionOp, createSetTextOp, createTextLayer, createTilePattern, createTransformOp, createViewResolver, createViewportLayer, cycleVertexColors, decomposePath, defaultCommitAdapter, defaultDrawOne, defaultLabelTextRenderer, defaultNodeProperties, defaultNodeRouting, defaultVisibilityRules, defineTool, defineViewportTool, deleteScratch, deriveAlignmentGuides, deriveParallaxView, dispatchApplyBatch, dlog, domPositionToCharOffset, domToRuns, dwarn, easeIn, easeInBack, easeInBounce, easeInCirc, easeInCubic, easeInElastic, easeInExpo, easeInOut, easeInOutBack, easeInOutBounce, easeInOutCirc, easeInOutCubic, easeInOutElastic, easeInOutExpo, easeInOutQuad, easeInOutQuart, easeInOutQuint, easeInOutSine, easeInQuad, easeInQuart, easeInQuint, easeInSine, easeOut, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, 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, hovering, hoveringSelected, imageStatus, inferredNodeProperties, inferredNodeRouting, insertAction, interpolateView, isBuiltinToolPref, isDebugEnabled, isEditableTarget, isGradientFill, isPatternSpec, keySpecShortcut, lassoSelectAction, lerpColorArray, lerpOklab, lerpOklch, linePath, linear, listMarkers, listPaintKinds, liveScope, makePinchZoomAction, 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, 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, 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, useDecayLoop, useDeviceProfile, useDistribute, useDragGesture, useDragHandle, useDragRadial, useDragRect, useDropZone, useEllipseTool, useEyedropperTool, useGestureDispatcher, useGridCellHover, useGuides, useHandTool, useHandleDrag, useHoverTracking, useImageTool, useKeybindings, useLassoTool, useLineTool, useNodeOverlayFrame, usePenTool, usePencilTool, usePinchGesture, usePinchZoomTool, usePointerStylus, usePolygonTool, usePublishSelection, useRectTool, useResizePolicy, useRotateTool, useScene, useSceneAdapter, useSceneTextEdit, useSelectTool, useSelectionContext, useSimulation, useSliceDep, useStandardActions, useStarTool, useTextEdit, useTextTool, useTools, useVelocityTracker, useVisibleRaf, useZoom, viewportDragPanAction, viewportZoomAction, viewportsAt, visualBoundsViaDescriptor, when, withAlpha01, withCoord, withGradientKind, withinPxBox, withinPxRadius, worldEditToStorage, zoomAt, zoomAtLeast };
|