@weasel-js/core 1.11.0 → 1.12.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 +611 -0
- package/README.md +1 -1
- package/dist/WeaselProvider.js +1 -1
- package/dist/affordances/pathAnchors.js +10 -6
- package/dist/affordances/pathAnchors.js.map +1 -1
- package/dist/animation/index.js +3 -3
- package/dist/animation/rig/bindRig.js +1 -1
- package/dist/animation/rig/rigNode.js.map +1 -1
- package/dist/barrel/canvas.js +9 -3
- package/dist/barrel/interactions.js +5 -4
- package/dist/barrel/paint.js +4 -4
- package/dist/barrel/paths.js +10 -6
- package/dist/barrel/renderer.js +5 -3
- package/dist/barrel/routing.js +7 -12
- package/dist/barrel/scene.js +9 -5
- package/dist/barrel/text.js +2 -2
- package/dist/barrel/viewport.js +9 -4
- package/dist/canvas/Canvas.js +5 -2
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +23 -34
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/ModalityHud.js +1 -1
- package/dist/canvas/NodeShape.js +4 -1
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js +1 -1
- package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js +1 -1
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +1 -1
- package/dist/canvas/SceneCanvas/SceneCanvasInput.js +17 -3
- package/dist/canvas/SceneCanvas/SceneCanvasInput.js.map +1 -1
- package/dist/canvas/SceneCanvas/SurfaceDeclarations.js +23 -0
- package/dist/canvas/SceneCanvas/SurfaceDeclarations.js.map +1 -0
- package/dist/canvas/SceneCanvas/builtinToolSets.js +30 -0
- package/dist/canvas/SceneCanvas/builtinToolSets.js.map +1 -0
- package/dist/canvas/SceneCanvas/canvasPassThrough.js +2 -0
- package/dist/canvas/SceneCanvas/canvasPassThrough.js.map +1 -1
- package/dist/canvas/SceneCanvas/coordTrace.js +5 -16
- package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +5 -0
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/features.js +45 -5
- package/dist/canvas/SceneCanvas/features.js.map +1 -1
- package/dist/canvas/SceneCanvas/props.js +1 -11
- package/dist/canvas/SceneCanvas/props.js.map +1 -1
- package/dist/canvas/SceneCanvas/scenePointQuery.js +7 -3
- package/dist/canvas/SceneCanvas/scenePointQuery.js.map +1 -1
- package/dist/canvas/SceneCanvas/toolRegistry.js +8 -4
- package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -1
- package/dist/canvas/SceneCanvas/useActionTunings.js +6 -1
- package/dist/canvas/SceneCanvas/useActionTunings.js.map +1 -1
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js +1 -11
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -1
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useBuiltinTools.js +2 -9
- package/dist/canvas/SceneCanvas/useBuiltinTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js +94 -0
- package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasSelection.js +7 -2
- package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -1
- package/dist/canvas/SceneCanvas/useCanvasTools.js +15 -10
- package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useNodeKinds.js +1 -1
- package/dist/canvas/SceneCanvas/useNodeKinds.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +9 -3
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +23 -4
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +2 -3
- package/dist/canvas/SceneCanvas/useSceneCanvasTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneChrome.js +6 -7
- package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +24 -7
- package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js.map +1 -1
- package/dist/canvas/SceneCanvas/useScenePicking.js +2 -3
- package/dist/canvas/SceneCanvas/useScenePicking.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +2 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneStandardActions.js +5 -5
- package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -1
- package/dist/canvas/SceneCanvas.js +27 -24
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SurfaceCanvas.js +5 -22
- package/dist/canvas/SurfaceCanvas.js.map +1 -1
- package/dist/canvas/ViewMarker.js +35 -0
- package/dist/canvas/ViewMarker.js.map +1 -0
- package/dist/canvas/canvasRenderer.js +9 -5
- package/dist/canvas/canvasRenderer.js.map +1 -1
- package/dist/canvas/contextAttributes.js +14 -0
- package/dist/canvas/contextAttributes.js.map +1 -0
- package/dist/canvas/defaultDrawOne.js +2 -0
- package/dist/canvas/defaultDrawOne.js.map +1 -1
- package/dist/canvas/deps/booleans.js +2 -1
- package/dist/canvas/deps/booleans.js.map +1 -1
- package/dist/canvas/deps/editAnchors.js +9 -113
- package/dist/canvas/deps/editAnchors.js.map +1 -1
- package/dist/canvas/deps/hitTestArea.js +2 -2
- package/dist/canvas/deps/hitTestArea.js.map +1 -1
- package/dist/canvas/deps/insert.js +10 -4
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/pathEditCommits.js +189 -0
- package/dist/canvas/deps/pathEditCommits.js.map +1 -0
- package/dist/canvas/deps/snap.js +12 -9
- package/dist/canvas/deps/snap.js.map +1 -1
- package/dist/canvas/deps/transformFollowers.js +20 -0
- package/dist/canvas/deps/transformFollowers.js.map +1 -0
- package/dist/canvas/derivedPath.js +20 -1
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/drawnBounds.js +38 -4
- package/dist/canvas/drawnBounds.js.map +1 -1
- package/dist/canvas/inheritedPaints.js +44 -0
- package/dist/canvas/inheritedPaints.js.map +1 -0
- package/dist/canvas/nodeShapes/derivedPainter.js +23 -16
- package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/nodePaint.js +13 -34
- package/dist/canvas/nodeShapes/nodePaint.js.map +1 -1
- package/dist/canvas/nodeShapes/pathPainter.js +12 -10
- package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +4 -5
- package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/shapePainter.js +12 -11
- package/dist/canvas/nodeShapes/shapePainter.js.map +1 -1
- package/dist/canvas/nodeShapes/textPainter.js +13 -12
- package/dist/canvas/nodeShapes/textPainter.js.map +1 -1
- package/dist/canvas/overlayRoleStrokes.js +12 -0
- package/dist/canvas/overlayRoleStrokes.js.map +1 -1
- package/dist/canvas/pathOverlay.js +27 -7
- package/dist/canvas/pathOverlay.js.map +1 -1
- package/dist/canvas/pickReach.js +3 -3
- package/dist/canvas/pickReach.js.map +1 -1
- package/dist/canvas/pickWalk.js +3 -1
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/renderDebugSnapshot.js +1 -0
- package/dist/canvas/renderDebugSnapshot.js.map +1 -1
- package/dist/canvas/renderSceneToPixels.js +7 -6
- package/dist/canvas/renderSceneToPixels.js.map +1 -1
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneSlotWiring.js +2 -1
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +2 -1
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/surfaceContribution.js +12 -8
- package/dist/canvas/surfaceContribution.js.map +1 -1
- package/dist/canvas/useCanvasPaint.js +2 -1
- package/dist/canvas/useCanvasPaint.js.map +1 -1
- package/dist/canvas/useCanvasView.js +4 -2
- package/dist/canvas/useCanvasView.js.map +1 -1
- package/dist/canvas/useInFlightBounds.js +52 -0
- package/dist/canvas/useInFlightBounds.js.map +1 -0
- package/dist/canvas/useLayerStack.js +6 -2
- package/dist/canvas/useLayerStack.js.map +1 -1
- package/dist/canvas/useViewAim.js +121 -0
- package/dist/canvas/useViewAim.js.map +1 -0
- package/dist/canvas/useViewHelpers.js +7 -9
- package/dist/canvas/useViewHelpers.js.map +1 -1
- package/dist/canvas/useViewNesting.js +3 -2
- package/dist/canvas/useViewNesting.js.map +1 -1
- package/dist/canvas/useViewRegistrySurface.js +4 -2
- package/dist/canvas/useViewRegistrySurface.js.map +1 -1
- package/dist/canvas/viewMarkers.js +63 -0
- package/dist/canvas/viewMarkers.js.map +1 -0
- package/dist/canvas/viewRegistry.js +27 -1
- package/dist/canvas/viewRegistry.js.map +1 -1
- package/dist/clipboard.d.ts +3 -2
- package/dist/{clone-DZDrfIlU.d.ts → clone-C3e0OTuF.d.ts} +8 -21
- package/dist/clone.d.ts +4 -3
- package/dist/core/geometry/autoPoseDescriptor.js +1 -1
- package/dist/core/ops/setDependsOn.js +37 -0
- package/dist/core/ops/setDependsOn.js.map +1 -0
- package/dist/core/ops/writtenBy.js +53 -0
- package/dist/core/ops/writtenBy.js.map +1 -0
- package/dist/core/pages/fitViewToPage.js +12 -1
- package/dist/core/pages/fitViewToPage.js.map +1 -1
- package/dist/core/pages/pageEdits.js +163 -0
- package/dist/core/pages/pageEdits.js.map +1 -0
- package/dist/core/pages/pages.js +30 -1
- package/dist/core/pages/pages.js.map +1 -1
- package/dist/core/paint/meshKindLazy.js +59 -2
- package/dist/core/paint/meshKindLazy.js.map +1 -1
- package/dist/core/scene/NodeRouting.js +8 -3
- package/dist/core/scene/NodeRouting.js.map +1 -1
- package/dist/core/scene/arrivalWindow.js.map +1 -1
- package/dist/core/scene/carryDescendants.js +51 -0
- package/dist/core/scene/carryDescendants.js.map +1 -0
- package/dist/core/scene/clipNothing.js +13 -0
- package/dist/core/scene/clipNothing.js.map +1 -0
- package/dist/core/scene/depMemo.js +11 -3
- package/dist/core/scene/depMemo.js.map +1 -1
- package/dist/core/scene/dependents.js +7 -1
- package/dist/core/scene/dependents.js.map +1 -1
- package/dist/core/scene/derivedParts.js +10 -11
- package/dist/core/scene/derivedParts.js.map +1 -1
- package/dist/core/scene/docValues.js +57 -0
- package/dist/core/scene/docValues.js.map +1 -0
- package/dist/core/scene/editPass.js +111 -0
- package/dist/core/scene/editPass.js.map +1 -0
- package/dist/core/scene/effectivePose.js +13 -2
- package/dist/core/scene/effectivePose.js.map +1 -1
- package/dist/core/scene/fieldEdits.js +4 -1
- package/dist/core/scene/fieldEdits.js.map +1 -1
- package/dist/core/scene/fontReads.js +37 -0
- package/dist/core/scene/fontReads.js.map +1 -0
- package/dist/core/scene/historyFacade.js +1 -0
- package/dist/core/scene/historyFacade.js.map +1 -1
- package/dist/core/scene/inheritedPaint.js +75 -0
- package/dist/core/scene/inheritedPaint.js.map +1 -0
- package/dist/core/scene/kitRegistry.js +5 -0
- package/dist/core/scene/kitRegistry.js.map +1 -1
- package/dist/core/scene/layoutPass.js +28 -3
- package/dist/core/scene/layoutPass.js.map +1 -1
- package/dist/core/scene/nodeMemo.js +15 -7
- package/dist/core/scene/nodeMemo.js.map +1 -1
- package/dist/core/scene/pathEffects/blend.js.map +1 -1
- package/dist/core/scene/pathEffects/derive.js +7 -2
- package/dist/core/scene/pathEffects/derive.js.map +1 -1
- package/dist/core/scene/pathEffects/effects.js +3 -1
- package/dist/core/scene/pathEffects/effects.js.map +1 -1
- package/dist/core/scene/pathEffects/textAlong.js +95 -0
- package/dist/core/scene/pathEffects/textAlong.js.map +1 -0
- package/dist/core/scene/recorder.js +28 -19
- package/dist/core/scene/recorder.js.map +1 -1
- package/dist/core/scene/scene.js +15 -9
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/sceneChanges.js +13 -0
- package/dist/core/scene/sceneChanges.js.map +1 -0
- package/dist/core/scene/sceneEdits.js +8 -1
- package/dist/core/scene/sceneEdits.js.map +1 -1
- package/dist/core/scene/sceneMutators.js +1 -0
- package/dist/core/scene/sceneMutators.js.map +1 -1
- package/dist/core/scene/sceneRecording.js +20 -3
- package/dist/core/scene/sceneRecording.js.map +1 -1
- package/dist/core/scene/sceneSelection.js +4 -1
- package/dist/core/scene/sceneSelection.js.map +1 -1
- package/dist/core/scene/sceneState.js +11 -5
- package/dist/core/scene/sceneState.js.map +1 -1
- package/dist/core/scene/serialization.js +5 -3
- package/dist/core/scene/serialization.js.map +1 -1
- package/dist/core/scene/types.js.map +1 -1
- package/dist/core/scene/unitScopes.js +19 -1
- package/dist/core/scene/unitScopes.js.map +1 -1
- package/dist/core/selection/usePublishSceneSelection.js +6 -12
- package/dist/core/selection/usePublishSceneSelection.js.map +1 -1
- package/dist/core/shapeKinds.js +25 -11
- package/dist/core/shapeKinds.js.map +1 -1
- package/dist/{cornerHandles-Camw_yeu.d.ts → cornerHandles-p8fDIAKt.d.ts} +3 -2
- package/dist/debug/createDebugOverlayLayer.js +16 -111
- package/dist/debug/createDebugOverlayLayer.js.map +1 -1
- package/dist/debug/createDebugSink.js +2 -1
- package/dist/debug/createDebugSink.js.map +1 -1
- package/dist/debug/defaultTheme.js +4 -2
- package/dist/debug/defaultTheme.js.map +1 -1
- package/dist/debug/features.js +17 -0
- package/dist/debug/features.js.map +1 -0
- package/dist/debug/overlayPanels.js +117 -0
- package/dist/debug/overlayPanels.js.map +1 -0
- package/dist/debug/parseDebugFlags.js +4 -13
- package/dist/debug/parseDebugFlags.js.map +1 -1
- package/dist/{depSchema-Cgfu_G9s.d.ts → depSchema-mG19aEdD.d.ts} +174 -904
- package/dist/devtools/handlers.js +112 -0
- package/dist/devtools/handlers.js.map +1 -0
- package/dist/devtools/history.js +71 -0
- package/dist/devtools/history.js.map +1 -0
- package/dist/devtools/hook.js +74 -0
- package/dist/devtools/hook.js.map +1 -0
- package/dist/devtools/label.js +25 -0
- package/dist/devtools/label.js.map +1 -0
- package/dist/devtools/notices.js +58 -0
- package/dist/devtools/notices.js.map +1 -0
- package/dist/devtools/protocol.js +7 -0
- package/dist/devtools/protocol.js.map +1 -0
- package/dist/devtools/registry.js +90 -0
- package/dist/devtools/registry.js.map +1 -0
- package/dist/devtools/root.js +80 -0
- package/dist/devtools/root.js.map +1 -0
- package/dist/devtools/serialize.js +86 -0
- package/dist/devtools/serialize.js.map +1 -0
- package/dist/devtools/session.js +111 -0
- package/dist/devtools/session.js.map +1 -0
- package/dist/devtools/transport.js +67 -0
- package/dist/devtools/transport.js.map +1 -0
- package/dist/devtools/useDevtoolsRoot.js +81 -0
- package/dist/devtools/useDevtoolsRoot.js.map +1 -0
- package/dist/devtools-protocol.d.ts +435 -0
- package/dist/devtools-protocol.js +7 -0
- package/dist/devtools.d.ts +8 -0
- package/dist/devtools.js +12 -0
- package/dist/devtools.js.map +1 -0
- package/dist/features/chrome-caps/useHoverTracking.js +16 -10
- package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
- package/dist/features/ingestion/contentHandlers.js +25 -2
- package/dist/features/ingestion/contentHandlers.js.map +1 -1
- package/dist/features/measure/measureCommands.js +7 -5
- package/dist/features/measure/measureCommands.js.map +1 -1
- package/dist/features/measure/measureContribution.js +4 -2
- package/dist/features/measure/measureContribution.js.map +1 -1
- package/dist/features/modes/modeTriggers.js +7 -3
- package/dist/features/modes/modeTriggers.js.map +1 -1
- package/dist/features/pathEffects/effectSources.js +60 -0
- package/dist/features/pathEffects/effectSources.js.map +1 -0
- package/dist/features/pathEffects/readSource.js +17 -1
- package/dist/features/pathEffects/readSource.js.map +1 -1
- package/dist/features/pathEffects/textItems.js +53 -0
- package/dist/features/pathEffects/textItems.js.map +1 -0
- package/dist/features/pathEffects/useEffectSourcesLayer.js +57 -0
- package/dist/features/pathEffects/useEffectSourcesLayer.js.map +1 -0
- package/dist/features/paths/index.js +2 -2
- package/dist/features/paths/pathEditExtension.js.map +1 -1
- package/dist/features/paths/pathEditState.js +5 -2
- package/dist/features/paths/pathEditState.js.map +1 -1
- package/dist/features/paths/pathSnap/pathSnapSource.js +5 -5
- package/dist/features/paths/pathSnap/pathSnapSource.js.map +1 -1
- package/dist/features/paths/pathSnap/sceneIndex.js +10 -3
- package/dist/features/paths/pathSnap/sceneIndex.js.map +1 -1
- package/dist/features/selection/selectionPose.js +4 -1
- package/dist/features/selection/selectionPose.js.map +1 -1
- package/dist/features/snap/gather.js +9 -1
- package/dist/features/snap/gather.js.map +1 -1
- package/dist/features/snap/lazySession.js +17 -0
- package/dist/features/snap/lazySession.js.map +1 -0
- package/dist/features/snap/marks.js.map +1 -1
- package/dist/features/snap/probes2d.js +27 -19
- package/dist/features/snap/probes2d.js.map +1 -1
- package/dist/features/snap/readoutLayer.js.map +1 -1
- package/dist/features/snap/roles.js +2 -1
- package/dist/features/snap/roles.js.map +1 -1
- package/dist/features/snap/rotationSource.js +25 -8
- package/dist/features/snap/rotationSource.js.map +1 -1
- package/dist/features/snap/sceneSession2d.js +6 -4
- package/dist/features/snap/sceneSession2d.js.map +1 -1
- package/dist/features/snap/session2d.js +37 -23
- package/dist/features/snap/session2d.js.map +1 -1
- package/dist/features/snap/spanSnap.js +5 -2
- package/dist/features/snap/spanSnap.js.map +1 -1
- package/dist/features/text/sceneTextDrafts.js +65 -0
- package/dist/features/text/sceneTextDrafts.js.map +1 -0
- package/dist/features/text/textHitAt.js +31 -2
- package/dist/features/text/textHitAt.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +22 -18
- package/dist/features/text/useSceneTextEdit.js.map +1 -1
- package/dist/features/viewports/aim.js +105 -0
- package/dist/features/viewports/aim.js.map +1 -0
- package/dist/features/viewports/viewMarker.js +82 -0
- package/dist/features/viewports/viewMarker.js.map +1 -0
- package/dist/features/viewports/viewMarkerDrag.js +55 -0
- package/dist/features/viewports/viewMarkerDrag.js.map +1 -0
- package/dist/icons.table.js +1 -1
- package/dist/icons.table.js.map +1 -1
- package/dist/icons.table.json +0 -10
- package/dist/index.d.ts +1198 -894
- package/dist/index.js +55 -38
- package/dist/interactions/actions/align/action.js +6 -4
- package/dist/interactions/actions/align/action.js.map +1 -1
- package/dist/interactions/actions/align/align.js.map +1 -1
- package/dist/interactions/actions/booleans/action.js +7 -1
- package/dist/interactions/actions/booleans/action.js.map +1 -1
- package/dist/interactions/actions/booleans/booleans.js +2 -1
- package/dist/interactions/actions/booleans/booleans.js.map +1 -1
- package/dist/interactions/actions/booleans/operands.js +6 -5
- package/dist/interactions/actions/booleans/operands.js.map +1 -1
- package/dist/interactions/actions/clipboard/action.js +27 -17
- package/dist/interactions/actions/clipboard/action.js.map +1 -1
- package/dist/interactions/actions/clone/action.js +1 -1
- package/dist/interactions/actions/clone/behaviors.js +4 -4
- package/dist/interactions/actions/clone/behaviors.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +44 -23
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorJoin.js +12 -6
- package/dist/interactions/actions/defaults/anchorJoin.js.map +1 -1
- package/dist/interactions/actions/defaults/bendSegment.js +8 -5
- package/dist/interactions/actions/defaults/bendSegment.js.map +1 -1
- package/dist/interactions/actions/defaults/cancelGesture.js +11 -8
- package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -1
- package/dist/interactions/actions/defaults/contextMenu.js +17 -8
- package/dist/interactions/actions/defaults/contextMenu.js.map +1 -1
- package/dist/interactions/actions/defaults/createPaintAction.js +2 -2
- package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -1
- package/dist/interactions/actions/defaults/delete.js +64 -41
- package/dist/interactions/actions/defaults/delete.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +12 -9
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
- package/dist/interactions/actions/defaults/enterPathEdit.js +19 -9
- package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/escape.js +11 -8
- package/dist/interactions/actions/defaults/escape.js.map +1 -1
- package/dist/interactions/actions/defaults/exitPathEdit.js +7 -4
- package/dist/interactions/actions/defaults/exitPathEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +21 -15
- package/dist/interactions/actions/defaults/group.js.map +1 -1
- package/dist/interactions/actions/defaults/ingest.js +17 -9
- package/dist/interactions/actions/defaults/ingest.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +7 -4
- package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
- package/dist/interactions/actions/defaults/nudge.js +21 -40
- package/dist/interactions/actions/defaults/nudge.js.map +1 -1
- package/dist/interactions/actions/defaults/pathEditTools.js +11 -8
- package/dist/interactions/actions/defaults/pathEditTools.js.map +1 -1
- package/dist/interactions/actions/defaults/pinchZoom.js +7 -4
- package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -1
- package/dist/interactions/actions/defaults/reorder.js +24 -6
- package/dist/interactions/actions/defaults/reorder.js.map +1 -1
- package/dist/interactions/actions/defaults/selectAll.js +8 -5
- package/dist/interactions/actions/defaults/selectAll.js.map +1 -1
- package/dist/interactions/actions/defaults/setFill.js +7 -3
- package/dist/interactions/actions/defaults/setFill.js.map +1 -1
- package/dist/interactions/actions/defaults/setFillOpacity.js +1 -1
- package/dist/interactions/actions/defaults/setStroke.js +12 -11
- package/dist/interactions/actions/defaults/setStroke.js.map +1 -1
- package/dist/interactions/actions/defaults/setStrokeOpacity.js +1 -1
- package/dist/interactions/actions/defaults/toolActivate.js +7 -1
- package/dist/interactions/actions/defaults/toolActivate.js.map +1 -1
- package/dist/interactions/actions/defaults/toolResetToDefault.js +7 -4
- package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -1
- package/dist/interactions/actions/defaults/undoRedo.js +19 -13
- package/dist/interactions/actions/defaults/undoRedo.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportWheelPan.js +16 -7
- package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportZoom.js +24 -6
- package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
- package/dist/interactions/actions/distribute/action.js +6 -4
- package/dist/interactions/actions/distribute/action.js.map +1 -1
- package/dist/interactions/actions/drawnBoxes.js +2 -1
- package/dist/interactions/actions/drawnBoxes.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/action.js +10 -10
- package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/preview.js +41 -8
- package/dist/interactions/actions/edit-anchors/preview.js.map +1 -1
- package/dist/interactions/actions/flip/action.js +14 -6
- package/dist/interactions/actions/flip/action.js.map +1 -1
- package/dist/interactions/actions/gestureLifecycle.js +5 -2
- package/dist/interactions/actions/gestureLifecycle.js.map +1 -1
- package/dist/interactions/actions/insert/action.js +1 -2
- package/dist/interactions/actions/insert/action.js.map +1 -1
- package/dist/interactions/actions/insert/commit.js +1 -1
- package/dist/interactions/actions/insert/parent.js +11 -0
- package/dist/interactions/actions/insert/parent.js.map +1 -0
- package/dist/interactions/actions/insert/placeAction.js +7 -2
- package/dist/interactions/actions/insert/placeAction.js.map +1 -1
- package/dist/interactions/actions/insert/repositionAction.js +2 -1
- package/dist/interactions/actions/insert/repositionAction.js.map +1 -1
- package/dist/interactions/actions/insert/session.js +5 -1
- package/dist/interactions/actions/insert/session.js.map +1 -1
- package/dist/interactions/actions/move/action.js +15 -8
- package/dist/interactions/actions/move/action.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/layoutDrop.js +0 -1
- package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +1 -1
- package/dist/interactions/actions/move/capture.js +1 -1
- package/dist/interactions/actions/move/commit/index.js +0 -2
- package/dist/interactions/actions/move/commit/index.js.map +1 -1
- package/dist/interactions/actions/move/commit/layoutDrop.js +2 -2
- package/dist/interactions/actions/move/commit/layoutRelease.js +2 -2
- package/dist/interactions/actions/move/commit/reparent.js +11 -5
- package/dist/interactions/actions/move/commit/reparent.js.map +1 -1
- package/dist/interactions/actions/move/frame.js +4 -10
- package/dist/interactions/actions/move/frame.js.map +1 -1
- package/dist/interactions/actions/move/landedDescendants.js +20 -17
- package/dist/interactions/actions/move/landedDescendants.js.map +1 -1
- package/dist/interactions/actions/move/layout/container.js +2 -1
- package/dist/interactions/actions/move/layout/container.js.map +1 -1
- package/dist/interactions/actions/move/layout/dragged.js +1 -1
- package/dist/interactions/actions/move/layout/dropPass.js +18 -1
- package/dist/interactions/actions/move/layout/dropPass.js.map +1 -1
- package/dist/interactions/actions/move/layout/exits.js +5 -5
- package/dist/interactions/actions/move/layout/exits.js.map +1 -1
- package/dist/interactions/actions/move/session.js +14 -3
- package/dist/interactions/actions/move/session.js.map +1 -1
- package/dist/interactions/actions/move/translate.js +8 -37
- package/dist/interactions/actions/move/translate.js.map +1 -1
- package/dist/interactions/actions/moveNodes.js +87 -0
- package/dist/interactions/actions/moveNodes.js.map +1 -0
- package/dist/interactions/actions/outlines/createOutlinesAction.js +8 -5
- package/dist/interactions/actions/outlines/createOutlinesAction.js.map +1 -1
- package/dist/interactions/actions/outlines/outlineStroke.js +5 -3
- package/dist/interactions/actions/outlines/outlineStroke.js.map +1 -1
- package/dist/interactions/actions/pathCommands/cutJoin.js +8 -5
- package/dist/interactions/actions/pathCommands/cutJoin.js.map +1 -1
- package/dist/interactions/actions/planeInput.js.map +1 -1
- package/dist/interactions/actions/resize/action.js +83 -72
- package/dist/interactions/actions/resize/action.js.map +1 -1
- package/dist/interactions/actions/resize/commit.js +2 -1
- package/dist/interactions/actions/resize/commit.js.map +1 -1
- package/dist/interactions/actions/resize/cornerHandles.js +2 -1
- package/dist/interactions/actions/resize/cornerHandles.js.map +1 -1
- package/dist/interactions/actions/resize/session.js +2 -0
- package/dist/interactions/actions/resize/session.js.map +1 -1
- package/dist/interactions/actions/resolvePreviews.js +3 -3
- package/dist/interactions/actions/resolvePreviews.js.map +1 -1
- package/dist/interactions/actions/rotate/action.js +7 -4
- package/dist/interactions/actions/rotate/action.js.map +1 -1
- package/dist/interactions/actions/rotate/commit.js +2 -1
- package/dist/interactions/actions/rotate/commit.js.map +1 -1
- package/dist/interactions/actions/rotate/session.js +2 -0
- package/dist/interactions/actions/rotate/session.js.map +1 -1
- package/dist/interactions/actions/selectionSubtree.js +25 -9
- package/dist/interactions/actions/selectionSubtree.js.map +1 -1
- package/dist/interactions/actions/testUtils.js.map +1 -1
- package/dist/interactions/actions/transform-again/action.js +13 -11
- package/dist/interactions/actions/transform-again/action.js.map +1 -1
- package/dist/interactions/actions/transformFinish.js +106 -0
- package/dist/interactions/actions/transformFinish.js.map +1 -0
- package/dist/json.d.ts +4 -0
- package/dist/json.js +3 -0
- package/dist/kitSettingsSchema.js +8 -5
- package/dist/kitSettingsSchema.js.map +1 -1
- package/dist/{math-CrJULaZI.d.ts → math-B56zxVs5.d.ts} +10 -1
- package/dist/math.d.ts +1 -1
- package/dist/math.js +2 -1
- package/dist/move.d.ts +5 -4
- package/dist/{options-p9GZMXbY.d.ts → options-DBxEryYq.d.ts} +1 -1
- package/dist/resize.d.ts +4 -3
- package/dist/routing.d.ts +1 -1
- package/dist/routing.js +2 -2
- package/dist/test-hook/createTestHook.js +1 -1
- package/dist/test-hook/createTestHook.js.map +1 -1
- package/dist/test-hook/useTestHook.js +2 -1
- package/dist/test-hook/useTestHook.js.map +1 -1
- package/dist/test-seams.d.ts +9 -5
- package/dist/tools/builtin/ellipse/useEllipseTool.js +1 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js +2 -1
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
- package/dist/tools/builtin/hand/dragPanContribution.js +4 -1
- package/dist/tools/builtin/hand/dragPanContribution.js.map +1 -1
- package/dist/tools/builtin/hand/useHandTool.js +7 -4
- package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
- package/dist/tools/builtin/image/useImageTool.js +1 -0
- package/dist/tools/builtin/image/useImageTool.js.map +1 -1
- package/dist/tools/builtin/lasso/useLassoTool.js +1 -0
- package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
- package/dist/tools/builtin/line/useLineTool.js +1 -0
- package/dist/tools/builtin/line/useLineTool.js.map +1 -1
- package/dist/tools/builtin/measure/useMeasureTool.js +12 -5
- package/dist/tools/builtin/measure/useMeasureTool.js.map +1 -1
- package/dist/tools/builtin/pen/penHandle.js +3 -5
- package/dist/tools/builtin/pen/penHandle.js.map +1 -1
- package/dist/tools/builtin/pen/usePenTool.js +14 -6
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
- package/dist/tools/builtin/pencil/usePencilTool.js +1 -0
- package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
- package/dist/tools/builtin/polygon/usePolygonTool.js +13 -4
- package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
- package/dist/tools/builtin/rect/useRectTool.js +1 -0
- package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
- package/dist/tools/builtin/select/adapterPointQuery.js +3 -2
- package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -1
- package/dist/tools/builtin/select/pressDecision.js +32 -0
- package/dist/tools/builtin/select/pressDecision.js.map +1 -0
- package/dist/tools/builtin/select/selectionContributions.js +22 -13
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +13 -10
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/slice/useSliceTool.js +22 -8
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
- package/dist/tools/builtin/star/useStarTool.js +13 -4
- package/dist/tools/builtin/star/useStarTool.js.map +1 -1
- package/dist/tools/builtin/sticky/stickyNode.js +4 -1
- package/dist/tools/builtin/sticky/stickyNode.js.map +1 -1
- package/dist/tools/builtin/sticky/useStickyTool.js +10 -5
- package/dist/tools/builtin/sticky/useStickyTool.js.map +1 -1
- package/dist/tools/builtin/text/useTextTool.js +3 -1
- package/dist/tools/builtin/text/useTextTool.js.map +1 -1
- package/dist/tools/index.js +26 -0
- package/dist/{types-CHVXGfYm.d.ts → types-7puAuVD2.d.ts} +3 -262
- package/dist/types-BN9hbdMI.d.ts +184 -0
- package/dist/types-CniVctmk.d.ts +949 -0
- package/dist/types-oFeQ5VjV.d.ts +264 -0
- package/dist/util/paint.js +1 -3
- package/dist/util/paint.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +39 -25
- package/dist/canvas/SceneCanvas/useBuiltinRigTools.js +0 -65
- package/dist/canvas/SceneCanvas/useBuiltinRigTools.js.map +0 -1
- package/dist/tools/builtin/bone/boneActions.js +0 -156
- package/dist/tools/builtin/bone/boneActions.js.map +0 -1
- package/dist/tools/builtin/bone/boneOverlay.js +0 -71
- package/dist/tools/builtin/bone/boneOverlay.js.map +0 -1
- package/dist/tools/builtin/bone/placedRig.js +0 -28
- package/dist/tools/builtin/bone/placedRig.js.map +0 -1
- package/dist/tools/builtin/bone/rigEditState.js +0 -30
- package/dist/tools/builtin/bone/rigEditState.js.map +0 -1
- package/dist/tools/builtin/bone/useBoneTool.js +0 -125
- package/dist/tools/builtin/bone/useBoneTool.js.map +0 -1
- package/dist/tools/builtin/weight/useWeightTool.js +0 -101
- package/dist/tools/builtin/weight/useWeightTool.js.map +0 -1
- package/dist/tools/builtin/weight/weightActions.js +0 -140
- package/dist/tools/builtin/weight/weightActions.js.map +0 -1
- package/dist/tools/builtin/weight/weightOverlay.js +0 -78
- package/dist/tools/builtin/weight/weightOverlay.js.map +0 -1
package/dist/core/shapeKinds.js
CHANGED
|
@@ -7,45 +7,55 @@
|
|
|
7
7
|
var SHAPE_KINDS = {
|
|
8
8
|
rect: {
|
|
9
9
|
tool: true,
|
|
10
|
-
insertPreview: true
|
|
10
|
+
insertPreview: true,
|
|
11
|
+
family: "shape"
|
|
11
12
|
},
|
|
12
13
|
ellipse: {
|
|
13
14
|
tool: true,
|
|
14
|
-
insertPreview: true
|
|
15
|
+
insertPreview: true,
|
|
16
|
+
family: "shape"
|
|
15
17
|
},
|
|
16
18
|
line: {
|
|
17
19
|
tool: true,
|
|
18
|
-
insertPreview: true
|
|
20
|
+
insertPreview: true,
|
|
21
|
+
family: "shape"
|
|
19
22
|
},
|
|
20
23
|
polygon: {
|
|
21
24
|
tool: true,
|
|
22
|
-
insertPreview: true
|
|
25
|
+
insertPreview: true,
|
|
26
|
+
family: "shape"
|
|
23
27
|
},
|
|
24
28
|
star: {
|
|
25
29
|
tool: true,
|
|
26
|
-
insertPreview: true
|
|
30
|
+
insertPreview: true,
|
|
31
|
+
family: "shape"
|
|
27
32
|
},
|
|
28
33
|
pen: {
|
|
29
34
|
tool: true,
|
|
30
|
-
insertPreview: false
|
|
35
|
+
insertPreview: false,
|
|
36
|
+
family: "draw"
|
|
31
37
|
},
|
|
32
38
|
pencil: {
|
|
33
39
|
tool: true,
|
|
34
|
-
insertPreview: true
|
|
40
|
+
insertPreview: true,
|
|
41
|
+
family: "draw"
|
|
35
42
|
},
|
|
36
43
|
lasso: {
|
|
37
44
|
tool: true,
|
|
38
|
-
insertPreview: false
|
|
45
|
+
insertPreview: false,
|
|
46
|
+
family: "select"
|
|
39
47
|
},
|
|
40
48
|
text: {
|
|
41
49
|
tool: true,
|
|
42
50
|
insertPreview: true,
|
|
43
|
-
text: true
|
|
51
|
+
text: true,
|
|
52
|
+
family: "type"
|
|
44
53
|
},
|
|
45
54
|
sticky: {
|
|
46
55
|
tool: true,
|
|
47
56
|
insertPreview: true,
|
|
48
|
-
text: true
|
|
57
|
+
text: true,
|
|
58
|
+
family: "type"
|
|
49
59
|
},
|
|
50
60
|
image: {
|
|
51
61
|
tool: false,
|
|
@@ -63,7 +73,11 @@ function shapeKindInfo(kind) {
|
|
|
63
73
|
}
|
|
64
74
|
/** Runtime, iterable list of the shape-tool ids in `BuiltinShapeToolId`. */
|
|
65
75
|
var KIT_SHAPE_KINDS = shapeKindsWhere(SHAPE_KINDS, "tool");
|
|
76
|
+
/** The shape-tool ids of one family, in declaration order. */
|
|
77
|
+
function kitShapeKindsOf(family) {
|
|
78
|
+
return KIT_SHAPE_KINDS.filter((k) => SHAPE_KINDS[k].family === family);
|
|
79
|
+
}
|
|
66
80
|
|
|
67
81
|
//#endregion
|
|
68
|
-
export { KIT_SHAPE_KINDS, SHAPE_KINDS, shapeKindInfo, shapeKindsWhere };
|
|
82
|
+
export { KIT_SHAPE_KINDS, SHAPE_KINDS, kitShapeKindsOf, shapeKindInfo, shapeKindsWhere };
|
|
69
83
|
//# sourceMappingURL=shapeKinds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shapeKinds.js","names":[],"sources":["../../src/core/shapeKinds.ts"],"sourcesContent":["/**\n * The kit's built-in shape kinds — one table, every other spelling derived.\n *\n * This module imports nothing on purpose: `useBuiltinShapeTools` imports the\n * package barrel, so anything barrel-reachable that needs these lists at\n * module-evaluation time must not route through it.\n */\n\n/** What the kit knows about one built-in shape kind. */\nexport interface ShapeKindDescriptor {\n /** Mounted as a built-in shape tool by `useBuiltinShapeTools`, and so a\n * member of `BuiltinShapeToolId` / `KIT_SHAPE_KINDS`. `image` is false:\n * `useImageTool` needs a `src` and can't be auto-mounted. */\n readonly tool: boolean;\n /** `insertAction` emits an `insertPreview` overlay for this kind, and the\n * dispatcher overlay layer knows how to draw it. Kinds without one still\n * commit; they just have no live drag preview. */\n readonly insertPreview: boolean;\n /** A node of this kind is a text node: an insert drops into its caret, and\n * its properties carry the text groups. Absent, it is not. */\n readonly text?: boolean;\n}\n\n/**\n * Declaration order is the enumeration order of every derived list —\n * `KIT_SHAPE_KINDS`, and through it `defaultNodeRouting` /\n * `defaultNodeProperties` / `BUILTIN_TOOL_IDS`.\n */\nexport const SHAPE_KINDS = {\n rect: { tool: true, insertPreview: true },\n ellipse: { tool: true, insertPreview: true },\n line: { tool: true, insertPreview: true },\n polygon: { tool: true, insertPreview: true },\n star: { tool: true, insertPreview: true },\n pen: { tool: true, insertPreview: false },\n pencil: { tool: true, insertPreview: true },\n lasso: { tool: true, insertPreview: false },\n text: { tool: true, insertPreview: true, text: true },\n sticky: { tool: true, insertPreview: true, text: true },\n image: { tool: false, insertPreview: true },\n} as const satisfies Record<string, ShapeKindDescriptor>;\n\n/** Every kind in the table, tool or not. */\nexport type ShapeKind = keyof typeof SHAPE_KINDS;\n\n/** The keys of a shape-kind table whose descriptor sets `F` to `true`. */\nexport type ShapeKindsWhere<T, F extends keyof ShapeKindDescriptor> = {\n [K in keyof T]: T[K] extends Record<F, true> ? K : never;\n}[keyof T];\n\n/** Built-in shape tool ids handled by `useBuiltinShapeTools`. */\nexport type BuiltinShapeToolId = ShapeKindsWhere<typeof SHAPE_KINDS, 'tool'>;\n\n/** The insert kinds the kit's dispatcher overlay layer knows how to render.\n * Consumer-defined kinds fall outside it: no live preview, commit unaffected. */\nexport type KitInsertShape = ShapeKindsWhere<typeof SHAPE_KINDS, 'insertPreview'>;\n\n/** Kinds in `table` whose descriptor sets `field`, in declaration order. */\nexport function shapeKindsWhere<T extends Record<string, ShapeKindDescriptor>>(\n table: T,\n field: keyof ShapeKindDescriptor,\n): (keyof T & string)[] {\n return (Object.keys(table) as (keyof T & string)[]).filter((k) => table[k][field]);\n}\n\n/** The descriptor for `kind`, or `undefined` for a kind the kit doesn't ship.\n * The one accessor: ask it rather than testing membership of a derived list. */\nexport function shapeKindInfo(kind: string): ShapeKindDescriptor | undefined {\n return (SHAPE_KINDS as Record<string, ShapeKindDescriptor>)[kind];\n}\n\n/** Runtime, iterable list of the shape-tool ids in `BuiltinShapeToolId`. */\nexport const KIT_SHAPE_KINDS: readonly BuiltinShapeToolId[] =\n shapeKindsWhere(SHAPE_KINDS, 'tool') as BuiltinShapeToolId[];\n"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"shapeKinds.js","names":[],"sources":["../../src/core/shapeKinds.ts"],"sourcesContent":["/**\n * The kit's built-in shape kinds — one table, every other spelling derived.\n *\n * This module imports nothing on purpose: `useBuiltinShapeTools` imports the\n * package barrel, so anything barrel-reachable that needs these lists at\n * module-evaluation time must not route through it.\n */\n\n/** What the kit knows about one built-in shape kind. */\nexport interface ShapeKindDescriptor {\n /** Mounted as a built-in shape tool by `useBuiltinShapeTools`, and so a\n * member of `BuiltinShapeToolId` / `KIT_SHAPE_KINDS`. `image` is false:\n * `useImageTool` needs a `src` and can't be auto-mounted. */\n readonly tool: boolean;\n /** `insertAction` emits an `insertPreview` overlay for this kind, and the\n * dispatcher overlay layer knows how to draw it. Kinds without one still\n * commit; they just have no live drag preview. */\n readonly insertPreview: boolean;\n /** The tool family a kind with a tool belongs to: which built-in tool set\n * names it, and so which palette group it sits in. */\n readonly family?: 'shape' | 'draw' | 'select' | 'type';\n /** A node of this kind is a text node: an insert drops into its caret, and\n * its properties carry the text groups. Absent, it is not. */\n readonly text?: boolean;\n}\n\n/**\n * Declaration order is the enumeration order of every derived list —\n * `KIT_SHAPE_KINDS`, and through it `defaultNodeRouting` /\n * `defaultNodeProperties` / `BUILTIN_TOOL_IDS`.\n */\nexport const SHAPE_KINDS = {\n rect: { tool: true, insertPreview: true, family: 'shape' },\n ellipse: { tool: true, insertPreview: true, family: 'shape' },\n line: { tool: true, insertPreview: true, family: 'shape' },\n polygon: { tool: true, insertPreview: true, family: 'shape' },\n star: { tool: true, insertPreview: true, family: 'shape' },\n pen: { tool: true, insertPreview: false, family: 'draw' },\n pencil: { tool: true, insertPreview: true, family: 'draw' },\n lasso: { tool: true, insertPreview: false, family: 'select' },\n text: { tool: true, insertPreview: true, text: true, family: 'type' },\n sticky: { tool: true, insertPreview: true, text: true, family: 'type' },\n image: { tool: false, insertPreview: true },\n} as const satisfies Record<string, ShapeKindDescriptor>;\n\n/** Every kind in the table, tool or not. */\nexport type ShapeKind = keyof typeof SHAPE_KINDS;\n\n/** The keys of a shape-kind table whose descriptor sets `F` to `true`. */\nexport type ShapeKindsWhere<T, F extends keyof ShapeKindDescriptor> = {\n [K in keyof T]: T[K] extends Record<F, true> ? K : never;\n}[keyof T];\n\n/** Built-in shape tool ids handled by `useBuiltinShapeTools`. */\nexport type BuiltinShapeToolId = ShapeKindsWhere<typeof SHAPE_KINDS, 'tool'>;\n\n/** The insert kinds the kit's dispatcher overlay layer knows how to render.\n * Consumer-defined kinds fall outside it: no live preview, commit unaffected. */\nexport type KitInsertShape = ShapeKindsWhere<typeof SHAPE_KINDS, 'insertPreview'>;\n\n/** Kinds in `table` whose descriptor sets `field`, in declaration order. */\nexport function shapeKindsWhere<T extends Record<string, ShapeKindDescriptor>>(\n table: T,\n field: keyof ShapeKindDescriptor,\n): (keyof T & string)[] {\n return (Object.keys(table) as (keyof T & string)[]).filter((k) => table[k][field]);\n}\n\n/** The descriptor for `kind`, or `undefined` for a kind the kit doesn't ship.\n * The one accessor: ask it rather than testing membership of a derived list. */\nexport function shapeKindInfo(kind: string): ShapeKindDescriptor | undefined {\n return (SHAPE_KINDS as Record<string, ShapeKindDescriptor>)[kind];\n}\n\n/** Runtime, iterable list of the shape-tool ids in `BuiltinShapeToolId`. */\nexport const KIT_SHAPE_KINDS: readonly BuiltinShapeToolId[] =\n shapeKindsWhere(SHAPE_KINDS, 'tool') as BuiltinShapeToolId[];\n\n/** The shape-tool ids of one family, in declaration order. */\nexport function kitShapeKindsOf(family: NonNullable<ShapeKindDescriptor['family']>): BuiltinShapeToolId[] {\n return KIT_SHAPE_KINDS.filter((k) => (SHAPE_KINDS as Record<string, ShapeKindDescriptor>)[k]!.family === family);\n}\n"],"mappings":";;;;;;AA+BA,IAAa,cAAc;CACzB,MAAM;EAAE,MAAM;EAAM,eAAe;EAAM,QAAQ;CAAQ;CACzD,SAAS;EAAE,MAAM;EAAM,eAAe;EAAM,QAAQ;CAAQ;CAC5D,MAAM;EAAE,MAAM;EAAM,eAAe;EAAM,QAAQ;CAAQ;CACzD,SAAS;EAAE,MAAM;EAAM,eAAe;EAAM,QAAQ;CAAQ;CAC5D,MAAM;EAAE,MAAM;EAAM,eAAe;EAAM,QAAQ;CAAQ;CACzD,KAAK;EAAE,MAAM;EAAM,eAAe;EAAO,QAAQ;CAAO;CACxD,QAAQ;EAAE,MAAM;EAAM,eAAe;EAAM,QAAQ;CAAO;CAC1D,OAAO;EAAE,MAAM;EAAM,eAAe;EAAO,QAAQ;CAAS;CAC5D,MAAM;EAAE,MAAM;EAAM,eAAe;EAAM,MAAM;EAAM,QAAQ;CAAO;CACpE,QAAQ;EAAE,MAAM;EAAM,eAAe;EAAM,MAAM;EAAM,QAAQ;CAAO;CACtE,OAAO;EAAE,MAAM;EAAO,eAAe;CAAK;AAC5C;;AAkBA,SAAgB,gBACd,OACA,OACsB;CACtB,OAAQ,OAAO,KAAK,KAAK,CAAC,CAA0B,QAAQ,MAAM,MAAM,EAAE,CAAC,MAAM;AACnF;;;AAIA,SAAgB,cAAc,MAA+C;CAC3E,OAAQ,YAAoD;AAC9D;;AAGA,IAAa,kBACX,gBAAgB,aAAa,MAAM;;AAGrC,SAAgB,gBAAgB,QAA0E;CACxG,OAAO,gBAAgB,QAAQ,MAAO,YAAoD,EAAE,CAAE,WAAW,MAAM;AACjH"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BoundsConstraint } from './clone-
|
|
1
|
+
import { B as BoundsConstraint } from './clone-C3e0OTuF.js';
|
|
2
2
|
import { FramedBox, Affine } from '@weasel-js/geom';
|
|
3
3
|
import { ResizeAnchor } from '@weasel-js/routing';
|
|
4
4
|
|
|
@@ -139,7 +139,8 @@ declare function handlePoint(bounds: FramedBox, entry: Pick<ResizeHandleAnchor,
|
|
|
139
139
|
x: number;
|
|
140
140
|
y: number;
|
|
141
141
|
};
|
|
142
|
-
/**
|
|
142
|
+
/** A corner handle's position for the given bounds, in the bounds' frame.
|
|
143
|
+
* @deprecated Use {@link handlePoint}, which also places edge handles. */
|
|
143
144
|
declare const cornerPoint: (bounds: FramedBox, entry: Pick<CornerAnchor, 'xEdge' | 'yEdge'>) => {
|
|
144
145
|
x: number;
|
|
145
146
|
y: number;
|
|
@@ -2,6 +2,7 @@ import { viewToTransform } from "../core/viewport/view.js";
|
|
|
2
2
|
import { worldToScreen } from "../core/viewport/viewTransform.js";
|
|
3
3
|
import { rotatePoint } from "../interactions/actions/rotate/geometry.js";
|
|
4
4
|
import { DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME } from "./defaultTheme.js";
|
|
5
|
+
import { LINE_H, emitFramePanel, emitLayersPanel, emitTextPanel, rectPath as rectPath$1 } from "./overlayPanels.js";
|
|
5
6
|
import { textCommandFromRuns } from "@weasel-js/renderer";
|
|
6
7
|
import { PATH_L, PATH_M, PATH_Z } from "@weasel-js/geom";
|
|
7
8
|
|
|
@@ -53,6 +54,7 @@ function buildDebugOverlayCommands(snapshot, config, view, dims, frameTimes = []
|
|
|
53
54
|
if (config.viewport && s.viewport) emitViewport(out, s.viewport, view, dims, theme, strokes);
|
|
54
55
|
if (config.hitboxes) emitHitboxes(out, s, view, t, theme, strokes);
|
|
55
56
|
if (config.bounds) emitBounds(out, s, view, t, theme, strokes);
|
|
57
|
+
if (config.highlight?.length) emitHighlight(out, s, new Set(config.highlight), view, t, theme, strokes);
|
|
56
58
|
if (config.handles) emitHandles(out, s, t, theme, strokes);
|
|
57
59
|
if (config.origins) emitOrigins(out, s, t, theme);
|
|
58
60
|
if (config.snap) emitSnap(out, s, t, theme, strokes);
|
|
@@ -113,17 +115,6 @@ function rotatedRectScreen(r, t) {
|
|
|
113
115
|
fillRule: "nonzero"
|
|
114
116
|
};
|
|
115
117
|
}
|
|
116
|
-
function rectPath$1(x, y, w, h) {
|
|
117
|
-
return {
|
|
118
|
-
kind: "rect",
|
|
119
|
-
x,
|
|
120
|
-
y,
|
|
121
|
-
width: w,
|
|
122
|
-
height: h
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
/** A `DebugStroke` + color as the renderer's stroke shape. `dash` is dropped
|
|
126
|
-
* when empty rather than passed through, so a solid line stays solid. */
|
|
127
118
|
function strokeOf(s, color) {
|
|
128
119
|
return {
|
|
129
120
|
paint: {
|
|
@@ -208,6 +199,18 @@ function emitBounds(out, s, view, t, theme, strokes) {
|
|
|
208
199
|
});
|
|
209
200
|
}
|
|
210
201
|
}
|
|
202
|
+
function emitHighlight(out, s, ids, view, t, theme, strokes) {
|
|
203
|
+
const stroke = strokeOf(strokes.highlight, theme.highlight);
|
|
204
|
+
for (const b of s.bounds) {
|
|
205
|
+
if (!ids.has(b.id)) continue;
|
|
206
|
+
const [sx, sy] = worldToScreen(b.bounds.x, b.bounds.y, t);
|
|
207
|
+
out.push({
|
|
208
|
+
kind: "path",
|
|
209
|
+
path: rectPath$1(sx, sy, b.bounds.width * view.scale.x, b.bounds.height * view.scale.y),
|
|
210
|
+
stroke
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
211
214
|
function emitHandles(out, s, t, theme, strokes) {
|
|
212
215
|
const stroke = strokeOf(strokes.handle, theme.handle);
|
|
213
216
|
for (const h of s.handles) {
|
|
@@ -290,105 +293,6 @@ function emitIds(out, s, t, theme) {
|
|
|
290
293
|
}));
|
|
291
294
|
}
|
|
292
295
|
}
|
|
293
|
-
function emitLayersPanel(out, s, dims, theme) {
|
|
294
|
-
if (s.layers.length === 0) return;
|
|
295
|
-
const lineH = 14;
|
|
296
|
-
const padX = 6;
|
|
297
|
-
const lines = s.layers.map((l) => `[${l.index}] ${l.id} (${l.space})`);
|
|
298
|
-
const charW = 6.6;
|
|
299
|
-
let maxW = 0;
|
|
300
|
-
for (const line of lines) maxW = Math.max(maxW, line.length * charW);
|
|
301
|
-
const boxW = maxW + 12;
|
|
302
|
-
const boxH = lines.length * lineH + 8;
|
|
303
|
-
const x = dims.width - boxW - 8;
|
|
304
|
-
out.push({
|
|
305
|
-
kind: "path",
|
|
306
|
-
path: rectPath$1(x, 8, boxW, boxH),
|
|
307
|
-
fill: { paint: {
|
|
308
|
-
kind: "solid",
|
|
309
|
-
color: theme.layerTextBg
|
|
310
|
-
} }
|
|
311
|
-
});
|
|
312
|
-
for (let i = 0; i < lines.length; i++) out.push(textCommandFromRuns(x + padX, 12 + i * lineH, [{
|
|
313
|
-
text: lines[i],
|
|
314
|
-
fill: { paint: {
|
|
315
|
-
kind: "solid",
|
|
316
|
-
color: theme.layerText
|
|
317
|
-
} }
|
|
318
|
-
}], {
|
|
319
|
-
fontFamily: "ui-monospace, Menlo, monospace",
|
|
320
|
-
fontSize: 11
|
|
321
|
-
}));
|
|
322
|
-
}
|
|
323
|
-
var MONO = {
|
|
324
|
-
fontFamily: "ui-monospace, Menlo, monospace",
|
|
325
|
-
fontSize: 11
|
|
326
|
-
};
|
|
327
|
-
var MONO_CHAR_W = 6.6;
|
|
328
|
-
var LINE_H = 14;
|
|
329
|
-
/** A dark box holding monospace lines, at `(x, y)`; `y < 0` anchors its bottom
|
|
330
|
-
* that far above `bottom`. Width is estimated from the character count — there
|
|
331
|
-
* is no text measurer here, and a debug panel does not need one. */
|
|
332
|
-
function emitTextPanel(out, lines, x, y, color, bg) {
|
|
333
|
-
const padX = 6;
|
|
334
|
-
const padY = 4;
|
|
335
|
-
let maxLen = 0;
|
|
336
|
-
for (const l of lines) maxLen = Math.max(maxLen, l.length);
|
|
337
|
-
out.push({
|
|
338
|
-
kind: "path",
|
|
339
|
-
path: rectPath$1(x, y, maxLen * MONO_CHAR_W + 12, lines.length * LINE_H + 8),
|
|
340
|
-
fill: { paint: {
|
|
341
|
-
kind: "solid",
|
|
342
|
-
color: bg
|
|
343
|
-
} }
|
|
344
|
-
});
|
|
345
|
-
for (let i = 0; i < lines.length; i++) out.push(textCommandFromRuns(x + padX, y + padY + i * LINE_H, [{
|
|
346
|
-
text: lines[i],
|
|
347
|
-
fill: { paint: {
|
|
348
|
-
kind: "solid",
|
|
349
|
-
color
|
|
350
|
-
} }
|
|
351
|
-
}], MONO));
|
|
352
|
-
}
|
|
353
|
-
/** Fixed-width number, right-aligned, `decimals` places: `%{width}.{decimals}f`. */
|
|
354
|
-
function fixed(v, width, decimals) {
|
|
355
|
-
return v.toFixed(decimals).padStart(width);
|
|
356
|
-
}
|
|
357
|
-
function emitFramePanel(out, history, frame, theme) {
|
|
358
|
-
const span = history.length >= 2 ? history[history.length - 1] - history[0] : 0;
|
|
359
|
-
const interval = span > 0 ? span / (history.length - 1) : null;
|
|
360
|
-
const rows = [[
|
|
361
|
-
"fps",
|
|
362
|
-
null,
|
|
363
|
-
interval ? 1e3 / interval : null,
|
|
364
|
-
" "
|
|
365
|
-
], [
|
|
366
|
-
"frame",
|
|
367
|
-
null,
|
|
368
|
-
interval,
|
|
369
|
-
"ms"
|
|
370
|
-
]];
|
|
371
|
-
if (frame) {
|
|
372
|
-
rows.push([
|
|
373
|
-
"paint",
|
|
374
|
-
frame.drawCalls,
|
|
375
|
-
frame.paintMs,
|
|
376
|
-
"ms"
|
|
377
|
-
]);
|
|
378
|
-
for (const l of frame.layers) rows.push([
|
|
379
|
-
l.id,
|
|
380
|
-
l.drawCalls,
|
|
381
|
-
l.ms,
|
|
382
|
-
"ms"
|
|
383
|
-
]);
|
|
384
|
-
}
|
|
385
|
-
let labelW = 0;
|
|
386
|
-
for (const [label] of rows) labelW = Math.max(labelW, label.length);
|
|
387
|
-
const line = (label, count, value, unit) => `${label.padEnd(labelW)} ${count.padStart(5)} ${value.padStart(7)} ${unit}`;
|
|
388
|
-
const lines = rows.map(([label, count, value, unit]) => line(label, count === null ? "" : String(count), value === null ? "—" : fixed(value, 7, 2), unit));
|
|
389
|
-
if (frame) lines.splice(2, 0, line("", "draws", "cpu", " "));
|
|
390
|
-
emitTextPanel(out, lines, 8, 8, theme.fpsText, theme.fpsTextBg);
|
|
391
|
-
}
|
|
392
296
|
function emitViewport(out, rec, view, dims, theme, strokes) {
|
|
393
297
|
const t = viewToTransform(view);
|
|
394
298
|
const stroke = strokeOf(strokes.viewport, theme.viewport);
|
|
@@ -421,7 +325,8 @@ function emitViewport(out, rec, view, dims, theme, strokes) {
|
|
|
421
325
|
stroke: strokeOf({ width: strokes.viewport.width }, theme.viewport)
|
|
422
326
|
});
|
|
423
327
|
}
|
|
424
|
-
|
|
328
|
+
const text = rec.kind === "pan" ? `pan Δ ${signed((from.x - to.x) * to.scale.x)} ${signed((from.y - to.y) * to.scale.y)} px` : `zoom ×${(to.scale.x / from.scale.x).toFixed(3)} ${from.scale.x.toFixed(3)} → ${to.scale.x.toFixed(3)}`;
|
|
329
|
+
emitTextPanel(out, [text], 8, dims.height - LINE_H - 16, theme.viewport, theme.layerTextBg);
|
|
425
330
|
}
|
|
426
331
|
function signed(v) {
|
|
427
332
|
const r = Math.abs(v) < .05 ? 0 : v;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDebugOverlayLayer.js","names":["rectPath"],"sources":["../../src/debug/createDebugOverlayLayer.ts"],"sourcesContent":["import type { DrawCommand, PathDrawCommand } from '@weasel-js/renderer';\nimport type { Dims, RenderLayer } from 'core/layers/render';\nimport type { View } from 'core/viewport/view';\nimport { viewToTransform } from 'core/viewport/view';\nimport { worldToScreen } from 'core/viewport/viewTransform';\nimport { rotatePoint } from 'interactions/actions/rotate/geometry';\nimport { PATH_L, PATH_M, PATH_Z, type PolygonPath } from '@weasel-js/geom';\nimport { textCommandFromRuns } from '@weasel-js/renderer';\nimport type {\n DebugConfig,\n DebugSnapshot,\n DebugStroke,\n DebugStrokes,\n DebugTheme,\n FrameStats,\n RecordedViewport,\n} from './types';\nimport { DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME } from './defaultTheme';\n\n/** What `createDebugOverlayLayer` paints from: a sink to snapshot and the features to draw. */\nexport interface CreateDebugOverlayLayerOpts {\n sink: { snapshot(): DebugSnapshot };\n config: DebugConfig;\n}\n\nexport const DEBUG_OVERLAY_ID = 'debug-overlay';\nconst FPS_WINDOW = 60;\n\n/**\n * Screen-space `RenderLayer` that paints the sink's snapshot. Appended at\n * the top of the Canvas's layer stack when `debug` is enabled. World-space\n * coords in the snapshot are projected through `view` here, since the\n * layer itself runs at identity transform.\n */\nexport function createDebugOverlayLayer({\n sink,\n config,\n}: CreateDebugOverlayLayerOpts): RenderLayer<unknown> {\n // Timestamps of the last FPS_WINDOW draws, kept for the life of the layer.\n const fpsHistory: number[] = [];\n return {\n id: DEBUG_OVERLAY_ID,\n label: 'Debug overlay',\n space: 'screen',\n alwaysOn: true,\n draw: (_data, view, dims) => {\n if (config.fps) {\n fpsHistory.push(typeof performance !== 'undefined' ? performance.now() : Date.now());\n if (fpsHistory.length > FPS_WINDOW) fpsHistory.shift();\n } else if (fpsHistory.length > 0) {\n fpsHistory.length = 0;\n }\n return buildDebugOverlayCommands(sink.snapshot(), config, view, dims, fpsHistory);\n },\n };\n}\n\n/**\n * The debug overlay's draw commands for one snapshot, in screen space (CSS\n * pixels of a `dims`-sized canvas looking through `view`). What the overlay\n * layer paints each frame, and what `renderDebugSnapshot` rasterizes.\n *\n * `frameTimes` are `performance.now()` stamps of recent paints, oldest first;\n * the frame panel derives its rate from them and shows none without two.\n */\nexport function buildDebugOverlayCommands(\n snapshot: DebugSnapshot,\n config: DebugConfig,\n view: View,\n dims: Dims,\n frameTimes: readonly number[] = [],\n): DrawCommand[] {\n const theme: DebugTheme = { ...DEFAULT_DEBUG_THEME, ...(config.theme ?? {}) };\n const strokes: DebugStrokes = { ...DEFAULT_DEBUG_STROKES, ...(config.strokes ?? {}) };\n const s = snapshot;\n const t = viewToTransform(view);\n const out: DrawCommand[] = [];\n\n if (config.viewport && s.viewport) emitViewport(out, s.viewport, view, dims, theme, strokes);\n if (config.hitboxes) emitHitboxes(out, s, view, t, theme, strokes);\n if (config.bounds) emitBounds(out, s, view, t, theme, strokes);\n if (config.handles) emitHandles(out, s, t, theme, strokes);\n if (config.origins) emitOrigins(out, s, t, theme);\n if (config.snap) emitSnap(out, s, t, theme, strokes);\n if (config.ids) emitIds(out, s, t, theme);\n if (config.layers) emitLayersPanel(out, s, dims, theme);\n if (config.fps) emitFramePanel(out, frameTimes, s.frame, theme);\n return out;\n}\n\n// --- emitters (screen-space) ---\n\nfunction approxCircleScreen(cx: number, cy: number, r: number, segments = 24): PolygonPath {\n return approxEllipseScreen(cx, cy, r, r, segments);\n}\n\nfunction approxEllipseScreen(cx: number, cy: number, rx: number, ry: number, segments = 24): PolygonPath {\n // Commands: M + (segments-1) L + Z. Coords: (segments) × 2 — pairs for\n // the moveTo and the (segments-1) lineTos. PATH_Z consumes no coords.\n const cmds = new Uint8Array(segments + 1);\n const coords = new Float32Array(segments * 2);\n cmds[0] = PATH_M;\n coords[0] = cx + rx;\n coords[1] = cy;\n for (let i = 1; i < segments; i++) {\n cmds[i] = PATH_L;\n const theta = (i / segments) * Math.PI * 2;\n coords[i * 2] = cx + rx * Math.cos(theta);\n coords[i * 2 + 1] = cy + ry * Math.sin(theta);\n }\n cmds[segments] = PATH_Z;\n return { kind: 'polygon', commands: cmds, coords, fillRule: 'nonzero' };\n}\n\n/** A world rect turned `rotation` about its center, as the screen quad it\n * lands on. */\nfunction rotatedRectScreen(\n r: { x: number; y: number; width: number; height: number; rotation: number },\n t: ReturnType<typeof viewToTransform>,\n): PolygonPath {\n const cx = r.x + r.width / 2, cy = r.y + r.height / 2;\n const coords = new Float32Array(8);\n const corners = [[r.x, r.y], [r.x + r.width, r.y], [r.x + r.width, r.y + r.height], [r.x, r.y + r.height]];\n corners.forEach(([x, y], i) => {\n const w = rotatePoint(x, y, cx, cy, r.rotation);\n const [sx, sy] = worldToScreen(w.x, w.y, t);\n coords[i * 2] = sx;\n coords[i * 2 + 1] = sy;\n });\n return {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L, PATH_L, PATH_L, PATH_Z]),\n coords,\n fillRule: 'nonzero',\n };\n}\n\nfunction rectPath(x: number, y: number, w: number, h: number): { kind: 'rect'; x: number; y: number; width: number; height: number } {\n return { kind: 'rect', x, y, width: w, height: h };\n}\n\n/** A `DebugStroke` + color as the renderer's stroke shape. `dash` is dropped\n * when empty rather than passed through, so a solid line stays solid. */\nfunction strokeOf(s: DebugStroke, color: string) {\n return {\n paint: { kind: 'solid' as const, color },\n width: s.width,\n ...(s.dash && s.dash.length > 0 ? { dash: [...s.dash] } : {}),\n };\n}\n\nfunction emitHitboxes(\n out: DrawCommand[],\n s: DebugSnapshot,\n view: View,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const fill = { kind: 'solid' as const, color: theme.hitboxFill };\n const stroke = strokeOf(strokes.hitbox, theme.hitboxStroke);\n for (const h of s.hitboxes) {\n if (h.shape.kind === 'rect' && h.shape.rotation) {\n const path = rotatedRectScreen({ ...h.shape, rotation: h.shape.rotation }, t);\n out.push({ kind: 'path', path, fill: { paint: fill }, stroke });\n } else if (h.shape.kind === 'rect') {\n const [sx, sy] = worldToScreen(h.shape.x, h.shape.y, t);\n const sw = h.shape.width * view.scale.x;\n const sh = h.shape.height * view.scale.y;\n out.push({ kind: 'path', path: rectPath(sx, sy, sw, sh), fill: { paint: fill }, stroke });\n } else if (h.shape.kind === 'circle') {\n const [cx, cy] = worldToScreen(h.shape.cx, h.shape.cy, t);\n const rx = h.shape.r * Math.abs(view.scale.x);\n const ry = h.shape.r * Math.abs(view.scale.y);\n out.push({ kind: 'path', path: approxEllipseScreen(cx, cy, rx, ry), fill: { paint: fill }, stroke });\n } else if (h.shape.kind === 'polygon' && h.shape.points.length > 2) {\n const pts = h.shape.points;\n const coords = new Float32Array(pts.length * 2);\n pts.forEach((p, i) => {\n const [sx, sy] = worldToScreen(p.x, p.y, t);\n coords[i * 2] = sx;\n coords[i * 2 + 1] = sy;\n });\n const commands = new Uint8Array(pts.length + 1).fill(PATH_L);\n commands[0] = PATH_M;\n commands[pts.length] = PATH_Z;\n out.push({ kind: 'path', path: { kind: 'polygon', commands, coords, fillRule: 'nonzero' }, fill: { paint: fill }, stroke });\n }\n // 'path' kind: v1 punt — matches 2D behavior.\n }\n}\n\nfunction emitBounds(\n out: DrawCommand[],\n s: DebugSnapshot,\n view: View,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const stroke = strokeOf(strokes.bounds, theme.bounds);\n for (const b of s.bounds) {\n const [sx, sy] = worldToScreen(b.bounds.x, b.bounds.y, t);\n const sw = b.bounds.width * view.scale.x;\n const sh = b.bounds.height * view.scale.y;\n out.push({ kind: 'path', path: rectPath(sx, sy, sw, sh), stroke });\n }\n}\n\nfunction emitHandles(\n out: DrawCommand[],\n s: DebugSnapshot,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const stroke = strokeOf(strokes.handle, theme.handle);\n for (const h of s.handles) {\n const [cx, cy] = worldToScreen(h.position.x, h.position.y, t);\n const horiz: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([cx - 4, cy, cx + 4, cy]),\n fillRule: 'nonzero',\n };\n const vert: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([cx, cy - 4, cx, cy + 4]),\n fillRule: 'nonzero',\n };\n out.push({ kind: 'path', path: horiz, stroke });\n out.push({ kind: 'path', path: vert, stroke });\n }\n}\n\nfunction emitOrigins(\n out: DrawCommand[],\n s: DebugSnapshot,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n): void {\n const fill = { kind: 'solid' as const, color: theme.origin };\n for (const o of s.origins) {\n const [cx, cy] = worldToScreen(o.point.x, o.point.y, t);\n out.push({ kind: 'path', path: approxCircleScreen(cx, cy, 3), fill: { paint: fill } });\n }\n}\n\nfunction emitSnap(\n out: DrawCommand[],\n s: DebugSnapshot,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const color = theme.snap;\n for (const c of s.snap) {\n const [cx, cy] = worldToScreen(c.point.x, c.point.y, t);\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: approxCircleScreen(cx, cy, 4),\n ...(c.accepted\n ? { fill: { paint: { kind: 'solid' as const, color } } }\n : { stroke: strokeOf(strokes.snap, color) }),\n };\n out.push(cmd);\n }\n}\n\nfunction emitIds(\n out: DrawCommand[],\n s: DebugSnapshot,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n): void {\n // Pulls from the bounds stream — every consumer that records bounds\n // (selection overlay's handle math, the kit's per-node debug shim) gets\n // an id label for free.\n for (const b of s.bounds) {\n const [sx, sy] = worldToScreen(b.bounds.x, b.bounds.y, t);\n out.push(textCommandFromRuns(\n sx + 2,\n sy + 11,\n [{ text: b.id, fill: { paint: { kind: 'solid', color: theme.idText } } }],\n { fontFamily: 'ui-monospace, Menlo, monospace', fontSize: 10 },\n ));\n }\n}\n\nfunction emitLayersPanel(\n out: DrawCommand[],\n s: DebugSnapshot,\n dims: Dims,\n theme: DebugTheme,\n): void {\n if (s.layers.length === 0) return;\n const lineH = 14;\n const padX = 6;\n const padY = 4;\n const lines = s.layers.map((l) => `[${l.index}] ${l.id} (${l.space})`);\n // Approximate width: 11px font, monospaced — assume each glyph ≈6.6px.\n // 2D path uses ctx.measureText; we don't have a ctx here, so fall back\n // to a character-count estimate. Pixel-level accuracy is not load-bearing\n // for a debug panel; right-edge anchoring stays correct.\n const charW = 6.6;\n let maxW = 0;\n for (const line of lines) maxW = Math.max(maxW, line.length * charW);\n const boxW = maxW + padX * 2;\n const boxH = lines.length * lineH + padY * 2;\n const x = dims.width - boxW - 8;\n const y = 8;\n out.push({\n kind: 'path',\n path: rectPath(x, y, boxW, boxH),\n fill: { paint: { kind: 'solid', color: theme.layerTextBg } },\n });\n for (let i = 0; i < lines.length; i++) {\n out.push(textCommandFromRuns(\n x + padX,\n y + padY + i * lineH,\n [{ text: lines[i], fill: { paint: { kind: 'solid', color: theme.layerText } } }],\n { fontFamily: 'ui-monospace, Menlo, monospace', fontSize: 11 },\n ));\n }\n}\n\nconst MONO = { fontFamily: 'ui-monospace, Menlo, monospace', fontSize: 11 };\nconst MONO_CHAR_W = 6.6;\nconst LINE_H = 14;\n\n/** A dark box holding monospace lines, at `(x, y)`; `y < 0` anchors its bottom\n * that far above `bottom`. Width is estimated from the character count — there\n * is no text measurer here, and a debug panel does not need one. */\nfunction emitTextPanel(\n out: DrawCommand[],\n lines: readonly string[],\n x: number,\n y: number,\n color: string,\n bg: string,\n): void {\n const padX = 6;\n const padY = 4;\n let maxLen = 0;\n for (const l of lines) maxLen = Math.max(maxLen, l.length);\n out.push({\n kind: 'path',\n path: rectPath(x, y, maxLen * MONO_CHAR_W + padX * 2, lines.length * LINE_H + padY * 2),\n fill: { paint: { kind: 'solid', color: bg } },\n });\n for (let i = 0; i < lines.length; i++) {\n out.push(textCommandFromRuns(\n x + padX,\n y + padY + i * LINE_H,\n [{ text: lines[i], fill: { paint: { kind: 'solid', color } } }],\n MONO,\n ));\n }\n}\n\n/** Fixed-width number, right-aligned, `decimals` places: `%{width}.{decimals}f`. */\nfunction fixed(v: number, width: number, decimals: number): string {\n return v.toFixed(decimals).padStart(width);\n}\n\nfunction emitFramePanel(\n out: DrawCommand[],\n history: readonly number[],\n frame: FrameStats | null,\n theme: DebugTheme,\n): void {\n const span = history.length >= 2 ? history[history.length - 1] - history[0] : 0;\n const interval = span > 0 ? span / (history.length - 1) : null;\n // Columns: label, draw-call count, value, unit — every row the same width,\n // so decimals line up down the panel.\n const rows: [label: string, count: number | null, value: number | null, unit: string][] = [\n ['fps', null, interval ? 1000 / interval : null, ' '],\n ['frame', null, interval, 'ms'],\n ];\n if (frame) {\n rows.push(['paint', frame.drawCalls, frame.paintMs, 'ms']);\n for (const l of frame.layers) rows.push([l.id, l.drawCalls, l.ms, 'ms']);\n }\n let labelW = 0;\n for (const [label] of rows) labelW = Math.max(labelW, label.length);\n const line = (label: string, count: string, value: string, unit: string) =>\n `${label.padEnd(labelW)} ${count.padStart(5)} ${value.padStart(7)} ${unit}`;\n const lines = rows.map(([label, count, value, unit]) =>\n line(label, count === null ? '' : String(count), value === null ? '—' : fixed(value, 7, 2), unit));\n if (frame) lines.splice(2, 0, line('', 'draws', 'cpu', ' '));\n emitTextPanel(out, lines, 8, 8, theme.fpsText, theme.fpsTextBg);\n}\n\nfunction emitViewport(\n out: DrawCommand[],\n rec: RecordedViewport,\n view: View,\n dims: Dims,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const t = viewToTransform(view);\n const stroke = strokeOf(strokes.viewport, theme.viewport);\n // Where the viewport the gesture started from sits in the current camera.\n const { from, to } = rec;\n const [fx, fy] = worldToScreen(from.x, from.y, t);\n out.push({\n kind: 'path',\n path: rectPath(fx, fy, (dims.width / from.scale.x) * view.scale.x, (dims.height / from.scale.y) * view.scale.y),\n stroke,\n });\n if (rec.anchor) {\n const [ax0, ay0] = worldToScreen(rec.anchor.x, rec.anchor.y, viewToTransform(from));\n const [ax1, ay1] = worldToScreen(rec.anchor.x, rec.anchor.y, t);\n out.push({ kind: 'path', path: approxCircleScreen(ax0, ay0, 2.5), fill: { paint: { kind: 'solid', color: theme.viewport } } });\n if (Math.hypot(ax1 - ax0, ay1 - ay0) > 0.5) {\n out.push({ kind: 'path', path: segment(ax0, ay0, ax1, ay1), stroke });\n }\n out.push({ kind: 'path', path: approxCircleScreen(ax1, ay1, 6), stroke: strokeOf({ width: strokes.viewport.width }, theme.viewport) });\n }\n const text = rec.kind === 'pan'\n ? `pan Δ ${signed((from.x - to.x) * to.scale.x)} ${signed((from.y - to.y) * to.scale.y)} px`\n : `zoom ×${(to.scale.x / from.scale.x).toFixed(3)} ${from.scale.x.toFixed(3)} → ${to.scale.x.toFixed(3)}`;\n emitTextPanel(out, [text], 8, dims.height - LINE_H - 16, theme.viewport, theme.layerTextBg);\n}\n\nfunction signed(v: number): string {\n const r = Math.abs(v) < 0.05 ? 0 : v;\n return `${r >= 0 ? '+' : '-'}${Math.abs(r).toFixed(1)}`.padStart(8);\n}\n\nfunction segment(x0: number, y0: number, x1: number, y1: number): PolygonPath {\n return {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([x0, y0, x1, y1]),\n fillRule: 'nonzero',\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createDebugOverlayLayer.js","names":["rectPath"],"sources":["../../src/debug/createDebugOverlayLayer.ts"],"sourcesContent":["import type { DrawCommand, PathDrawCommand } from '@weasel-js/renderer';\nimport type { Dims, RenderLayer } from 'core/layers/render';\nimport type { View } from 'core/viewport/view';\nimport { viewToTransform } from 'core/viewport/view';\nimport { worldToScreen } from 'core/viewport/viewTransform';\nimport { rotatePoint } from 'interactions/actions/rotate/geometry';\nimport { PATH_L, PATH_M, PATH_Z, type PolygonPath } from '@weasel-js/geom';\nimport { textCommandFromRuns } from '@weasel-js/renderer';\nimport type {\n DebugConfig,\n DebugSnapshot,\n DebugStroke,\n DebugStrokes,\n DebugTheme,\n RecordedViewport,\n} from './types';\nimport { DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME } from './defaultTheme';\nimport { emitFramePanel, emitLayersPanel, emitTextPanel, LINE_H, rectPath } from './overlayPanels';\n\n/** What `createDebugOverlayLayer` paints from: a sink to snapshot and the features to draw. */\nexport interface CreateDebugOverlayLayerOpts {\n sink: { snapshot(): DebugSnapshot };\n config: DebugConfig;\n}\n\nexport const DEBUG_OVERLAY_ID = 'debug-overlay';\nconst FPS_WINDOW = 60;\n\n/**\n * Screen-space `RenderLayer` that paints the sink's snapshot. Appended at\n * the top of the Canvas's layer stack when `debug` is enabled. World-space\n * coords in the snapshot are projected through `view` here, since the\n * layer itself runs at identity transform.\n */\nexport function createDebugOverlayLayer({\n sink,\n config,\n}: CreateDebugOverlayLayerOpts): RenderLayer<unknown> {\n // Timestamps of the last FPS_WINDOW draws, kept for the life of the layer.\n const fpsHistory: number[] = [];\n return {\n id: DEBUG_OVERLAY_ID,\n label: 'Debug overlay',\n space: 'screen',\n alwaysOn: true,\n draw: (_data, view, dims) => {\n if (config.fps) {\n fpsHistory.push(typeof performance !== 'undefined' ? performance.now() : Date.now());\n if (fpsHistory.length > FPS_WINDOW) fpsHistory.shift();\n } else if (fpsHistory.length > 0) {\n fpsHistory.length = 0;\n }\n return buildDebugOverlayCommands(sink.snapshot(), config, view, dims, fpsHistory);\n },\n };\n}\n\n/**\n * The debug overlay's draw commands for one snapshot, in screen space (CSS\n * pixels of a `dims`-sized canvas looking through `view`). What the overlay\n * layer paints each frame, and what `renderDebugSnapshot` rasterizes.\n *\n * `frameTimes` are `performance.now()` stamps of recent paints, oldest first;\n * the frame panel derives its rate from them and shows none without two.\n */\nexport function buildDebugOverlayCommands(\n snapshot: DebugSnapshot,\n config: DebugConfig,\n view: View,\n dims: Dims,\n frameTimes: readonly number[] = [],\n): DrawCommand[] {\n const theme: DebugTheme = { ...DEFAULT_DEBUG_THEME, ...(config.theme ?? {}) };\n const strokes: DebugStrokes = { ...DEFAULT_DEBUG_STROKES, ...(config.strokes ?? {}) };\n const s = snapshot;\n const t = viewToTransform(view);\n const out: DrawCommand[] = [];\n\n if (config.viewport && s.viewport) emitViewport(out, s.viewport, view, dims, theme, strokes);\n if (config.hitboxes) emitHitboxes(out, s, view, t, theme, strokes);\n if (config.bounds) emitBounds(out, s, view, t, theme, strokes);\n if (config.highlight?.length) emitHighlight(out, s, new Set(config.highlight), view, t, theme, strokes);\n if (config.handles) emitHandles(out, s, t, theme, strokes);\n if (config.origins) emitOrigins(out, s, t, theme);\n if (config.snap) emitSnap(out, s, t, theme, strokes);\n if (config.ids) emitIds(out, s, t, theme);\n if (config.layers) emitLayersPanel(out, s, dims, theme);\n if (config.fps) emitFramePanel(out, frameTimes, s.frame, theme);\n return out;\n}\n\n// --- emitters (screen-space) ---\n\nfunction approxCircleScreen(cx: number, cy: number, r: number, segments = 24): PolygonPath {\n return approxEllipseScreen(cx, cy, r, r, segments);\n}\n\nfunction approxEllipseScreen(cx: number, cy: number, rx: number, ry: number, segments = 24): PolygonPath {\n // Commands: M + (segments-1) L + Z. Coords: (segments) × 2 — pairs for\n // the moveTo and the (segments-1) lineTos. PATH_Z consumes no coords.\n const cmds = new Uint8Array(segments + 1);\n const coords = new Float32Array(segments * 2);\n cmds[0] = PATH_M;\n coords[0] = cx + rx;\n coords[1] = cy;\n for (let i = 1; i < segments; i++) {\n cmds[i] = PATH_L;\n const theta = (i / segments) * Math.PI * 2;\n coords[i * 2] = cx + rx * Math.cos(theta);\n coords[i * 2 + 1] = cy + ry * Math.sin(theta);\n }\n cmds[segments] = PATH_Z;\n return { kind: 'polygon', commands: cmds, coords, fillRule: 'nonzero' };\n}\n\n/** A world rect turned `rotation` about its center, as the screen quad it\n * lands on. */\nfunction rotatedRectScreen(\n r: { x: number; y: number; width: number; height: number; rotation: number },\n t: ReturnType<typeof viewToTransform>,\n): PolygonPath {\n const cx = r.x + r.width / 2, cy = r.y + r.height / 2;\n const coords = new Float32Array(8);\n const corners = [[r.x, r.y], [r.x + r.width, r.y], [r.x + r.width, r.y + r.height], [r.x, r.y + r.height]];\n corners.forEach(([x, y], i) => {\n const w = rotatePoint(x, y, cx, cy, r.rotation);\n const [sx, sy] = worldToScreen(w.x, w.y, t);\n coords[i * 2] = sx;\n coords[i * 2 + 1] = sy;\n });\n return {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L, PATH_L, PATH_L, PATH_Z]),\n coords,\n fillRule: 'nonzero',\n };\n}\n\nfunction strokeOf(s: DebugStroke, color: string) {\n return {\n paint: { kind: 'solid' as const, color },\n width: s.width,\n ...(s.dash && s.dash.length > 0 ? { dash: [...s.dash] } : {}),\n };\n}\n\nfunction emitHitboxes(\n out: DrawCommand[],\n s: DebugSnapshot,\n view: View,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const fill = { kind: 'solid' as const, color: theme.hitboxFill };\n const stroke = strokeOf(strokes.hitbox, theme.hitboxStroke);\n for (const h of s.hitboxes) {\n if (h.shape.kind === 'rect' && h.shape.rotation) {\n const path = rotatedRectScreen({ ...h.shape, rotation: h.shape.rotation }, t);\n out.push({ kind: 'path', path, fill: { paint: fill }, stroke });\n } else if (h.shape.kind === 'rect') {\n const [sx, sy] = worldToScreen(h.shape.x, h.shape.y, t);\n const sw = h.shape.width * view.scale.x;\n const sh = h.shape.height * view.scale.y;\n out.push({ kind: 'path', path: rectPath(sx, sy, sw, sh), fill: { paint: fill }, stroke });\n } else if (h.shape.kind === 'circle') {\n const [cx, cy] = worldToScreen(h.shape.cx, h.shape.cy, t);\n const rx = h.shape.r * Math.abs(view.scale.x);\n const ry = h.shape.r * Math.abs(view.scale.y);\n out.push({ kind: 'path', path: approxEllipseScreen(cx, cy, rx, ry), fill: { paint: fill }, stroke });\n } else if (h.shape.kind === 'polygon' && h.shape.points.length > 2) {\n const pts = h.shape.points;\n const coords = new Float32Array(pts.length * 2);\n pts.forEach((p, i) => {\n const [sx, sy] = worldToScreen(p.x, p.y, t);\n coords[i * 2] = sx;\n coords[i * 2 + 1] = sy;\n });\n const commands = new Uint8Array(pts.length + 1).fill(PATH_L);\n commands[0] = PATH_M;\n commands[pts.length] = PATH_Z;\n out.push({ kind: 'path', path: { kind: 'polygon', commands, coords, fillRule: 'nonzero' }, fill: { paint: fill }, stroke });\n }\n // 'path' kind: v1 punt — matches 2D behavior.\n }\n}\n\nfunction emitBounds(\n out: DrawCommand[],\n s: DebugSnapshot,\n view: View,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const stroke = strokeOf(strokes.bounds, theme.bounds);\n for (const b of s.bounds) {\n const [sx, sy] = worldToScreen(b.bounds.x, b.bounds.y, t);\n const sw = b.bounds.width * view.scale.x;\n const sh = b.bounds.height * view.scale.y;\n out.push({ kind: 'path', path: rectPath(sx, sy, sw, sh), stroke });\n }\n}\n\nfunction emitHighlight(\n out: DrawCommand[],\n s: DebugSnapshot,\n ids: ReadonlySet<string>,\n view: View,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const stroke = strokeOf(strokes.highlight, theme.highlight);\n for (const b of s.bounds) {\n if (!ids.has(b.id)) continue;\n const [sx, sy] = worldToScreen(b.bounds.x, b.bounds.y, t);\n out.push({ kind: 'path', path: rectPath(sx, sy, b.bounds.width * view.scale.x, b.bounds.height * view.scale.y), stroke });\n }\n}\n\nfunction emitHandles(\n out: DrawCommand[],\n s: DebugSnapshot,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const stroke = strokeOf(strokes.handle, theme.handle);\n for (const h of s.handles) {\n const [cx, cy] = worldToScreen(h.position.x, h.position.y, t);\n const horiz: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([cx - 4, cy, cx + 4, cy]),\n fillRule: 'nonzero',\n };\n const vert: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([cx, cy - 4, cx, cy + 4]),\n fillRule: 'nonzero',\n };\n out.push({ kind: 'path', path: horiz, stroke });\n out.push({ kind: 'path', path: vert, stroke });\n }\n}\n\nfunction emitOrigins(\n out: DrawCommand[],\n s: DebugSnapshot,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n): void {\n const fill = { kind: 'solid' as const, color: theme.origin };\n for (const o of s.origins) {\n const [cx, cy] = worldToScreen(o.point.x, o.point.y, t);\n out.push({ kind: 'path', path: approxCircleScreen(cx, cy, 3), fill: { paint: fill } });\n }\n}\n\nfunction emitSnap(\n out: DrawCommand[],\n s: DebugSnapshot,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const color = theme.snap;\n for (const c of s.snap) {\n const [cx, cy] = worldToScreen(c.point.x, c.point.y, t);\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: approxCircleScreen(cx, cy, 4),\n ...(c.accepted\n ? { fill: { paint: { kind: 'solid' as const, color } } }\n : { stroke: strokeOf(strokes.snap, color) }),\n };\n out.push(cmd);\n }\n}\n\nfunction emitIds(\n out: DrawCommand[],\n s: DebugSnapshot,\n t: ReturnType<typeof viewToTransform>,\n theme: DebugTheme,\n): void {\n // Pulls from the bounds stream — every consumer that records bounds\n // (selection overlay's handle math, the kit's per-node debug shim) gets\n // an id label for free.\n for (const b of s.bounds) {\n const [sx, sy] = worldToScreen(b.bounds.x, b.bounds.y, t);\n out.push(textCommandFromRuns(\n sx + 2,\n sy + 11,\n [{ text: b.id, fill: { paint: { kind: 'solid', color: theme.idText } } }],\n { fontFamily: 'ui-monospace, Menlo, monospace', fontSize: 10 },\n ));\n }\n}\n\nfunction emitViewport(\n out: DrawCommand[],\n rec: RecordedViewport,\n view: View,\n dims: Dims,\n theme: DebugTheme,\n strokes: DebugStrokes,\n): void {\n const t = viewToTransform(view);\n const stroke = strokeOf(strokes.viewport, theme.viewport);\n // Where the viewport the gesture started from sits in the current camera.\n const { from, to } = rec;\n const [fx, fy] = worldToScreen(from.x, from.y, t);\n out.push({\n kind: 'path',\n path: rectPath(fx, fy, (dims.width / from.scale.x) * view.scale.x, (dims.height / from.scale.y) * view.scale.y),\n stroke,\n });\n if (rec.anchor) {\n const [ax0, ay0] = worldToScreen(rec.anchor.x, rec.anchor.y, viewToTransform(from));\n const [ax1, ay1] = worldToScreen(rec.anchor.x, rec.anchor.y, t);\n out.push({ kind: 'path', path: approxCircleScreen(ax0, ay0, 2.5), fill: { paint: { kind: 'solid', color: theme.viewport } } });\n if (Math.hypot(ax1 - ax0, ay1 - ay0) > 0.5) {\n out.push({ kind: 'path', path: segment(ax0, ay0, ax1, ay1), stroke });\n }\n out.push({ kind: 'path', path: approxCircleScreen(ax1, ay1, 6), stroke: strokeOf({ width: strokes.viewport.width }, theme.viewport) });\n }\n const text = rec.kind === 'pan'\n ? `pan Δ ${signed((from.x - to.x) * to.scale.x)} ${signed((from.y - to.y) * to.scale.y)} px`\n : `zoom ×${(to.scale.x / from.scale.x).toFixed(3)} ${from.scale.x.toFixed(3)} → ${to.scale.x.toFixed(3)}`;\n emitTextPanel(out, [text], 8, dims.height - LINE_H - 16, theme.viewport, theme.layerTextBg);\n}\n\nfunction signed(v: number): string {\n const r = Math.abs(v) < 0.05 ? 0 : v;\n return `${r >= 0 ? '+' : '-'}${Math.abs(r).toFixed(1)}`.padStart(8);\n}\n\nfunction segment(x0: number, y0: number, x1: number, y1: number): PolygonPath {\n return {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([x0, y0, x1, y1]),\n fillRule: 'nonzero',\n };\n}\n"],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ function createDebugSink(config) {
|
|
|
19
19
|
viewport: null,
|
|
20
20
|
frame: null
|
|
21
21
|
};
|
|
22
|
+
const highlighted = new Set(config.highlight ?? []);
|
|
22
23
|
return {
|
|
23
24
|
recordHitbox(id, kind, shape) {
|
|
24
25
|
if (!config.hitboxes) return;
|
|
@@ -37,7 +38,7 @@ function createDebugSink(config) {
|
|
|
37
38
|
});
|
|
38
39
|
},
|
|
39
40
|
recordBounds(id, bounds) {
|
|
40
|
-
if (!config.bounds) return;
|
|
41
|
+
if (!config.bounds && !highlighted.has(id)) return;
|
|
41
42
|
snap.bounds.push({
|
|
42
43
|
id,
|
|
43
44
|
bounds
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDebugSink.js","names":[],"sources":["../../src/debug/createDebugSink.ts"],"sourcesContent":["import type {\n CanvasDebugSink,\n DebugConfig,\n DebugSnapshot,\n HandleKind,\n HitShape,\n} from './types';\n\n/**\n * Build a sink that stores recorded primitives in arrays keyed by feature.\n * A `recordX` call no-ops when its flag in `config` is off, so callers can\n * record unconditionally.\n *\n * `beginFrame()` clears every per-frame array. Snap, the latest viewport\n * record, and the last frame's stats survive across frames. `snapshot()`\n * returns live references — no copy.\n */\nexport function createDebugSink(config: DebugConfig): CanvasDebugSink {\n const snap: DebugSnapshot = {\n hitboxes: [],\n handles: [],\n bounds: [],\n origins: [],\n snap: [],\n layers: [],\n viewport: null,\n frame: null,\n };\n return {\n recordHitbox(id, kind, shape: HitShape) {\n if (!config.hitboxes) return;\n snap.hitboxes.push({ id, kind, shape });\n },\n recordHandle(id, position, kind: HandleKind) {\n if (!config.handles) return;\n snap.handles.push({ id, position, kind });\n },\n recordBounds(id, bounds) {\n if (!config.bounds) return;\n snap.bounds.push({ id, bounds });\n },\n recordOrigin(id, point) {\n if (!config.origins) return;\n snap.origins.push({ id, point });\n },\n recordSnapCandidate(point, accepted) {\n if (!config.snap) return;\n snap.snap.push({ point, accepted });\n },\n recordLayer(id, label, space, index) {\n if (!config.layers) return;\n snap.layers.push({ id, label, space, index });\n },\n recordViewport(kind, from, to, anchor) {\n if (!config.viewport) return;\n snap.viewport = anchor ? { kind, from, to, anchor } : { kind, from, to };\n },\n recordFrame(stats) {\n if (!config.fps) return;\n snap.frame = stats;\n },\n beginFrame() {\n snap.hitboxes.length = 0;\n snap.handles.length = 0;\n snap.bounds.length = 0;\n snap.origins.length = 0;\n snap.layers.length = 0;\n },\n clearSnap() {\n snap.snap.length = 0;\n },\n snapshot() {\n return snap;\n },\n };\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,gBAAgB,QAAsC;CACpE,MAAM,OAAsB;EAC1B,UAAU,CAAC;EACX,SAAS,CAAC;EACV,QAAQ,CAAC;EACT,SAAS,CAAC;EACV,MAAM,CAAC;EACP,QAAQ,CAAC;EACT,UAAU;EACV,OAAO;CACT;CACA,OAAO;EACL,aAAa,IAAI,MAAM,OAAiB;GACtC,IAAI,CAAC,OAAO,UAAU;GACtB,KAAK,SAAS,KAAK;IAAE;IAAI;IAAM;GAAM,CAAC;EACxC;EACA,aAAa,IAAI,UAAU,MAAkB;GAC3C,IAAI,CAAC,OAAO,SAAS;GACrB,KAAK,QAAQ,KAAK;IAAE;IAAI;IAAU;GAAK,CAAC;EAC1C;EACA,aAAa,IAAI,QAAQ;GACvB,IAAI,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"createDebugSink.js","names":[],"sources":["../../src/debug/createDebugSink.ts"],"sourcesContent":["import type {\n CanvasDebugSink,\n DebugConfig,\n DebugSnapshot,\n HandleKind,\n HitShape,\n} from './types';\n\n/**\n * Build a sink that stores recorded primitives in arrays keyed by feature.\n * A `recordX` call no-ops when its flag in `config` is off, so callers can\n * record unconditionally.\n *\n * `beginFrame()` clears every per-frame array. Snap, the latest viewport\n * record, and the last frame's stats survive across frames. `snapshot()`\n * returns live references — no copy.\n */\nexport function createDebugSink(config: DebugConfig): CanvasDebugSink {\n const snap: DebugSnapshot = {\n hitboxes: [],\n handles: [],\n bounds: [],\n origins: [],\n snap: [],\n layers: [],\n viewport: null,\n frame: null,\n };\n const highlighted = new Set(config.highlight ?? []);\n return {\n recordHitbox(id, kind, shape: HitShape) {\n if (!config.hitboxes) return;\n snap.hitboxes.push({ id, kind, shape });\n },\n recordHandle(id, position, kind: HandleKind) {\n if (!config.handles) return;\n snap.handles.push({ id, position, kind });\n },\n recordBounds(id, bounds) {\n if (!config.bounds && !highlighted.has(id)) return;\n snap.bounds.push({ id, bounds });\n },\n recordOrigin(id, point) {\n if (!config.origins) return;\n snap.origins.push({ id, point });\n },\n recordSnapCandidate(point, accepted) {\n if (!config.snap) return;\n snap.snap.push({ point, accepted });\n },\n recordLayer(id, label, space, index) {\n if (!config.layers) return;\n snap.layers.push({ id, label, space, index });\n },\n recordViewport(kind, from, to, anchor) {\n if (!config.viewport) return;\n snap.viewport = anchor ? { kind, from, to, anchor } : { kind, from, to };\n },\n recordFrame(stats) {\n if (!config.fps) return;\n snap.frame = stats;\n },\n beginFrame() {\n snap.hitboxes.length = 0;\n snap.handles.length = 0;\n snap.bounds.length = 0;\n snap.origins.length = 0;\n snap.layers.length = 0;\n },\n clearSnap() {\n snap.snap.length = 0;\n },\n snapshot() {\n return snap;\n },\n };\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,gBAAgB,QAAsC;CACpE,MAAM,OAAsB;EAC1B,UAAU,CAAC;EACX,SAAS,CAAC;EACV,QAAQ,CAAC;EACT,SAAS,CAAC;EACV,MAAM,CAAC;EACP,QAAQ,CAAC;EACT,UAAU;EACV,OAAO;CACT;CACA,MAAM,cAAc,IAAI,IAAI,OAAO,aAAa,CAAC,CAAC;CAClD,OAAO;EACL,aAAa,IAAI,MAAM,OAAiB;GACtC,IAAI,CAAC,OAAO,UAAU;GACtB,KAAK,SAAS,KAAK;IAAE;IAAI;IAAM;GAAM,CAAC;EACxC;EACA,aAAa,IAAI,UAAU,MAAkB;GAC3C,IAAI,CAAC,OAAO,SAAS;GACrB,KAAK,QAAQ,KAAK;IAAE;IAAI;IAAU;GAAK,CAAC;EAC1C;EACA,aAAa,IAAI,QAAQ;GACvB,IAAI,CAAC,OAAO,UAAU,CAAC,YAAY,IAAI,EAAE,GAAG;GAC5C,KAAK,OAAO,KAAK;IAAE;IAAI;GAAO,CAAC;EACjC;EACA,aAAa,IAAI,OAAO;GACtB,IAAI,CAAC,OAAO,SAAS;GACrB,KAAK,QAAQ,KAAK;IAAE;IAAI;GAAM,CAAC;EACjC;EACA,oBAAoB,OAAO,UAAU;GACnC,IAAI,CAAC,OAAO,MAAM;GAClB,KAAK,KAAK,KAAK;IAAE;IAAO;GAAS,CAAC;EACpC;EACA,YAAY,IAAI,OAAO,OAAO,OAAO;GACnC,IAAI,CAAC,OAAO,QAAQ;GACpB,KAAK,OAAO,KAAK;IAAE;IAAI;IAAO;IAAO;GAAM,CAAC;EAC9C;EACA,eAAe,MAAM,MAAM,IAAI,QAAQ;GACrC,IAAI,CAAC,OAAO,UAAU;GACtB,KAAK,WAAW,SAAS;IAAE;IAAM;IAAM;IAAI;GAAO,IAAI;IAAE;IAAM;IAAM;GAAG;EACzE;EACA,YAAY,OAAO;GACjB,IAAI,CAAC,OAAO,KAAK;GACjB,KAAK,QAAQ;EACf;EACA,aAAa;GACX,KAAK,SAAS,SAAS;GACvB,KAAK,QAAQ,SAAS;GACtB,KAAK,OAAO,SAAS;GACrB,KAAK,QAAQ,SAAS;GACtB,KAAK,OAAO,SAAS;EACvB;EACA,YAAY;GACV,KAAK,KAAK,SAAS;EACrB;EACA,WAAW;GACT,OAAO;EACT;CACF;AACF"}
|
|
@@ -16,7 +16,8 @@ var DEFAULT_DEBUG_THEME = {
|
|
|
16
16
|
idText: "#ffeb3b",
|
|
17
17
|
fpsText: "#e0e0e0",
|
|
18
18
|
fpsTextBg: "rgba(0, 0, 0, 0.6)",
|
|
19
|
-
viewport: "#b388ff"
|
|
19
|
+
viewport: "#b388ff",
|
|
20
|
+
highlight: "#ff4081"
|
|
20
21
|
};
|
|
21
22
|
/**
|
|
22
23
|
* Default line widths and dashes. Hairline everywhere so the overlay never
|
|
@@ -35,7 +36,8 @@ var DEFAULT_DEBUG_STROKES = {
|
|
|
35
36
|
viewport: {
|
|
36
37
|
width: 1,
|
|
37
38
|
dash: [6, 4]
|
|
38
|
-
}
|
|
39
|
+
},
|
|
40
|
+
highlight: { width: 2 }
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultTheme.js","names":[],"sources":["../../src/debug/defaultTheme.ts"],"sourcesContent":["import type { DebugStrokes, DebugTheme } from './types';\n\n/**\n * Default colors per the spec's Visual Style section. High contrast against\n * the demo's dark backdrop. Override by passing `theme: { ... }` on\n * `DebugConfig`.\n */\nexport const DEFAULT_DEBUG_THEME: DebugTheme = {\n hitboxFill: 'rgba(255, 0, 255, 0.25)',\n hitboxStroke: '#ff00ff',\n handle: '#00e5ff',\n bounds: '#ffeb3b',\n origin: '#69f0ae',\n snap: '#ffa726',\n layerText: '#e0e0e0',\n layerTextBg: 'rgba(0, 0, 0, 0.6)',\n idText: '#ffeb3b',\n fpsText: '#e0e0e0',\n fpsTextBg: 'rgba(0, 0, 0, 0.6)',\n viewport: '#b388ff',\n};\n\n/**\n * Default line widths and dashes. Hairline everywhere so the overlay never\n * hides the geometry it is describing; the dash on hitboxes is what\n * distinguishes them from the solid bounds box at the same rect.\n * Override by passing `strokes: { ... }` on `DebugConfig`.\n */\nexport const DEFAULT_DEBUG_STROKES: DebugStrokes = {\n hitbox: { width: 1, dash: [2, 2] },\n bounds: { width: 1 },\n handle: { width: 1 },\n snap: { width: 1 },\n viewport: { width: 1, dash: [6, 4] },\n};\n"],"mappings":";;;;;;AAOA,IAAa,sBAAkC;CAC7C,YAAY;CACZ,cAAc;CACd,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,WAAW;CACX,aAAa;CACb,QAAQ;CACR,SAAS;CACT,WAAW;CACX,UAAU;
|
|
1
|
+
{"version":3,"file":"defaultTheme.js","names":[],"sources":["../../src/debug/defaultTheme.ts"],"sourcesContent":["import type { DebugStrokes, DebugTheme } from './types';\n\n/**\n * Default colors per the spec's Visual Style section. High contrast against\n * the demo's dark backdrop. Override by passing `theme: { ... }` on\n * `DebugConfig`.\n */\nexport const DEFAULT_DEBUG_THEME: DebugTheme = {\n hitboxFill: 'rgba(255, 0, 255, 0.25)',\n hitboxStroke: '#ff00ff',\n handle: '#00e5ff',\n bounds: '#ffeb3b',\n origin: '#69f0ae',\n snap: '#ffa726',\n layerText: '#e0e0e0',\n layerTextBg: 'rgba(0, 0, 0, 0.6)',\n idText: '#ffeb3b',\n fpsText: '#e0e0e0',\n fpsTextBg: 'rgba(0, 0, 0, 0.6)',\n viewport: '#b388ff',\n highlight: '#ff4081',\n};\n\n/**\n * Default line widths and dashes. Hairline everywhere so the overlay never\n * hides the geometry it is describing; the dash on hitboxes is what\n * distinguishes them from the solid bounds box at the same rect.\n * Override by passing `strokes: { ... }` on `DebugConfig`.\n */\nexport const DEFAULT_DEBUG_STROKES: DebugStrokes = {\n hitbox: { width: 1, dash: [2, 2] },\n bounds: { width: 1 },\n handle: { width: 1 },\n snap: { width: 1 },\n viewport: { width: 1, dash: [6, 4] },\n highlight: { width: 2 },\n};\n"],"mappings":";;;;;;AAOA,IAAa,sBAAkC;CAC7C,YAAY;CACZ,cAAc;CACd,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,WAAW;CACX,aAAa;CACb,QAAQ;CACR,SAAS;CACT,WAAW;CACX,UAAU;CACV,WAAW;AACb;;;;;;;AAQA,IAAa,wBAAsC;CACjD,QAAQ;EAAE,OAAO;EAAG,MAAM,CAAC,GAAG,CAAC;CAAE;CACjC,QAAQ,EAAE,OAAO,EAAE;CACnB,QAAQ,EAAE,OAAO,EAAE;CACnB,MAAM,EAAE,OAAO,EAAE;CACjB,UAAU;EAAE,OAAO;EAAG,MAAM,CAAC,GAAG,CAAC;CAAE;CACnC,WAAW,EAAE,OAAO,EAAE;AACxB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/debug/features.ts
|
|
2
|
+
/** Every debug-overlay feature a `DebugConfig` flag turns on, in the order a list of them shows. */
|
|
3
|
+
var DEBUG_FEATURES = [
|
|
4
|
+
"hitboxes",
|
|
5
|
+
"handles",
|
|
6
|
+
"bounds",
|
|
7
|
+
"origins",
|
|
8
|
+
"snap",
|
|
9
|
+
"layers",
|
|
10
|
+
"ids",
|
|
11
|
+
"fps",
|
|
12
|
+
"viewport"
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { DEBUG_FEATURES };
|
|
17
|
+
//# sourceMappingURL=features.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features.js","names":[],"sources":["../../src/debug/features.ts"],"sourcesContent":["/** Every debug-overlay feature a `DebugConfig` flag turns on, in the order a list of them shows. */\nexport const DEBUG_FEATURES = [\n 'hitboxes', 'handles', 'bounds', 'origins', 'snap', 'layers', 'ids', 'fps', 'viewport',\n] as const;\n"],"mappings":";;AACA,IAAa,iBAAiB;CAC5B;CAAY;CAAW;CAAU;CAAW;CAAQ;CAAU;CAAO;CAAO;AAC9E"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { textCommandFromRuns } from "@weasel-js/renderer";
|
|
2
|
+
|
|
3
|
+
//#region src/debug/overlayPanels.ts
|
|
4
|
+
function rectPath(x, y, w, h) {
|
|
5
|
+
return {
|
|
6
|
+
kind: "rect",
|
|
7
|
+
x,
|
|
8
|
+
y,
|
|
9
|
+
width: w,
|
|
10
|
+
height: h
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/** A `DebugStroke` + color as the renderer's stroke shape. `dash` is dropped
|
|
14
|
+
* when empty rather than passed through, so a solid line stays solid. */
|
|
15
|
+
function emitLayersPanel(out, s, dims, theme) {
|
|
16
|
+
if (s.layers.length === 0) return;
|
|
17
|
+
const lineH = 14;
|
|
18
|
+
const padX = 6;
|
|
19
|
+
const lines = s.layers.map((l) => `[${l.index}] ${l.id} (${l.space})`);
|
|
20
|
+
const charW = 6.6;
|
|
21
|
+
let maxW = 0;
|
|
22
|
+
for (const line of lines) maxW = Math.max(maxW, line.length * charW);
|
|
23
|
+
const boxW = maxW + 12;
|
|
24
|
+
const boxH = lines.length * lineH + 8;
|
|
25
|
+
const x = dims.width - boxW - 8;
|
|
26
|
+
out.push({
|
|
27
|
+
kind: "path",
|
|
28
|
+
path: rectPath(x, 8, boxW, boxH),
|
|
29
|
+
fill: { paint: {
|
|
30
|
+
kind: "solid",
|
|
31
|
+
color: theme.layerTextBg
|
|
32
|
+
} }
|
|
33
|
+
});
|
|
34
|
+
for (let i = 0; i < lines.length; i++) out.push(textCommandFromRuns(x + padX, 12 + i * lineH, [{
|
|
35
|
+
text: lines[i],
|
|
36
|
+
fill: { paint: {
|
|
37
|
+
kind: "solid",
|
|
38
|
+
color: theme.layerText
|
|
39
|
+
} }
|
|
40
|
+
}], {
|
|
41
|
+
fontFamily: "ui-monospace, Menlo, monospace",
|
|
42
|
+
fontSize: 11
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
var MONO = {
|
|
46
|
+
fontFamily: "ui-monospace, Menlo, monospace",
|
|
47
|
+
fontSize: 11
|
|
48
|
+
};
|
|
49
|
+
var MONO_CHAR_W = 6.6;
|
|
50
|
+
var LINE_H = 14;
|
|
51
|
+
/** A dark box holding monospace lines, at `(x, y)`; `y < 0` anchors its bottom
|
|
52
|
+
* that far above `bottom`. Width is estimated from the character count — there
|
|
53
|
+
* is no text measurer here, and a debug panel does not need one. */
|
|
54
|
+
function emitTextPanel(out, lines, x, y, color, bg) {
|
|
55
|
+
const padX = 6;
|
|
56
|
+
const padY = 4;
|
|
57
|
+
let maxLen = 0;
|
|
58
|
+
for (const l of lines) maxLen = Math.max(maxLen, l.length);
|
|
59
|
+
out.push({
|
|
60
|
+
kind: "path",
|
|
61
|
+
path: rectPath(x, y, maxLen * MONO_CHAR_W + 12, lines.length * LINE_H + 8),
|
|
62
|
+
fill: { paint: {
|
|
63
|
+
kind: "solid",
|
|
64
|
+
color: bg
|
|
65
|
+
} }
|
|
66
|
+
});
|
|
67
|
+
for (let i = 0; i < lines.length; i++) out.push(textCommandFromRuns(x + padX, y + padY + i * LINE_H, [{
|
|
68
|
+
text: lines[i],
|
|
69
|
+
fill: { paint: {
|
|
70
|
+
kind: "solid",
|
|
71
|
+
color
|
|
72
|
+
} }
|
|
73
|
+
}], MONO));
|
|
74
|
+
}
|
|
75
|
+
/** Fixed-width number, right-aligned, `decimals` places: `%{width}.{decimals}f`. */
|
|
76
|
+
function fixed(v, width, decimals) {
|
|
77
|
+
return v.toFixed(decimals).padStart(width);
|
|
78
|
+
}
|
|
79
|
+
function emitFramePanel(out, history, frame, theme) {
|
|
80
|
+
const span = history.length >= 2 ? history[history.length - 1] - history[0] : 0;
|
|
81
|
+
const interval = span > 0 ? span / (history.length - 1) : null;
|
|
82
|
+
const rows = [[
|
|
83
|
+
"fps",
|
|
84
|
+
null,
|
|
85
|
+
interval ? 1e3 / interval : null,
|
|
86
|
+
" "
|
|
87
|
+
], [
|
|
88
|
+
"frame",
|
|
89
|
+
null,
|
|
90
|
+
interval,
|
|
91
|
+
"ms"
|
|
92
|
+
]];
|
|
93
|
+
if (frame) {
|
|
94
|
+
rows.push([
|
|
95
|
+
"paint",
|
|
96
|
+
frame.drawCalls,
|
|
97
|
+
frame.paintMs,
|
|
98
|
+
"ms"
|
|
99
|
+
]);
|
|
100
|
+
for (const l of frame.layers) rows.push([
|
|
101
|
+
l.id,
|
|
102
|
+
l.drawCalls,
|
|
103
|
+
l.ms,
|
|
104
|
+
"ms"
|
|
105
|
+
]);
|
|
106
|
+
}
|
|
107
|
+
let labelW = 0;
|
|
108
|
+
for (const [label] of rows) labelW = Math.max(labelW, label.length);
|
|
109
|
+
const line = (label, count, value, unit) => `${label.padEnd(labelW)} ${count.padStart(5)} ${value.padStart(7)} ${unit}`;
|
|
110
|
+
const lines = rows.map(([label, count, value, unit]) => line(label, count === null ? "" : String(count), value === null ? "—" : fixed(value, 7, 2), unit));
|
|
111
|
+
if (frame) lines.splice(2, 0, line("", "draws", "cpu", " "));
|
|
112
|
+
emitTextPanel(out, lines, 8, 8, theme.fpsText, theme.fpsTextBg);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
export { LINE_H, emitFramePanel, emitLayersPanel, emitTextPanel, rectPath };
|
|
117
|
+
//# sourceMappingURL=overlayPanels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlayPanels.js","names":[],"sources":["../../src/debug/overlayPanels.ts"],"sourcesContent":["/** The debug overlay's text panels — the layer list and the frame stats — and the rect path every box is drawn with. */\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport { textCommandFromRuns } from '@weasel-js/renderer';\nimport type { Dims } from 'core/layers/render';\nimport type { DebugSnapshot, DebugTheme, FrameStats } from './types';\n\nexport function rectPath(x: number, y: number, w: number, h: number): { kind: 'rect'; x: number; y: number; width: number; height: number } {\n return { kind: 'rect', x, y, width: w, height: h };\n}\n\n/** A `DebugStroke` + color as the renderer's stroke shape. `dash` is dropped\n * when empty rather than passed through, so a solid line stays solid. */\nexport function emitLayersPanel(\n out: DrawCommand[],\n s: DebugSnapshot,\n dims: Dims,\n theme: DebugTheme,\n): void {\n if (s.layers.length === 0) return;\n const lineH = 14;\n const padX = 6;\n const padY = 4;\n const lines = s.layers.map((l) => `[${l.index}] ${l.id} (${l.space})`);\n // Approximate width: 11px font, monospaced — assume each glyph ≈6.6px.\n // 2D path uses ctx.measureText; we don't have a ctx here, so fall back\n // to a character-count estimate. Pixel-level accuracy is not load-bearing\n // for a debug panel; right-edge anchoring stays correct.\n const charW = 6.6;\n let maxW = 0;\n for (const line of lines) maxW = Math.max(maxW, line.length * charW);\n const boxW = maxW + padX * 2;\n const boxH = lines.length * lineH + padY * 2;\n const x = dims.width - boxW - 8;\n const y = 8;\n out.push({\n kind: 'path',\n path: rectPath(x, y, boxW, boxH),\n fill: { paint: { kind: 'solid', color: theme.layerTextBg } },\n });\n for (let i = 0; i < lines.length; i++) {\n out.push(textCommandFromRuns(\n x + padX,\n y + padY + i * lineH,\n [{ text: lines[i], fill: { paint: { kind: 'solid', color: theme.layerText } } }],\n { fontFamily: 'ui-monospace, Menlo, monospace', fontSize: 11 },\n ));\n }\n}\n\nconst MONO = { fontFamily: 'ui-monospace, Menlo, monospace', fontSize: 11 };\nconst MONO_CHAR_W = 6.6;\nexport const LINE_H = 14;\n\n/** A dark box holding monospace lines, at `(x, y)`; `y < 0` anchors its bottom\n * that far above `bottom`. Width is estimated from the character count — there\n * is no text measurer here, and a debug panel does not need one. */\nexport function emitTextPanel(\n out: DrawCommand[],\n lines: readonly string[],\n x: number,\n y: number,\n color: string,\n bg: string,\n): void {\n const padX = 6;\n const padY = 4;\n let maxLen = 0;\n for (const l of lines) maxLen = Math.max(maxLen, l.length);\n out.push({\n kind: 'path',\n path: rectPath(x, y, maxLen * MONO_CHAR_W + padX * 2, lines.length * LINE_H + padY * 2),\n fill: { paint: { kind: 'solid', color: bg } },\n });\n for (let i = 0; i < lines.length; i++) {\n out.push(textCommandFromRuns(\n x + padX,\n y + padY + i * LINE_H,\n [{ text: lines[i], fill: { paint: { kind: 'solid', color } } }],\n MONO,\n ));\n }\n}\n\n/** Fixed-width number, right-aligned, `decimals` places: `%{width}.{decimals}f`. */\nfunction fixed(v: number, width: number, decimals: number): string {\n return v.toFixed(decimals).padStart(width);\n}\n\nexport function emitFramePanel(\n out: DrawCommand[],\n history: readonly number[],\n frame: FrameStats | null,\n theme: DebugTheme,\n): void {\n const span = history.length >= 2 ? history[history.length - 1] - history[0] : 0;\n const interval = span > 0 ? span / (history.length - 1) : null;\n // Columns: label, draw-call count, value, unit — every row the same width,\n // so decimals line up down the panel.\n const rows: [label: string, count: number | null, value: number | null, unit: string][] = [\n ['fps', null, interval ? 1000 / interval : null, ' '],\n ['frame', null, interval, 'ms'],\n ];\n if (frame) {\n rows.push(['paint', frame.drawCalls, frame.paintMs, 'ms']);\n for (const l of frame.layers) rows.push([l.id, l.drawCalls, l.ms, 'ms']);\n }\n let labelW = 0;\n for (const [label] of rows) labelW = Math.max(labelW, label.length);\n const line = (label: string, count: string, value: string, unit: string) =>\n `${label.padEnd(labelW)} ${count.padStart(5)} ${value.padStart(7)} ${unit}`;\n const lines = rows.map(([label, count, value, unit]) =>\n line(label, count === null ? '' : String(count), value === null ? '—' : fixed(value, 7, 2), unit));\n if (frame) lines.splice(2, 0, line('', 'draws', 'cpu', ' '));\n emitTextPanel(out, lines, 8, 8, theme.fpsText, theme.fpsTextBg);\n}\n"],"mappings":"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"}
|