@weasel-js/core 1.9.3 → 1.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +356 -0
- package/README.md +2 -2
- package/dist/WeaselProvider.js +5 -5
- package/dist/affordances/composeAffordanceLayer.js +10 -20
- package/dist/affordances/composeAffordanceLayer.js.map +1 -1
- package/dist/affordances/cornerResize.js +25 -17
- package/dist/affordances/cornerResize.js.map +1 -1
- package/dist/affordances/hitAffordanceRegions.js +27 -20
- package/dist/affordances/hitAffordanceRegions.js.map +1 -1
- package/dist/affordances/rotationHandle.js +18 -18
- package/dist/affordances/rotationHandle.js.map +1 -1
- package/dist/animation/behaviors/momentum.js +93 -55
- package/dist/animation/behaviors/momentum.js.map +1 -1
- package/dist/animation/loop.js +10 -12
- package/dist/animation/loop.js.map +1 -1
- package/dist/animation/reflow.js +8 -8
- package/dist/animation/reflow.js.map +1 -1
- package/dist/animation/stagger.js +64 -56
- package/dist/animation/stagger.js.map +1 -1
- package/dist/animation/timeline/booking.js +62 -54
- package/dist/animation/timeline/booking.js.map +1 -1
- package/dist/animation/timeline/createTimeline.js +85 -76
- package/dist/animation/timeline/createTimeline.js.map +1 -1
- package/dist/animation/timeline/sampleTrack.js +13 -5
- package/dist/animation/timeline/sampleTrack.js.map +1 -1
- package/dist/animation/useAnimator.js +45 -35
- package/dist/animation/useAnimator.js.map +1 -1
- package/dist/animation/wrappers/animateLifecycle.js +31 -24
- package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
- package/dist/animation/wrappers/animateOnSetPose.js +28 -26
- package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
- package/dist/animation/wrappers/instantPose.js +13 -0
- package/dist/animation/wrappers/instantPose.js.map +1 -0
- package/dist/{poseDescriptor-D-OH-tu5.d.ts → autoPoseDescriptor-Ct7yqivU.d.ts} +28 -3
- package/dist/barrel/chrome.js +16 -0
- package/dist/barrel/input.js +19 -0
- package/dist/barrel/interactions.js +42 -0
- package/dist/barrel/paint.js +18 -0
- package/dist/barrel/paths.js +19 -0
- package/dist/barrel/renderer.js +20 -0
- package/dist/barrel/routing.js +51 -0
- package/dist/barrel/text.js +18 -0
- package/dist/barrel/viewport.js +52 -0
- package/dist/builtins-DPcdghtB.d.ts +1223 -0
- package/dist/canvas/Canvas.js +363 -448
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +164 -165
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/CursorCoordsHud.js +37 -32
- package/dist/canvas/CursorCoordsHud.js.map +1 -1
- package/dist/canvas/DrawCanvas.js +49 -43
- package/dist/canvas/DrawCanvas.js.map +1 -1
- package/dist/canvas/MinimapCanvas.js +26 -25
- package/dist/canvas/MinimapCanvas.js.map +1 -1
- package/dist/canvas/NodeShape.js +59 -377
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/PickHud.js +50 -47
- package/dist/canvas/PickHud.js.map +1 -1
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +167 -0
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -0
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +13 -13
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +67 -0
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -0
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +16 -0
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -0
- package/dist/canvas/SceneCanvas/coordTrace.js +10 -0
- package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -0
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +112 -70
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +9 -8
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
- package/dist/canvas/SceneCanvas/features.js +1 -0
- package/dist/canvas/SceneCanvas/features.js.map +1 -1
- package/dist/canvas/SceneCanvas/isDev.js +12 -0
- package/dist/canvas/SceneCanvas/isDev.js.map +1 -0
- package/dist/canvas/SceneCanvas/poseGeometry.js +29 -28
- package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
- package/dist/canvas/SceneCanvas/poseRegistrars.js +13 -0
- package/dist/canvas/SceneCanvas/poseRegistrars.js.map +1 -0
- package/dist/canvas/SceneCanvas/props.js +38 -0
- package/dist/canvas/SceneCanvas/props.js.map +1 -0
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +21 -62
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +46 -48
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +33 -33
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas.js +534 -788
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SceneViewCanvas.js +45 -43
- package/dist/canvas/SceneViewCanvas.js.map +1 -1
- package/dist/canvas/buildSceneLayer.js +91 -0
- package/dist/canvas/buildSceneLayer.js.map +1 -0
- package/dist/canvas/buildSceneTree.js +16 -19
- package/dist/canvas/buildSceneTree.js.map +1 -1
- package/dist/canvas/canvasRenderer.js +68 -52
- package/dist/canvas/canvasRenderer.js.map +1 -1
- package/dist/canvas/deps/changes.js +13 -0
- package/dist/canvas/deps/changes.js.map +1 -0
- package/dist/canvas/deps/editAnchors.js +28 -28
- package/dist/canvas/deps/insert.js +119 -91
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/slice.js +46 -45
- package/dist/canvas/deps/slice.js.map +1 -1
- package/dist/canvas/deps/textEdit.js +10 -9
- package/dist/canvas/deps/textEdit.js.map +1 -1
- package/dist/canvas/derivedPath.js +46 -23
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/getNodeAtPoint.js +7 -7
- package/dist/canvas/getNodeAtPoint.js.map +1 -1
- package/dist/canvas/hud.module.js +1 -1
- package/dist/canvas/hud.module.js.map +1 -1
- package/dist/canvas/kitRequirements.js +2 -2
- package/dist/canvas/kitRequirements.js.map +1 -1
- package/dist/canvas/layerOrder.js +13 -6
- package/dist/canvas/layerOrder.js.map +1 -1
- package/dist/canvas/minimapMath.js +12 -10
- package/dist/canvas/minimapMath.js.map +1 -1
- package/dist/canvas/nodeShapes/derivedPainter.js +34 -0
- package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/imagePainter.js +87 -0
- package/dist/canvas/nodeShapes/imagePainter.js.map +1 -0
- package/dist/canvas/nodeShapes/memo.js +9 -0
- package/dist/canvas/nodeShapes/memo.js.map +1 -0
- package/dist/canvas/nodeShapes/nodePaint.js +57 -0
- package/dist/canvas/nodeShapes/nodePaint.js.map +1 -0
- package/dist/canvas/nodeShapes/pathPainter.js +38 -0
- package/dist/canvas/nodeShapes/pathPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/poseBox.js +20 -0
- package/dist/canvas/nodeShapes/poseBox.js.map +1 -0
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +38 -0
- package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/shapePainter.js +72 -0
- package/dist/canvas/nodeShapes/shapePainter.js.map +1 -0
- package/dist/canvas/nodeShapes/textPainter.js +55 -0
- package/dist/canvas/nodeShapes/textPainter.js.map +1 -0
- package/dist/canvas/overlayRoleStrokes.js.map +1 -1
- package/dist/canvas/paintCull.js +10 -11
- package/dist/canvas/paintCull.js.map +1 -1
- package/dist/canvas/pickWalk.js +52 -63
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/poseRotation.js +11 -23
- package/dist/canvas/poseRotation.js.map +1 -1
- package/dist/canvas/renderDebugSnapshot.js +5 -5
- package/dist/canvas/renderSceneToPixels.js +3 -1
- package/dist/canvas/renderSceneToPixels.js.map +1 -1
- package/dist/canvas/sceneAdapter.js +66 -148
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneClipboard.js +112 -0
- package/dist/canvas/sceneClipboard.js.map +1 -0
- package/dist/canvas/sceneSlotWiring.js +4 -4
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +39 -40
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/useCanvasRenderer.js +14 -6
- package/dist/canvas/useCanvasRenderer.js.map +1 -1
- package/dist/canvas/useCanvasView.js +58 -0
- package/dist/canvas/useCanvasView.js.map +1 -0
- package/dist/canvas/useFrameLoop.js +35 -26
- package/dist/canvas/useFrameLoop.js.map +1 -1
- package/dist/canvas/useSceneLayerList.js +21 -0
- package/dist/canvas/useSceneLayerList.js.map +1 -0
- package/dist/clipboard.d.ts +10 -6
- package/dist/clone.d.ts +4 -3
- package/dist/core/adapters/arrayAdapter.js +48 -39
- package/dist/core/adapters/arrayAdapter.js.map +1 -1
- package/dist/core/device/index.js +5 -4
- package/dist/core/device/useDeviceProfile.js +38 -44
- package/dist/core/device/useDeviceProfile.js.map +1 -1
- package/dist/core/device/watchDevicePixelRatio.js +17 -0
- package/dist/core/device/watchDevicePixelRatio.js.map +1 -0
- package/dist/core/fillInPoseFrame.js.map +1 -1
- package/dist/core/geometry/poseDescriptor.js +21 -19
- package/dist/core/geometry/poseDescriptor.js.map +1 -1
- package/dist/core/geometry/poseFrame.js +44 -0
- package/dist/core/geometry/poseFrame.js.map +1 -0
- package/dist/core/geometry/poseRotation.js.map +1 -1
- package/dist/core/geometry/regionHit.js +9 -10
- package/dist/core/geometry/regionHit.js.map +1 -1
- package/dist/core/geometry/unionBounds.js +31 -29
- package/dist/core/geometry/unionBounds.js.map +1 -1
- package/dist/core/isPlainObject.js +2 -11
- package/dist/core/ops/arrange.js +1 -0
- package/dist/core/ops/arrange.js.map +1 -1
- package/dist/core/ops/create.js +10 -5
- package/dist/core/ops/create.js.map +1 -1
- package/dist/core/ops/delete.js +12 -24
- package/dist/core/ops/delete.js.map +1 -1
- package/dist/core/ops/reorder/index.js +43 -40
- package/dist/core/ops/reorder/index.js.map +1 -1
- package/dist/core/ops/reorder/setChildOrder.js +34 -0
- package/dist/core/ops/reorder/setChildOrder.js.map +1 -0
- package/dist/core/paintKinds.js +5 -5
- package/dist/core/paintKinds.js.map +1 -1
- package/dist/core/scene/NodeProperties.js.map +1 -1
- package/dist/core/scene/appliedLog.js +37 -0
- package/dist/core/scene/appliedLog.js.map +1 -0
- package/dist/core/scene/arrivalWindow.js +101 -0
- package/dist/core/scene/arrivalWindow.js.map +1 -0
- package/dist/core/scene/derivedPath.js.map +1 -1
- package/dist/core/scene/historyFacade.js +84 -0
- package/dist/core/scene/historyFacade.js.map +1 -0
- package/dist/core/scene/kitOps.js +173 -0
- package/dist/core/scene/kitOps.js.map +1 -0
- package/dist/core/scene/layerStack.js +38 -0
- package/dist/core/scene/layerStack.js.map +1 -0
- package/dist/core/scene/lockGuard.js +37 -0
- package/dist/core/scene/lockGuard.js.map +1 -0
- package/dist/core/scene/nodeFnFields.js +5 -6
- package/dist/core/scene/nodeFnFields.js.map +1 -1
- package/dist/core/scene/nodeMemo.js +45 -19
- package/dist/core/scene/nodeMemo.js.map +1 -1
- package/dist/core/scene/nodeStore.js +126 -0
- package/dist/core/scene/nodeStore.js.map +1 -0
- package/dist/core/scene/pickability.js +6 -0
- package/dist/core/scene/pickability.js.map +1 -0
- package/dist/core/scene/poseFeed.js +38 -38
- package/dist/core/scene/poseFeed.js.map +1 -1
- package/dist/core/scene/poseOverrides.js +34 -38
- package/dist/core/scene/poseOverrides.js.map +1 -1
- package/dist/core/scene/renderOrder.js +84 -0
- package/dist/core/scene/renderOrder.js.map +1 -0
- package/dist/core/scene/scene.js +289 -866
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/serialization.js +68 -0
- package/dist/core/scene/serialization.js.map +1 -0
- package/dist/core/scene/treeOrder.js +13 -0
- package/dist/core/scene/treeOrder.js.map +1 -0
- package/dist/core/scene/types.js.map +1 -1
- package/dist/core/viewport/meanScale.js +1 -1
- package/dist/core/viewport/meanScale.js.map +1 -1
- package/dist/core/viewport/view.js +12 -12
- package/dist/core/viewport/view.js.map +1 -1
- package/dist/core/viewport/zoomBounds.js +10 -8
- package/dist/core/viewport/zoomBounds.js.map +1 -1
- package/dist/{cornerHandles-BCrDp_mH.d.ts → cornerHandles-CtCb8a3G.d.ts} +1 -1
- package/dist/debug/createDebugOverlayLayer.js +14 -14
- package/dist/debug/createDebugOverlayLayer.js.map +1 -1
- package/dist/debug/flag.js +2 -41
- package/dist/features/chrome-caps/useHoverTracking.js +22 -17
- package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
- package/dist/features/focus/gateLayer.js +3 -4
- package/dist/features/focus/gateLayer.js.map +1 -1
- package/dist/features/images/imageCache.js +19 -9
- package/dist/features/images/imageCache.js.map +1 -1
- package/dist/features/ingestion/contentHandlers.js +14 -11
- package/dist/features/ingestion/contentHandlers.js.map +1 -1
- package/dist/features/ingestion/index.js +1 -1
- package/dist/features/ingestion/registerKitHandlers.js +7 -7
- package/dist/features/ingestion/weaselJsonHandler.js +17 -14
- package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
- package/dist/features/meshPaint/lazyKind.js +201 -35
- package/dist/features/meshPaint/lazyKind.js.map +1 -1
- package/dist/features/meshPaint/meshPaint.js +82 -79
- package/dist/features/meshPaint/meshPaint.js.map +1 -1
- package/dist/features/minimap/createMinimapContribution.js +42 -42
- package/dist/features/minimap/layers.js +44 -62
- package/dist/features/minimap/layers.js.map +1 -1
- package/dist/features/parallax/createParallaxPlane.js +10 -14
- package/dist/features/parallax/createParallaxPlane.js.map +1 -1
- package/dist/features/paths/anchorEdits.js +19 -8
- package/dist/features/paths/anchorEdits.js.map +1 -1
- package/dist/features/paths/anchors.js +31 -26
- package/dist/features/paths/anchors.js.map +1 -1
- package/dist/features/paths/booleans.js +2 -2
- package/dist/features/paths/index.js +13 -11
- package/dist/features/paths/markerCommands.js +37 -36
- package/dist/features/paths/markerCommands.js.map +1 -1
- package/dist/features/paths/pathInWorld.js +19 -19
- package/dist/features/paths/pathInWorld.js.map +1 -1
- package/dist/features/paths/pathLayer.js.map +1 -1
- package/dist/features/paths/strokeToPath.js +40 -0
- package/dist/features/paths/strokeToPath.js.map +1 -0
- package/dist/features/paths/tessellate/stroke.js.map +1 -1
- package/dist/features/patterns/commandPaint.js +18 -0
- package/dist/features/patterns/commandPaint.js.map +1 -0
- package/dist/features/patterns/index.js +5 -17
- package/dist/features/patterns/index.js.map +1 -1
- package/dist/features/patterns/rasterizeTile.js +17 -0
- package/dist/features/patterns/rasterizeTile.js.map +1 -0
- package/dist/features/patterns/resolveSpec.js +52 -44
- package/dist/features/patterns/resolveSpec.js.map +1 -1
- package/dist/features/poseRun/usePoseRun.js +8 -3
- package/dist/features/poseRun/usePoseRun.js.map +1 -1
- package/dist/features/selection/SelectionContext.js +5 -0
- package/dist/features/selection/SelectionContext.js.map +1 -1
- package/dist/features/selection/overlay.js +18 -18
- package/dist/features/selection/overlay.js.map +1 -1
- package/dist/features/text/domOffsets.js +82 -0
- package/dist/features/text/domOffsets.js.map +1 -0
- package/dist/features/text/domRuns.js +103 -131
- package/dist/features/text/domRuns.js.map +1 -1
- package/dist/features/text/hitTest.js +5 -2
- package/dist/features/text/hitTest.js.map +1 -1
- package/dist/features/text/isTextData.js +8 -0
- package/dist/features/text/isTextData.js.map +1 -0
- package/dist/features/text/overlayDirection.js +15 -0
- package/dist/features/text/overlayDirection.js.map +1 -0
- package/dist/features/text/runs/rangeStyle.js +32 -34
- package/dist/features/text/runs/rangeStyle.js.map +1 -1
- package/dist/features/text/textCommand.js +34 -33
- package/dist/features/text/textCommand.js.map +1 -1
- package/dist/features/text/textToPath.js +40 -40
- package/dist/features/text/textToPath.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +76 -82
- package/dist/features/text/useSceneTextEdit.js.map +1 -1
- package/dist/features/text/useTextEdit.js +184 -160
- package/dist/features/text/useTextEdit.js.map +1 -1
- package/dist/features/tiling/createTiledLayer.js +24 -22
- package/dist/features/tiling/createTiledLayer.js.map +1 -1
- package/dist/index.d.ts +11033 -7749
- package/dist/index.js +316 -309
- package/dist/input/keyState.js +42 -43
- package/dist/input/keyState.js.map +1 -1
- package/dist/input/useKeyModifiers.js +11 -0
- package/dist/input/useKeyModifiers.js.map +1 -0
- package/dist/interactions/actions/align/align.js +8 -8
- package/dist/interactions/actions/clipboard/clipboardOps.js +34 -32
- package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
- package/dist/interactions/actions/clipboard/materializePaste.js +10 -7
- package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
- package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +1 -1
- package/dist/interactions/actions/defaultCommitAdapter.js +20 -18
- package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
- package/dist/interactions/actions/defaults/align.js +9 -10
- package/dist/interactions/actions/defaults/align.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +59 -81
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
- package/dist/interactions/actions/defaults/areaSelect.js +35 -38
- package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/clipboard.js +26 -10
- package/dist/interactions/actions/defaults/clipboard.js.map +1 -1
- package/dist/interactions/actions/defaults/clone.js +44 -60
- package/dist/interactions/actions/defaults/clone.js.map +1 -1
- package/dist/interactions/actions/defaults/copySubtree.js +40 -0
- package/dist/interactions/actions/defaults/copySubtree.js.map +1 -0
- package/dist/interactions/actions/defaults/distribute.js +14 -13
- package/dist/interactions/actions/defaults/distribute.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +17 -57
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
- package/dist/interactions/actions/defaults/editAnchors.js +18 -18
- package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/flip.js +52 -46
- package/dist/interactions/actions/defaults/flip.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +43 -48
- package/dist/interactions/actions/defaults/group.js.map +1 -1
- package/dist/interactions/actions/defaults/ingest.js +35 -33
- package/dist/interactions/actions/defaults/ingest.js.map +1 -1
- package/dist/interactions/actions/defaults/insert.js +50 -51
- package/dist/interactions/actions/defaults/insert.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +7 -7
- package/dist/interactions/actions/defaults/lassoSelect.js +67 -70
- package/dist/interactions/actions/defaults/lassoSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/move.js +267 -249
- package/dist/interactions/actions/defaults/move.js.map +1 -1
- package/dist/interactions/actions/defaults/nudge.js +40 -68
- package/dist/interactions/actions/defaults/nudge.js.map +1 -1
- package/dist/interactions/actions/defaults/nudgeSteps.js +37 -0
- package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -0
- package/dist/interactions/actions/defaults/reorder.js +2 -0
- package/dist/interactions/actions/defaults/reorder.js.map +1 -1
- package/dist/interactions/actions/defaults/resize.js +104 -98
- package/dist/interactions/actions/defaults/resize.js.map +1 -1
- package/dist/interactions/actions/defaults/rotate.js +111 -110
- package/dist/interactions/actions/defaults/rotate.js.map +1 -1
- package/dist/interactions/actions/defaults/setFill.js +7 -7
- package/dist/interactions/actions/defaults/setFillOpacity.js +4 -4
- package/dist/interactions/actions/defaults/setStroke.js +12 -12
- package/dist/interactions/actions/defaults/setStrokeOpacity.js +6 -6
- package/dist/interactions/actions/defaults/sliceOps.js +19 -19
- package/dist/interactions/actions/defaults/viewportDragPan.js +37 -26
- package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/geometry.js +28 -23
- package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
- package/dist/interactions/actions/flip/helpers.js +30 -17
- package/dist/interactions/actions/flip/helpers.js.map +1 -1
- package/dist/interactions/actions/hitSelection.js +8 -0
- package/dist/interactions/actions/hitSelection.js.map +1 -0
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +14 -18
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +5 -5
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +32 -21
- package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
- package/dist/interactions/actions/move/gestureAdapter.js +32 -15
- package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
- package/dist/interactions/actions/move/landedDescendants.js +33 -0
- package/dist/interactions/actions/move/landedDescendants.js.map +1 -0
- package/dist/interactions/actions/outlines/createOutlines.js +18 -18
- package/dist/interactions/actions/poseDescriptorDep.js +16 -4
- package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
- package/dist/interactions/actions/poseFrame.js +11 -6
- package/dist/interactions/actions/poseFrame.js.map +1 -1
- package/dist/interactions/actions/previewOverrides.js +5 -5
- package/dist/interactions/actions/previewOverrides.js.map +1 -1
- package/dist/interactions/actions/selectionSubtree.js +69 -0
- package/dist/interactions/actions/selectionSubtree.js.map +1 -0
- package/dist/interactions/actions/useStandardActions.js +66 -62
- package/dist/interactions/actions/useStandardActions.js.map +1 -1
- package/dist/interactions/gestures/dragGesture/dragGesture.js +4 -7
- package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -1
- package/dist/interactions/gestures/dragGesture/dragPointOf.js +23 -0
- package/dist/interactions/gestures/dragGesture/dragPointOf.js.map +1 -0
- package/dist/interactions/gestures/handleDrag/handleDrag.js +21 -26
- package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -1
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js +8 -6
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +8 -4
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
- package/dist/{math-Drrw4ewZ.d.ts → math-J-ACHyEg.d.ts} +1 -2
- package/dist/math.d.ts +2 -3
- package/dist/move.d.ts +12 -11
- package/dist/{originProjection-DEklpDc_.d.ts → originProjection-gHnOup4e.d.ts} +1 -1
- package/dist/{registerProgram-BMZRDgrh.d.ts → registerProgram-T9S_PfAX.d.ts} +18 -7
- package/dist/renderer/DrawCommand.js.map +1 -1
- package/dist/renderer/WeaselRenderer.js +75 -73
- package/dist/renderer/WeaselRenderer.js.map +1 -1
- package/dist/renderer/cache/GLImageCache.js +15 -5
- package/dist/renderer/cache/GLImageCache.js.map +1 -1
- package/dist/renderer/cache/GLMeshCache.js +23 -23
- package/dist/renderer/cache/GLMeshCache.js.map +1 -1
- package/dist/renderer/cache/GLTextureCache.js +18 -1
- package/dist/renderer/cache/GLTextureCache.js.map +1 -1
- package/dist/renderer/cache/cache.js.map +1 -1
- package/dist/renderer/cache/markerCommandCache.js.map +1 -1
- package/dist/renderer/cache/strokeMeshCache.js.map +1 -1
- package/dist/renderer/cullDrawCommands.js +11 -11
- package/dist/renderer/draw/batch.js +133 -0
- package/dist/renderer/draw/batch.js.map +1 -0
- package/dist/renderer/draw/clip.js +89 -0
- package/dist/renderer/draw/clip.js.map +1 -0
- package/dist/renderer/draw/customShader.js +230 -0
- package/dist/renderer/draw/customShader.js.map +1 -0
- package/dist/renderer/draw/drawTriangles.js +8 -0
- package/dist/renderer/draw/drawTriangles.js.map +1 -0
- package/dist/renderer/draw/effects.js +28 -0
- package/dist/renderer/draw/effects.js.map +1 -0
- package/dist/renderer/draw/flushBatch.js +35 -0
- package/dist/renderer/draw/flushBatch.js.map +1 -0
- package/dist/renderer/draw/gradient.js +90 -0
- package/dist/renderer/draw/gradient.js.map +1 -0
- package/dist/renderer/draw/image.js +38 -0
- package/dist/renderer/draw/image.js.map +1 -0
- package/dist/renderer/draw/mesh.js +16 -0
- package/dist/renderer/draw/mesh.js.map +1 -0
- package/dist/renderer/draw/paintBind.js +70 -0
- package/dist/renderer/draw/paintBind.js.map +1 -0
- package/dist/renderer/draw/pathPaint.js +142 -0
- package/dist/renderer/draw/pathPaint.js.map +1 -0
- package/dist/renderer/draw/scratchPass.js +83 -0
- package/dist/renderer/draw/scratchPass.js.map +1 -0
- package/dist/renderer/draw/stencil.js +28 -0
- package/dist/renderer/draw/stencil.js.map +1 -0
- package/dist/renderer/draw/text.js +167 -0
- package/dist/renderer/draw/text.js.map +1 -0
- package/dist/renderer/draw/uniforms.js +77 -0
- package/dist/renderer/draw/uniforms.js.map +1 -0
- package/dist/renderer/draw.js +60 -1116
- package/dist/renderer/draw.js.map +1 -1
- package/dist/renderer/effects/EffectTargets.js +3 -0
- package/dist/renderer/effects/EffectTargets.js.map +1 -1
- package/dist/renderer/effects/composite.js +7 -5
- package/dist/renderer/effects/composite.js.map +1 -1
- package/dist/renderer/index.js +18 -17
- package/dist/renderer/math/color.js +63 -83
- package/dist/renderer/math/color.js.map +1 -1
- package/dist/renderer/math/mat3.js +15 -11
- package/dist/renderer/math/mat3.js.map +1 -1
- package/dist/renderer/math/viewToMat3.js +1 -1
- package/dist/renderer/math/viewToMat3.js.map +1 -1
- package/dist/renderer/shaders/ShaderProgram.js +13 -13
- package/dist/renderer/shaders/ShaderProgram.js.map +1 -1
- package/dist/renderer/shaders/glyphPaint.js +3 -3
- package/dist/renderer/shaders/glyphPaint.js.map +1 -1
- package/dist/renderer/shaders/gradFill.js +2 -1
- package/dist/renderer/shaders/gradFill.js.map +1 -1
- package/dist/renderer/shaders/pathFill.js +2 -1
- package/dist/renderer/shaders/pathFill.js.map +1 -1
- package/dist/renderer/shaders/patternFill.js +2 -1
- package/dist/renderer/shaders/patternFill.js.map +1 -1
- package/dist/renderer/shaders/registerProgram.js.map +1 -1
- package/dist/renderer/strokeLengths.js.map +1 -1
- package/dist/renderer/textures/registerTexture.js +25 -5
- package/dist/renderer/textures/registerTexture.js.map +1 -1
- package/dist/renderer.d.ts +16 -15
- package/dist/renderer.js +17 -16
- package/dist/resize.d.ts +5 -6
- package/dist/resize.js +5 -5
- package/dist/style.css +1 -1
- package/dist/test-hook/install.js +12 -6
- package/dist/test-hook/install.js.map +1 -1
- package/dist/{test-seams-CuIxe0xY.d.ts → test-seams-DM2B87-g.d.ts} +4 -4
- package/dist/test-seams.d.ts +2 -2
- package/dist/tools/builtin/ellipse/useEllipseTool.js +1 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
- package/dist/tools/builtin/hand/useHandTool.js +1 -0
- package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
- package/dist/tools/builtin/lasso/useLassoTool.js +11 -11
- 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/pen/usePenTool.js +153 -103
- 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 -8
- 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/selectionContributions.js +24 -23
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +51 -48
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/shared/pointerFollower.js +17 -0
- package/dist/tools/builtin/shared/pointerFollower.js.map +1 -0
- package/dist/tools/builtin/slice/useSliceTool.js +49 -54
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
- package/dist/tools/builtin/star/useStarTool.js +22 -16
- package/dist/tools/builtin/star/useStarTool.js.map +1 -1
- package/dist/tools/builtin/text/useTextTool.js +1 -0
- package/dist/tools/builtin/text/useTextTool.js.map +1 -1
- package/dist/tools/useKeybindings.js +14 -30
- package/dist/tools/useKeybindings.js.map +1 -1
- package/dist/{types-B_9g6hMM.d.ts → types-B4iJRHC3.d.ts} +5 -1
- package/dist/{types-A37hYkeR.d.ts → types-k-5Oqh-U.d.ts} +31 -7
- package/dist/util/color.js +3 -3
- package/dist/util/color.js.map +1 -1
- package/dist/util/paint.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +20 -18
- package/dist/autoPoseDescriptor-vCdt55xm.d.ts +0 -27
- package/dist/builtins-C-VgUlWI.d.ts +0 -4514
- package/dist/core/isPlainObject.js.map +0 -1
- package/dist/debug/flag.js.map +0 -1
- package/dist/interactions/actions/defaults/freshNodeId.js +0 -10
- package/dist/interactions/actions/defaults/freshNodeId.js.map +0 -1
- package/dist/renderer/shaders/imageFill.js +0 -14
- package/dist/renderer/shaders/imageFill.js.map +0 -1
- package/dist/tools/prefs.js +0 -62
- package/dist/tools/prefs.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stagger.js","names":["CompositeHandle","timers","supervisor","totalItems","p","kids","c","h","entry","delayMs","idx","fire","now","s","delayFor","delay","i","createStagger","factory","runStagger","createSupervisor","watchCompletion","items","opts","makeBuilder","animator","composite","ms","child","item","resolvePerItem","v","itemId","id","springPose","adapter","poseFn"],"sources":["../../src/animation/stagger.ts"],"sourcesContent":["import { springPose } from './poseHelpers';\nimport type { Supervisor, SupervisorFactory, WatchCompletion } from './supervisor';\nimport type {\n AnimationHandle,\n Animator,\n StaggerBuilder,\n StaggerDelay,\n StaggerFactory,\n StaggerOptions,\n StaggerPerItem,\n StaggerSpringPoseOptions,\n StaggerTweenOptions,\n} from './types';\nimport type { SceneAdapter } from 'core/adapters/types';\n\n/** Resolved timer-pair + clock, supplied by `useAnimator` so stagger picks\n * up the same test-time injection points the rAF loop uses. `now` is used\n * by pause/resume to freeze pending timers at their remaining time. */\nexport interface StaggerTimers {\n setTimer: (cb: () => void, ms: number) => unknown;\n clearTimer: (handle: unknown) => void;\n now: () => number;\n}\n\ninterface PendingEntry {\n /** Active host-scheduler timer handle, or null while paused. */\n timer: unknown | null;\n /** Absolute virtual-time at which the entry should fire. */\n resolvedAt: number;\n /** Wrapped callback (drops itself from `pending` before invoking the user fire). */\n fire: () => void;\n /** Remaining ms when paused; ignored while running. */\n remainingMs: number;\n /** True while the timer is suspended by `composite.pause()`. */\n paused: boolean;\n}\n\n/**\n * Composite handle returned by `createStagger`. Owns a list of in-flight\n * child handles and a list of pending timer entries; cancel cancels both.\n * Pause/resume/setTimeScale propagate to in-flight children; pause/resume\n * also freeze and thaw pending per-item timers, preserving each entry's\n * remaining time across the pause.\n *\n * Registered with the animator via a supervisor so animator.cancel /\n * cancelKey / isActive all work for it.\n */\nclass CompositeHandle implements AnimationHandle {\n readonly id: number;\n private cancelled = false;\n private paused_ = false;\n private timeScale_ = 1;\n private children: AnimationHandle[] = [];\n private pending: PendingEntry[] = [];\n private outstanding: number;\n private finished = false;\n\n constructor(\n private timers: StaggerTimers,\n private supervisor: Supervisor,\n totalItems: number,\n ) {\n this.id = supervisor.id;\n this.outstanding = totalItems;\n supervisor.setOnCancel(() => this.handleSupervisorCancel());\n }\n\n /** Invoked when the supervisor is cancelled externally (animator.cancel /\n * cancelKey) OR via this composite's own `cancel`. */\n private handleSupervisorCancel(): void {\n if (this.cancelled) return;\n this.cancelled = true;\n for (const p of this.pending) {\n if (p.timer != null) this.timers.clearTimer(p.timer);\n }\n this.pending = [];\n // Snapshot children first: child.cancel() may synchronously invoke our\n // own noteChildDone path via the animator's completion listener, which\n // would mutate this.children mid-iteration.\n const kids = this.children.slice();\n this.children = [];\n for (const c of kids) c.cancel();\n }\n\n noteChildDone(): void {\n if (this.cancelled || this.finished) return;\n this.outstanding -= 1;\n if (this.outstanding <= 0) {\n this.finished = true;\n this.children = [];\n this.supervisor.finish();\n }\n }\n\n addChild(h: AnimationHandle): void {\n if (this.cancelled) {\n h.cancel();\n return;\n }\n this.children.push(h);\n if (this.paused_) h.pause();\n if (this.timeScale_ !== 1) h.setTimeScale(this.timeScale_);\n }\n\n schedule(delayMs: number, fire: () => void): void {\n if (this.cancelled) return;\n const entry: PendingEntry = {\n timer: null,\n resolvedAt: this.timers.now() + delayMs,\n fire: () => {},\n remainingMs: delayMs,\n paused: false,\n };\n entry.fire = (): void => {\n if (this.cancelled) return;\n const idx = this.pending.indexOf(entry);\n if (idx >= 0) this.pending.splice(idx, 1);\n fire();\n };\n if (this.paused_) {\n entry.paused = true;\n } else {\n entry.timer = this.timers.setTimer(entry.fire, delayMs);\n }\n this.pending.push(entry);\n }\n\n cancel(): void {\n // Route through the supervisor so the animator's id table is kept in\n // sync. The supervisor's onCancel forwards back to\n // handleSupervisorCancel which actually tears down children + timers.\n this.supervisor.cancel();\n }\n\n pause(): void {\n if (this.paused_) return;\n this.paused_ = true;\n const now = this.timers.now();\n for (const p of this.pending) {\n if (p.timer != null) {\n p.remainingMs = Math.max(0, p.resolvedAt - now);\n this.timers.clearTimer(p.timer);\n p.timer = null;\n p.paused = true;\n }\n }\n for (const c of this.children) c.pause();\n }\n\n resume(): void {\n if (!this.paused_) return;\n this.paused_ = false;\n const now = this.timers.now();\n for (const p of this.pending) {\n if (p.paused) {\n p.resolvedAt = now + p.remainingMs;\n p.timer = this.timers.setTimer(p.fire, p.remainingMs);\n p.paused = false;\n }\n }\n for (const c of this.children) c.resume();\n }\n\n setTimeScale(s: number): void {\n this.timeScale_ = s;\n for (const c of this.children) c.setTimeScale(s);\n }\n\n timeScale(): number {\n return this.timeScale_;\n }\n\n isPaused(): boolean {\n return this.paused_;\n }\n}\n\nfunction delayFor(delay: StaggerDelay, i: number): number {\n return typeof delay === 'function' ? delay(i) : delay * i;\n}\n\n/**\n * Stagger primitive. With `factory`, returns the composite handle directly.\n * Without `factory`, returns a `StaggerBuilder` whose `.each` runs the\n * stagger with a factory.\n */\nexport function createStagger<TItem>(\n animator: Animator,\n timers: StaggerTimers,\n createSupervisor: SupervisorFactory,\n watchCompletion: WatchCompletion,\n items: readonly TItem[],\n delay: StaggerDelay,\n factory: StaggerFactory<TItem>,\n opts?: StaggerOptions,\n): AnimationHandle;\nexport function createStagger<TItem>(\n animator: Animator,\n timers: StaggerTimers,\n createSupervisor: SupervisorFactory,\n watchCompletion: WatchCompletion,\n items: readonly TItem[],\n delay: StaggerDelay,\n): StaggerBuilder<TItem>;\nexport function createStagger<TItem>(\n animator: Animator,\n timers: StaggerTimers,\n createSupervisor: SupervisorFactory,\n watchCompletion: WatchCompletion,\n items: readonly TItem[],\n delay: StaggerDelay,\n factory?: StaggerFactory<TItem>,\n opts?: StaggerOptions,\n): AnimationHandle | StaggerBuilder<TItem> {\n if (factory) return runStagger(timers, createSupervisor, watchCompletion, items, delay, factory, opts);\n return makeBuilder(animator, timers, createSupervisor, watchCompletion, items, delay);\n}\n\nfunction runStagger<TItem>(\n timers: StaggerTimers,\n createSupervisor: SupervisorFactory,\n watchCompletion: WatchCompletion,\n items: readonly TItem[],\n delay: StaggerDelay,\n factory: StaggerFactory<TItem>,\n opts?: StaggerOptions,\n): AnimationHandle {\n const supervisor = createSupervisor({ kind: 'stagger', cancelKey: opts?.cancelKey, label: opts?.label });\n const composite = new CompositeHandle(timers, supervisor, items.length);\n if (items.length === 0) {\n supervisor.finish();\n return composite;\n }\n items.forEach((item, i) => {\n const ms = delayFor(delay, i);\n const fire = (): void => {\n const child = factory(item, i);\n // Hook into the child's deregistration (natural OR cancel). If the\n // composite is already cancelled, the watcher fires immediately on\n // cancel and the noteChildDone branch is a no-op (cancelled guard).\n watchCompletion(child.id, () => composite.noteChildDone());\n composite.addChild(child);\n };\n if (ms <= 0) fire();\n else composite.schedule(ms, fire);\n });\n return composite;\n}\n\nfunction resolvePerItem<T, TItem>(\n v: StaggerPerItem<T, TItem>,\n item: TItem,\n i: number,\n): T {\n return typeof v === 'function'\n ? (v as (item: TItem, index: number) => T)(item, i)\n : v;\n}\n\nfunction itemId(item: unknown): string {\n if (item != null && typeof item === 'object' && 'id' in item) {\n const id = (item as { id: unknown }).id;\n if (typeof id === 'string') return id;\n }\n if (typeof item === 'string' || typeof item === 'number') return String(item);\n throw new Error(\n 'stagger().springPose: each item must either be a primitive (string/number) ' +\n 'or have a string `id` field. Otherwise pose ids would collide.',\n );\n}\n\nfunction makeBuilder<TItem>(\n animator: Animator,\n timers: StaggerTimers,\n createSupervisor: SupervisorFactory,\n watchCompletion: WatchCompletion,\n items: readonly TItem[],\n delay: StaggerDelay,\n): StaggerBuilder<TItem> {\n return {\n each: (factory, opts) =>\n runStagger(timers, createSupervisor, watchCompletion, items, delay, factory, opts),\n tween: <T,>(opts: StaggerTweenOptions<T, TItem>) =>\n runStagger(timers, createSupervisor, watchCompletion, items, delay, (item, i) =>\n animator.tween<T>({\n from: resolvePerItem(opts.from, item, i),\n to: resolvePerItem(opts.to, item, i),\n ms: resolvePerItem(opts.ms, item, i),\n easing: opts.easing,\n interpolate: opts.interpolate,\n onTick: (v) => opts.onTick(v, item, i),\n onDone: opts.onDone ? () => opts.onDone!(item, i) : undefined,\n }),\n opts,\n ),\n springPose: <TPose,>(\n adapter: SceneAdapter<{ id: string }, TPose>,\n poseFn: (item: TItem, index: number) => TPose,\n opts: StaggerSpringPoseOptions<TPose> = {},\n ) =>\n runStagger(timers, createSupervisor, watchCompletion, items, delay, (item, i) =>\n springPose(animator, adapter, {\n id: itemId(item),\n to: poseFn(item, i),\n preset: opts.preset,\n stiffness: opts.stiffness,\n damping: opts.damping,\n mass: opts.mass,\n geometry: opts.geometry,\n recordOp: opts.recordOp,\n opLabel: opts.opLabel,\n }),\n opts,\n ),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stagger.js","names":["CompositeHandle","supervisor","totalItems","paused","timeScale","virtualNow","kids","c","h","delayMs","due","p","a","b","s","delayFor","delay","i","createStagger","factory","runStagger","createSupervisor","watchCompletion","items","opts","makeBuilder","animator","composite","ms","fire","child","item","resolvePerItem","v","itemId","id","springPose","adapter","poseFn"],"sources":["../../src/animation/stagger.ts"],"sourcesContent":["import { springPose } from './poseHelpers';\nimport type { Supervisor, SupervisorFactory, WatchCompletion } from './supervisor';\nimport type {\n AnimationHandle,\n Animator,\n StaggerBuilder,\n StaggerDelay,\n StaggerFactory,\n StaggerOptions,\n StaggerPerItem,\n StaggerSpringPoseOptions,\n StaggerTweenOptions,\n} from './types';\nimport type { SceneAdapter } from 'core/adapters/types';\n\n/** An item still waiting: `fire` starts it once the stagger's own virtual\n * time reaches `at`. */\ninterface PendingEntry {\n at: number;\n fire: () => void;\n}\n\n/**\n * Composite handle returned by `createStagger`. Owns a list of in-flight\n * child handles and a list of items still waiting; cancel cancels both.\n * Pause/resume/setTimeScale propagate to in-flight children. The waiting\n * items are counted in the supervisor entry's virtual time, so whatever\n * holds or scales that entry holds or scales the delays with it.\n *\n * Registered with the animator via a supervisor so animator.cancel /\n * cancelKey / isActive all work for it.\n */\nclass CompositeHandle implements AnimationHandle {\n readonly id: number;\n private cancelled = false;\n private paused_ = false;\n private timeScale_ = 1;\n private children: AnimationHandle[] = [];\n private pending: PendingEntry[] = [];\n private outstanding: number;\n private finished = false;\n\n constructor(\n private supervisor: Supervisor,\n totalItems: number,\n ) {\n this.id = supervisor.id;\n this.outstanding = totalItems;\n supervisor.setOnCancel(() => this.handleSupervisorCancel());\n supervisor.setOnRate((paused, timeScale) => {\n if (paused) this.applyPause();\n else this.applyResume();\n this.applyTimeScale(timeScale);\n });\n supervisor.setOnFrame((virtualNow) => this.fireDue(virtualNow));\n }\n\n /** Invoked when the supervisor is cancelled externally (animator.cancel /\n * cancelKey) OR via this composite's own `cancel`. */\n private handleSupervisorCancel(): void {\n if (this.cancelled) return;\n this.cancelled = true;\n this.pending = [];\n // Snapshot children first: child.cancel() may synchronously invoke our\n // own noteChildDone path via the animator's completion listener, which\n // would mutate this.children mid-iteration.\n const kids = this.children.slice();\n this.children = [];\n for (const c of kids) c.cancel();\n }\n\n noteChildDone(): void {\n if (this.cancelled || this.finished) return;\n this.outstanding -= 1;\n if (this.outstanding <= 0) {\n this.finished = true;\n this.children = [];\n this.supervisor.finish();\n }\n }\n\n addChild(h: AnimationHandle): void {\n if (this.cancelled) {\n h.cancel();\n return;\n }\n this.children.push(h);\n if (this.paused_) h.pause();\n if (this.timeScale_ !== 1) h.setTimeScale(this.timeScale_);\n }\n\n schedule(delayMs: number, fire: () => void): void {\n if (this.cancelled) return;\n this.pending.push({ at: delayMs, fire });\n }\n\n private fireDue(virtualNow: number): void {\n if (this.cancelled || this.pending.length === 0) return;\n const due = this.pending.filter((p) => p.at <= virtualNow).sort((a, b) => a.at - b.at);\n this.pending = this.pending.filter((p) => p.at > virtualNow);\n for (const p of due) {\n if (this.cancelled) return;\n p.fire();\n }\n }\n\n cancel(): void {\n // Route through the supervisor so the animator's id table is kept in\n // sync. The supervisor's onCancel forwards back to\n // handleSupervisorCancel which actually tears down children + waiting items.\n this.supervisor.cancel();\n }\n\n pause(): void {\n this.supervisor.pause();\n }\n\n resume(): void {\n this.supervisor.resume();\n }\n\n setTimeScale(s: number): void {\n this.supervisor.setTimeScale(s);\n }\n\n private applyPause(): void {\n if (this.paused_) return;\n this.paused_ = true;\n for (const c of this.children) c.pause();\n }\n\n private applyResume(): void {\n if (!this.paused_) return;\n this.paused_ = false;\n for (const c of this.children) c.resume();\n }\n\n private applyTimeScale(s: number): void {\n if (s === this.timeScale_) return;\n this.timeScale_ = s;\n for (const c of this.children) c.setTimeScale(s);\n }\n\n timeScale(): number {\n return this.timeScale_;\n }\n\n isPaused(): boolean {\n return this.paused_;\n }\n}\n\nfunction delayFor(delay: StaggerDelay, i: number): number {\n return typeof delay === 'function' ? delay(i) : delay * i;\n}\n\n/**\n * Stagger primitive. With `factory`, returns the composite handle directly.\n * Without `factory`, returns a `StaggerBuilder` whose `.each` runs the\n * stagger with a factory.\n */\nexport function createStagger<TItem>(\n animator: Animator,\n createSupervisor: SupervisorFactory,\n watchCompletion: WatchCompletion,\n items: readonly TItem[],\n delay: StaggerDelay,\n factory: StaggerFactory<TItem>,\n opts?: StaggerOptions,\n): AnimationHandle;\nexport function createStagger<TItem>(\n animator: Animator,\n createSupervisor: SupervisorFactory,\n watchCompletion: WatchCompletion,\n items: readonly TItem[],\n delay: StaggerDelay,\n): StaggerBuilder<TItem>;\nexport function createStagger<TItem>(\n animator: Animator,\n createSupervisor: SupervisorFactory,\n watchCompletion: WatchCompletion,\n items: readonly TItem[],\n delay: StaggerDelay,\n factory?: StaggerFactory<TItem>,\n opts?: StaggerOptions,\n): AnimationHandle | StaggerBuilder<TItem> {\n if (factory) return runStagger(createSupervisor, watchCompletion, items, delay, factory, opts);\n return makeBuilder(animator, createSupervisor, watchCompletion, items, delay);\n}\n\nfunction runStagger<TItem>(\n createSupervisor: SupervisorFactory,\n watchCompletion: WatchCompletion,\n items: readonly TItem[],\n delay: StaggerDelay,\n factory: StaggerFactory<TItem>,\n opts?: StaggerOptions,\n): AnimationHandle {\n const supervisor = createSupervisor({ kind: 'stagger', cancelKey: opts?.cancelKey, label: opts?.label });\n const composite = new CompositeHandle(supervisor, items.length);\n if (items.length === 0) {\n supervisor.finish();\n return composite;\n }\n items.forEach((item, i) => {\n const ms = delayFor(delay, i);\n const fire = (): void => {\n const child = factory(item, i);\n // Hook into the child's deregistration (natural OR cancel). If the\n // composite is already cancelled, the watcher fires immediately on\n // cancel and the noteChildDone branch is a no-op (cancelled guard).\n watchCompletion(child.id, () => composite.noteChildDone());\n composite.addChild(child);\n };\n if (ms <= 0) fire();\n else composite.schedule(ms, fire);\n });\n return composite;\n}\n\nfunction resolvePerItem<T, TItem>(\n v: StaggerPerItem<T, TItem>,\n item: TItem,\n i: number,\n): T {\n return typeof v === 'function'\n ? (v as (item: TItem, index: number) => T)(item, i)\n : v;\n}\n\nfunction itemId(item: unknown): string {\n if (item != null && typeof item === 'object' && 'id' in item) {\n const id = (item as { id: unknown }).id;\n if (typeof id === 'string') return id;\n }\n if (typeof item === 'string' || typeof item === 'number') return String(item);\n throw new Error(\n 'stagger().springPose: each item must either be a primitive (string/number) ' +\n 'or have a string `id` field. Otherwise pose ids would collide.',\n );\n}\n\nfunction makeBuilder<TItem>(\n animator: Animator,\n createSupervisor: SupervisorFactory,\n watchCompletion: WatchCompletion,\n items: readonly TItem[],\n delay: StaggerDelay,\n): StaggerBuilder<TItem> {\n return {\n each: (factory, opts) =>\n runStagger(createSupervisor, watchCompletion, items, delay, factory, opts),\n tween: <T,>(opts: StaggerTweenOptions<T, TItem>) =>\n runStagger(createSupervisor, watchCompletion, items, delay, (item, i) =>\n animator.tween<T>({\n from: resolvePerItem(opts.from, item, i),\n to: resolvePerItem(opts.to, item, i),\n ms: resolvePerItem(opts.ms, item, i),\n easing: opts.easing,\n interpolate: opts.interpolate,\n onTick: (v) => opts.onTick(v, item, i),\n onDone: opts.onDone ? () => opts.onDone!(item, i) : undefined,\n }),\n opts,\n ),\n springPose: <TPose,>(\n adapter: SceneAdapter<{ id: string }, TPose>,\n poseFn: (item: TItem, index: number) => TPose,\n opts: StaggerSpringPoseOptions<TPose> = {},\n ) =>\n runStagger(createSupervisor, watchCompletion, items, delay, (item, i) =>\n springPose(animator, adapter, {\n id: itemId(item),\n to: poseFn(item, i),\n preset: opts.preset,\n stiffness: opts.stiffness,\n damping: opts.damping,\n mass: opts.mass,\n geometry: opts.geometry,\n recordOp: opts.recordOp,\n opLabel: opts.opLabel,\n }),\n opts,\n ),\n };\n}\n"],"mappings":"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"}
|
|
@@ -6,101 +6,109 @@ function e(e, t) {
|
|
|
6
6
|
}
|
|
7
7
|
return n;
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
function t(t, n) {
|
|
10
|
+
let r = e(t, n);
|
|
11
|
+
for (; r > 0 && t[r - 1].t === n;) --r;
|
|
12
|
+
return r;
|
|
13
|
+
}
|
|
14
|
+
var n = (e, t) => e.lap > t.lap || e.lap === t.lap && e.r > t.r;
|
|
15
|
+
function r(r, i) {
|
|
16
|
+
let a = r.lookahead ?? 100, o = r.maxLate ?? Infinity, s = /* @__PURE__ */ new Map(), c = {
|
|
12
17
|
lap: 0,
|
|
13
18
|
r: -Infinity
|
|
14
|
-
},
|
|
15
|
-
lap:
|
|
16
|
-
r:
|
|
17
|
-
}),
|
|
18
|
-
|
|
19
|
-
if (!
|
|
19
|
+
}, l = [], u = null, d = 0, f = 0, p = () => ({
|
|
20
|
+
lap: i.lap(),
|
|
21
|
+
r: i.playhead()
|
|
22
|
+
}), m = (e) => (e.lap - i.lap()) * i.duration() + e.r, h = (e) => n(e, p()), g = (e, t) => {
|
|
23
|
+
l = l.filter((n) => {
|
|
24
|
+
if (!n.handle || n.when <= e || !h(n) || !t(n)) return !0;
|
|
20
25
|
try {
|
|
21
|
-
|
|
26
|
+
n.handle.stop();
|
|
22
27
|
} catch (e) {
|
|
23
28
|
console.error("timeline: booking stop threw", e);
|
|
24
29
|
}
|
|
25
30
|
return !1;
|
|
26
31
|
});
|
|
27
|
-
let r =
|
|
28
|
-
for (let [e,
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
let
|
|
32
|
+
let r = p();
|
|
33
|
+
for (let [e, t] of s) n(t, r) && s.set(e, r);
|
|
34
|
+
n(c, r) && (c = r);
|
|
35
|
+
}, _ = (e, t, n, r) => Math.max(u + (e - t) / n, r), v = (n, r, a, u, d, f) => {
|
|
36
|
+
let p = i.lap(), m = i.duration(), h = i.playhead(), { events: g } = n, v = s.get(n) ?? c;
|
|
32
37
|
for (;;) {
|
|
33
|
-
let
|
|
34
|
-
if (
|
|
35
|
-
let
|
|
36
|
-
if (
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
lap: Math.max(
|
|
38
|
+
let n = (v.lap - p) * m;
|
|
39
|
+
if (n > a) break;
|
|
40
|
+
let i = (v.open ? t : e)(g, v.r - r);
|
|
41
|
+
if (i >= g.length || r + g[i].t > m) {
|
|
42
|
+
if (v.lap >= u) break;
|
|
43
|
+
v = {
|
|
44
|
+
lap: Math.max(v.lap + 1, p),
|
|
40
45
|
r: -Infinity
|
|
41
46
|
};
|
|
42
47
|
continue;
|
|
43
48
|
}
|
|
44
|
-
let
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
lap:
|
|
48
|
-
r:
|
|
49
|
+
let s = r + g[i].t, c = n + s;
|
|
50
|
+
if (c > a) break;
|
|
51
|
+
v = {
|
|
52
|
+
lap: v.lap,
|
|
53
|
+
r: s
|
|
49
54
|
};
|
|
50
|
-
for (let e =
|
|
51
|
-
let t =
|
|
52
|
-
if (!t.book ||
|
|
53
|
-
let n =
|
|
55
|
+
for (let e = i; e < g.length && g[e].t === g[i].t; e += 1) {
|
|
56
|
+
let t = g[e];
|
|
57
|
+
if (!t.book || l.some((e) => e.event === t && e.lap === v.lap) || (h - c) / f > o) continue;
|
|
58
|
+
let n = _(c, h, f, d), r;
|
|
54
59
|
try {
|
|
55
60
|
r = t.book(n) ?? void 0;
|
|
56
61
|
} catch (e) {
|
|
57
62
|
console.error("timeline: book threw", e);
|
|
58
63
|
}
|
|
59
|
-
|
|
64
|
+
l.push({
|
|
60
65
|
event: t,
|
|
61
|
-
lap:
|
|
62
|
-
r:
|
|
66
|
+
lap: v.lap,
|
|
67
|
+
r: s,
|
|
63
68
|
when: n,
|
|
64
69
|
handle: r
|
|
65
70
|
});
|
|
66
71
|
}
|
|
67
72
|
}
|
|
68
|
-
|
|
69
|
-
},
|
|
70
|
-
for (let o of e) o.kind === "event" ?
|
|
73
|
+
s.set(n, v);
|
|
74
|
+
}, y = (e, t, n, r, i, a) => {
|
|
75
|
+
for (let o of e) o.kind === "event" ? v(o, t, n, r, i, a) : o.kind === "timeline" && y(o.timeline.tracks, t + o.at, n, r, i, a);
|
|
71
76
|
};
|
|
72
77
|
return {
|
|
73
78
|
tick(e, t) {
|
|
74
|
-
let
|
|
75
|
-
if (
|
|
76
|
-
|
|
79
|
+
let n = r.clock.now();
|
|
80
|
+
if (l = l.filter(h), !(t > 0)) {
|
|
81
|
+
f > 0 && g(n, () => !0), f = 0, u = null;
|
|
77
82
|
return;
|
|
78
83
|
}
|
|
79
|
-
let o =
|
|
80
|
-
if (
|
|
84
|
+
let o = f > 0 && t !== f;
|
|
85
|
+
if (u === null) u = n;
|
|
81
86
|
else {
|
|
82
|
-
|
|
83
|
-
let
|
|
84
|
-
Math.abs(
|
|
87
|
+
u += (e - d) / t;
|
|
88
|
+
let r = n - u;
|
|
89
|
+
Math.abs(r) > 50 ? (u = n, o = !0) : u += r * .05;
|
|
85
90
|
}
|
|
86
|
-
|
|
87
|
-
let s =
|
|
88
|
-
o &&
|
|
89
|
-
let
|
|
90
|
-
|
|
91
|
+
d = e, f = t;
|
|
92
|
+
let s = i.playhead();
|
|
93
|
+
o && g(n, (e) => Math.abs(_(m(e), s, t, n) - e.when) > 1);
|
|
94
|
+
let c = i.duration(), p = i.lap() + (c > 0 ? i.lapsLeft() : 0);
|
|
95
|
+
y(i.tracks, 0, s + a * t, p, n, t);
|
|
91
96
|
},
|
|
92
97
|
retract() {
|
|
93
|
-
|
|
98
|
+
g(r.clock.now(), () => !0);
|
|
94
99
|
},
|
|
95
100
|
seek() {
|
|
96
|
-
|
|
101
|
+
l = [], s.clear(), c = {
|
|
102
|
+
...p(),
|
|
103
|
+
open: !0
|
|
104
|
+
};
|
|
97
105
|
},
|
|
98
106
|
rearm() {
|
|
99
|
-
|
|
107
|
+
u = null;
|
|
100
108
|
}
|
|
101
109
|
};
|
|
102
110
|
}
|
|
103
111
|
//#endregion
|
|
104
|
-
export {
|
|
112
|
+
export { r as createBooker, e as firstAfter, t as firstAtOrAfter };
|
|
105
113
|
|
|
106
114
|
//# sourceMappingURL=booking.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"booking.js","names":["firstAfter","lo","hi","events","mid","isAfter","a","b","createBooker","lookahead","opts","maxLate","cursors","start","bookings","est","mapVirtual","lastScale","playheadCursor","host","unwrapped","ahead","stopWhere","now","pred","err","at","track","c","whenFor","u","playhead","scale","scanTrack","lap","duration","lapStart","horizon","i","lastLap","r","j","ev","when","handle","visit","tracks","moved","virtualNow","residual"],"sources":["../../../src/animation/timeline/booking.ts"],"sourcesContent":["import type { EventBooking, EventBookingHandle, EventTrack, TimelineEvent, Track } from './types';\n\n/** A clock read further than this from the frame clock's prediction is taken\n * as a discontinuity — a hidden tab, a suspended context — not as jitter. */\nconst RESYNC_MS = 50;\n/** Share of each frame's clock residual folded into the estimate. Small enough\n * to average out a per-frame read that lands a render quantum early or late;\n * large enough to follow ppm-scale drift with well under a millisecond of lag. */\nconst SLEW = 0.05;\n/** A pending booking a rate change or resync moves by more than this is\n * retracted and booked again; anything less is left standing. */\nconst RETIME_MS = 1;\n\n/** Index of the first event after `t`. Binary search: tracks may be long. */\nexport function firstAfter(events: EventTrack['events'], t: number): number {\n let lo = 0;\n let hi = events.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (events[mid].t > t) hi = mid; else lo = mid + 1;\n }\n return lo;\n}\n\n/** The timeline state a booker reads. `lap` counts wraps since creation and is\n * never reset, so a (lap, root time) pair names one crossing for good. */\nexport interface BookerHost {\n tracks: Track[];\n duration(): number;\n /** Laps still allowed after the current one; `Infinity` when endless. */\n lapsLeft(): number;\n lap(): number;\n playhead(): number;\n}\n\nexport interface Booker {\n /** After the frame's wraps and crossings. `scale` is the effective one this\n * frame's virtual time advanced at, zero while paused. */\n tick(virtualNow: number, scale: number): void;\n /** Stop every booking still ahead of both the playhead and the clock, and\n * let the next tick book that span again. */\n retract(): void;\n /** After the playhead jumped. Call `retract` first, while it still reads the\n * old playhead. */\n seek(): void;\n /** After the animator restarted the timeline's virtual clock at zero. */\n rearm(): void;\n}\n\n/** Every event at root time `<= r` in lap `lap` has been taken. */\ninterface Cursor { lap: number; r: number }\n\ninterface Booking {\n event: TimelineEvent;\n lap: number;\n r: number;\n when: number;\n handle?: EventBookingHandle;\n}\n\nconst isAfter = (a: Cursor, b: Cursor): boolean => a.lap > b.lap || (a.lap === b.lap && a.r > b.r);\n\nexport function createBooker(opts: EventBooking, host: BookerHost): Booker {\n const lookahead = opts.lookahead ?? 100;\n const maxLate = opts.maxLate ?? Infinity;\n const cursors = new Map<EventTrack, Cursor>();\n let start: Cursor = { lap: 0, r: -Infinity };\n let bookings: Booking[] = [];\n /** Clock time of the current frame, smoothed. Null until anchored. */\n let est: number | null = null;\n let mapVirtual = 0;\n let lastScale = 0;\n\n const playheadCursor = (): Cursor => ({ lap: host.lap(), r: host.playhead() });\n\n const unwrapped = (b: { lap: number; r: number }): number =>\n (b.lap - host.lap()) * host.duration() + b.r;\n\n const ahead = (b: Booking): boolean => isAfter(b, playheadCursor());\n\n const stopWhere = (now: number, pred: (b: Booking) => boolean): void => {\n bookings = bookings.filter((b) => {\n if (!b.handle || b.when <= now || !ahead(b) || !pred(b)) return true;\n try { b.handle.stop(); } catch (err) { console.error('timeline: booking stop threw', err); }\n return false;\n });\n // Back to the playhead, not to each retracted booking: whatever still\n // stands is skipped by identity, and an edit may have added events behind\n // the cursor that only a rescan finds.\n const at = playheadCursor();\n for (const [track, c] of cursors) if (isAfter(c, at)) cursors.set(track, at);\n if (isAfter(start, at)) start = at;\n };\n\n const whenFor = (u: number, playhead: number, scale: number, now: number): number =>\n Math.max(est! + (u - playhead) / scale, now);\n\n const scanTrack = (\n track: EventTrack, at: number, horizon: number, lastLap: number, now: number, scale: number,\n ): void => {\n const lap = host.lap();\n const duration = host.duration();\n const playhead = host.playhead();\n const { events } = track;\n let c = cursors.get(track) ?? start;\n for (;;) {\n const lapStart = (c.lap - lap) * duration;\n if (lapStart > horizon) break;\n const i = firstAfter(events, c.r - at);\n if (i >= events.length || at + events[i].t > duration) {\n if (c.lap >= lastLap) break;\n // A frame that skipped whole laps books the outgoing lap's tail and\n // nothing of the laps in between, as crossings do.\n c = { lap: Math.max(c.lap + 1, lap), r: -Infinity };\n continue;\n }\n const r = at + events[i].t;\n const u = lapStart + r;\n if (u > horizon) break;\n c = { lap: c.lap, r };\n for (let j = i; j < events.length && events[j].t === events[i].t; j += 1) {\n const ev = events[j];\n if (!ev.book || bookings.some((b) => b.event === ev && b.lap === c.lap)) continue;\n if ((playhead - u) / scale > maxLate) continue;\n const when = whenFor(u, playhead, scale, now);\n let handle: EventBookingHandle | undefined;\n try {\n handle = ev.book(when) ?? undefined;\n } catch (err) {\n console.error('timeline: book threw', err);\n }\n bookings.push({ event: ev, lap: c.lap, r, when, handle });\n }\n }\n cursors.set(track, c);\n };\n\n const visit = (\n tracks: Track[], at: number, horizon: number, lastLap: number, now: number, scale: number,\n ): void => {\n for (const track of tracks) {\n if (track.kind === 'event') scanTrack(track, at, horizon, lastLap, now, scale);\n else if (track.kind === 'timeline') {\n visit(track.timeline.tracks, at + track.at, horizon, lastLap, now, scale);\n }\n }\n };\n\n return {\n tick(virtualNow, scale) {\n const now = opts.clock.now();\n bookings = bookings.filter(ahead);\n if (!(scale > 0)) {\n if (lastScale > 0) stopWhere(now, () => true);\n lastScale = 0;\n est = null;\n return;\n }\n\n let moved = lastScale > 0 && scale !== lastScale;\n if (est === null) {\n est = now;\n } else {\n est += (virtualNow - mapVirtual) / scale;\n const residual = now - est;\n if (Math.abs(residual) > RESYNC_MS) {\n est = now;\n moved = true;\n } else {\n est += residual * SLEW;\n }\n }\n mapVirtual = virtualNow;\n lastScale = scale;\n\n const playhead = host.playhead();\n if (moved) {\n stopWhere(now, (b) => Math.abs(whenFor(unwrapped(b), playhead, scale, now) - b.when) > RETIME_MS);\n }\n\n const duration = host.duration();\n const lastLap = host.lap() + (duration > 0 ? host.lapsLeft() : 0);\n visit(host.tracks, 0, playhead + lookahead * scale, lastLap, now, scale);\n },\n retract() {\n stopWhere(opts.clock.now(), () => true);\n },\n seek() {\n bookings = [];\n cursors.clear();\n start = playheadCursor();\n },\n rearm() {\n est = null;\n },\n };\n}\n"],"mappings":"AAcA,SAAgBA,EAAW,GAA8B,GAAmB;CAC1E,IAAIC,IAAK,GACLC,IAAKC,EAAO;CAChB,OAAOF,IAAKC,IAAI;EACd,IAAME,IAAOH,IAAKC,KAAO;EACzB,AAAIC,EAAOC,EAAI,CAAC,IAAI,IAAG,IAAKA,IAAU,IAAKA,IAAM;CACnD;CACA,OAAOH;AACT;AAsCA,IAAMI,KAAW,GAAW,MAAuBC,EAAE,MAAMC,EAAE,OAAQD,EAAE,QAAQC,EAAE,OAAOD,EAAE,IAAIC,EAAE;AAEhG,SAAgBC,EAAa,GAAoB,GAA0B;CACzE,IAAMC,IAAYC,EAAK,aAAa,KAC9BC,IAAUD,EAAK,WAAW,UAC1BE,oBAAU,IAAI,IAAwB,GACxCC,IAAgB;EAAE,KAAK;EAAG,GAAG;CAAU,GACvCC,IAAsB,CAAC,GAEvBC,IAAqB,MACrBC,IAAa,GACbC,IAAY,GAEVC,WAAgC;EAAE,KAAKC,EAAK,IAAI;EAAG,GAAGA,EAAK,SAAS;CAAE,IAEtEC,KAAa,OAChBb,EAAE,MAAMY,EAAK,IAAI,KAAKA,EAAK,SAAS,IAAIZ,EAAE,GAEvCc,KAAS,MAAwBhB,EAAQE,GAAGW,EAAe,CAAC,GAE5DI,KAAa,GAAa,MAAwC;EACtE,IAAWR,EAAS,QAAQ,MAAM;GAChC,IAAI,CAACP,EAAE,UAAUA,EAAE,QAAQgB,KAAO,CAACF,EAAMd,CAAC,KAAK,CAACiB,EAAKjB,CAAC,GAAG,OAAO;GAChE,IAAI;IAAE,EAAE,OAAO,KAAK;GAAG,SAASkB,GAAK;IAAE,QAAQ,MAAM,gCAAgCA,CAAG;GAAG;GAC3F,OAAO;EACT,CAAC;EAID,IAAMC,IAAKR,EAAe;EAC1B,KAAK,IAAM,CAACS,GAAOC,MAAMhB,GAAS,AAAIP,EAAQuB,GAAGF,CAAE,KAAGd,EAAQ,IAAIe,GAAOD,CAAE;EAC3E,AAAIrB,EAAQQ,GAAOa,CAAE,MAAG,IAAQA;CAClC,GAEMG,KAAW,GAAW,GAAkB,GAAe,MAC3D,KAAK,IAAId,KAAQe,IAAIC,KAAYC,GAAOT,CAAG,GAEvCU,KACJ,GAAmB,GAAY,GAAiB,GAAiB,GAAa,MACrE;EACT,IAAMC,IAAMf,EAAK,IAAI,GACfgB,IAAWhB,EAAK,SAAS,GACzBY,IAAWZ,EAAK,SAAS,GACzB,EAAE,cAAWQ,GACfC,IAAIhB,EAAQ,IAAIe,CAAK,KAAKd;EAC9B,SAAS;GACP,IAAMuB,KAAYR,EAAE,MAAMM,KAAOC;GACjC,IAAIC,IAAWC,GAAS;GACxB,IAAMC,IAAItC,EAAWG,GAAQyB,EAAE,IAAIF,CAAE;GACrC,IAAIY,KAAKnC,EAAO,UAAUuB,IAAKvB,EAAOmC,EAAE,CAAC,IAAIH,GAAU;IACrD,IAAIP,EAAE,OAAOW,GAAS;IAGtB,IAAI;KAAE,KAAK,KAAK,IAAIX,EAAE,MAAM,GAAGM,CAAG;KAAG,GAAG;IAAU;IAClD;GACF;GACA,IAAMM,IAAId,IAAKvB,EAAOmC,EAAE,CAAC,GACnBR,IAAIM,IAAWI;GACrB,IAAIV,IAAIO,GAAS;GACjB,IAAI;IAAE,KAAKT,EAAE;IAAK;GAAE;GACpB,KAAK,IAAIa,IAAIH,GAAGG,IAAItC,EAAO,UAAUA,EAAOsC,EAAE,CAAC,MAAMtC,EAAOmC,EAAE,CAAC,GAAG,KAAK,GAAG;IACxE,IAAMI,IAAKvC,EAAOsC;IAElB,IADI,CAACC,EAAG,QAAQ5B,EAAS,MAAM,MAAMP,EAAE,UAAUmC,KAAMnC,EAAE,QAAQqB,EAAE,GAAG,MACjEG,IAAWD,KAAKE,IAAQrB,GAAS;IACtC,IAAMgC,IAAOd,EAAQC,GAAGC,GAAUC,GAAOT,CAAG,GACxCqB;IACJ,IAAI;KACF,IAASF,EAAG,KAAKC,CAAI,KAAK,KAAA;IAC5B,SAASlB,GAAK;KACZ,QAAQ,MAAM,wBAAwBA,CAAG;IAC3C;IACA,EAAS,KAAK;KAAE,OAAOiB;KAAI,KAAKd,EAAE;KAAK;KAAG;KAAM;IAAO,CAAC;GAC1D;EACF;EACA,EAAQ,IAAID,GAAOC,CAAC;CACtB,GAEMiB,KACJ,GAAiB,GAAY,GAAiB,GAAiB,GAAa,MACnE;EACT,KAAK,IAAMlB,KAASmB,GAClB,AAAInB,EAAM,SAAS,UAASM,EAAUN,GAAOD,GAAIW,GAASE,GAAShB,GAAKS,CAAK,IACpEL,EAAM,SAAS,cACtBkB,EAAMlB,EAAM,SAAS,QAAQD,IAAKC,EAAM,IAAIU,GAASE,GAAShB,GAAKS,CAAK;CAG9E;CAEA,OAAO;EACL,KAAK,GAAY,GAAO;GACtB,IAAMT,IAAMb,EAAK,MAAM,IAAI;GAE3B,IADA,IAAWI,EAAS,OAAOO,CAAK,GAC5B,EAAEW,IAAQ,IAAI;IAGhB,AAFIf,IAAY,KAAGK,EAAUC,SAAW,EAAI,GAC5C,IAAY,GACZ,IAAM;IACN;GACF;GAEA,IAAIwB,IAAQ9B,IAAY,KAAKe,MAAUf;GACvC,IAAIF,MAAQ,MACV,IAAMQ;QACD;IACL,MAAQyB,IAAahC,KAAcgB;IACnC,IAAMiB,IAAW1B,IAAMR;IACvB,AAAI,KAAK,IAAIkC,CAAQ,IAAI,MACvB,IAAM1B,GACN,IAAQ,MAER,KAAO0B,IAAW;GAEtB;GAEA,AADA,IAAaD,GACb,IAAYhB;GAEZ,IAAMD,IAAWZ,EAAK,SAAS;GAC/B,AAAI4B,KACFzB,EAAUC,IAAM,MAAM,KAAK,IAAIM,EAAQT,EAAUb,CAAC,GAAGwB,GAAUC,GAAOT,CAAG,IAAIhB,EAAE,IAAI,IAAI,CAAS;GAGlG,IAAM4B,IAAWhB,EAAK,SAAS,GACzBoB,IAAUpB,EAAK,IAAI,KAAKgB,IAAW,IAAIhB,EAAK,SAAS,IAAI;GAC/D,EAAMA,EAAK,QAAQ,GAAGY,IAAWtB,IAAYuB,GAAOO,GAAShB,GAAKS,CAAK;EACzE;EACA,UAAU;GACR,EAAUtB,EAAK,MAAM,IAAI,SAAS,EAAI;EACxC;EACA,OAAO;GAGL,AAFA,IAAW,CAAC,GACZE,EAAQ,MAAM,GACd,IAAQM,EAAe;EACzB;EACA,QAAQ;GACN,IAAM;EACR;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"booking.js","names":["firstAfter","lo","hi","events","mid","firstAtOrAfter","i","t","isAfter","a","b","createBooker","lookahead","opts","maxLate","cursors","start","bookings","est","mapVirtual","lastScale","playheadCursor","host","unwrapped","ahead","stopWhere","now","pred","err","at","track","c","whenFor","u","playhead","scale","scanTrack","lap","duration","lapStart","horizon","lastLap","r","j","ev","when","handle","visit","tracks","moved","virtualNow","residual"],"sources":["../../../src/animation/timeline/booking.ts"],"sourcesContent":["import type { EventBooking, EventBookingHandle, EventTrack, TimelineEvent, Track } from './types';\n\n/** A clock read further than this from the frame clock's prediction is taken\n * as a discontinuity — a hidden tab, a suspended context — not as jitter. */\nconst RESYNC_MS = 50;\n/** Share of each frame's clock residual folded into the estimate. Small enough\n * to average out a per-frame read that lands a render quantum early or late;\n * large enough to follow ppm-scale drift with well under a millisecond of lag. */\nconst SLEW = 0.05;\n/** A pending booking a rate change or resync moves by more than this is\n * retracted and booked again; anything less is left standing. */\nconst RETIME_MS = 1;\n\n/** Index of the first event after `t`. Binary search: tracks may be long. */\nexport function firstAfter(events: EventTrack['events'], t: number): number {\n let lo = 0;\n let hi = events.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (events[mid].t > t) hi = mid; else lo = mid + 1;\n }\n return lo;\n}\n\n/** Index of the first event at or after `t`. */\nexport function firstAtOrAfter(events: EventTrack['events'], t: number): number {\n let i = firstAfter(events, t);\n while (i > 0 && events[i - 1].t === t) i -= 1;\n return i;\n}\n\n/** The timeline state a booker reads. `lap` counts wraps since creation and is\n * never reset, so a (lap, root time) pair names one crossing for good. */\nexport interface BookerHost {\n tracks: Track[];\n duration(): number;\n /** Laps still allowed after the current one; `Infinity` when endless. */\n lapsLeft(): number;\n lap(): number;\n playhead(): number;\n}\n\nexport interface Booker {\n /** After the frame's wraps and crossings. `scale` is the effective one this\n * frame's virtual time advanced at, zero while paused. */\n tick(virtualNow: number, scale: number): void;\n /** Stop every booking still ahead of both the playhead and the clock, and\n * let the next tick book that span again. */\n retract(): void;\n /** After the playhead jumped. Call `retract` first, while it still reads the\n * old playhead. */\n seek(): void;\n /** After the animator restarted the timeline's virtual clock at zero. */\n rearm(): void;\n}\n\n/** Every event at root time `<= r` in lap `lap` has been taken; with `open`,\n * only those before `r`, which is where a seek leaves the cursor. */\ninterface Cursor { lap: number; r: number; open?: boolean }\n\ninterface Booking {\n event: TimelineEvent;\n lap: number;\n r: number;\n when: number;\n handle?: EventBookingHandle;\n}\n\nconst isAfter = (a: Cursor, b: Cursor): boolean => a.lap > b.lap || (a.lap === b.lap && a.r > b.r);\n\nexport function createBooker(opts: EventBooking, host: BookerHost): Booker {\n const lookahead = opts.lookahead ?? 100;\n const maxLate = opts.maxLate ?? Infinity;\n const cursors = new Map<EventTrack, Cursor>();\n let start: Cursor = { lap: 0, r: -Infinity };\n let bookings: Booking[] = [];\n /** Clock time of the current frame, smoothed. Null until anchored. */\n let est: number | null = null;\n let mapVirtual = 0;\n let lastScale = 0;\n\n const playheadCursor = (): Cursor => ({ lap: host.lap(), r: host.playhead() });\n\n const unwrapped = (b: { lap: number; r: number }): number =>\n (b.lap - host.lap()) * host.duration() + b.r;\n\n const ahead = (b: Booking): boolean => isAfter(b, playheadCursor());\n\n const stopWhere = (now: number, pred: (b: Booking) => boolean): void => {\n bookings = bookings.filter((b) => {\n if (!b.handle || b.when <= now || !ahead(b) || !pred(b)) return true;\n try { b.handle.stop(); } catch (err) { console.error('timeline: booking stop threw', err); }\n return false;\n });\n // Back to the playhead, not to each retracted booking: whatever still\n // stands is skipped by identity, and an edit may have added events behind\n // the cursor that only a rescan finds.\n const at = playheadCursor();\n for (const [track, c] of cursors) if (isAfter(c, at)) cursors.set(track, at);\n if (isAfter(start, at)) start = at;\n };\n\n const whenFor = (u: number, playhead: number, scale: number, now: number): number =>\n Math.max(est! + (u - playhead) / scale, now);\n\n const scanTrack = (\n track: EventTrack, at: number, horizon: number, lastLap: number, now: number, scale: number,\n ): void => {\n const lap = host.lap();\n const duration = host.duration();\n const playhead = host.playhead();\n const { events } = track;\n let c = cursors.get(track) ?? start;\n for (;;) {\n const lapStart = (c.lap - lap) * duration;\n if (lapStart > horizon) break;\n const i = (c.open ? firstAtOrAfter : firstAfter)(events, c.r - at);\n if (i >= events.length || at + events[i].t > duration) {\n if (c.lap >= lastLap) break;\n // A frame that skipped whole laps books the outgoing lap's tail and\n // nothing of the laps in between, as crossings do.\n c = { lap: Math.max(c.lap + 1, lap), r: -Infinity };\n continue;\n }\n const r = at + events[i].t;\n const u = lapStart + r;\n if (u > horizon) break;\n c = { lap: c.lap, r };\n for (let j = i; j < events.length && events[j].t === events[i].t; j += 1) {\n const ev = events[j];\n if (!ev.book || bookings.some((b) => b.event === ev && b.lap === c.lap)) continue;\n if ((playhead - u) / scale > maxLate) continue;\n const when = whenFor(u, playhead, scale, now);\n let handle: EventBookingHandle | undefined;\n try {\n handle = ev.book(when) ?? undefined;\n } catch (err) {\n console.error('timeline: book threw', err);\n }\n bookings.push({ event: ev, lap: c.lap, r, when, handle });\n }\n }\n cursors.set(track, c);\n };\n\n const visit = (\n tracks: Track[], at: number, horizon: number, lastLap: number, now: number, scale: number,\n ): void => {\n for (const track of tracks) {\n if (track.kind === 'event') scanTrack(track, at, horizon, lastLap, now, scale);\n else if (track.kind === 'timeline') {\n visit(track.timeline.tracks, at + track.at, horizon, lastLap, now, scale);\n }\n }\n };\n\n return {\n tick(virtualNow, scale) {\n const now = opts.clock.now();\n bookings = bookings.filter(ahead);\n if (!(scale > 0)) {\n if (lastScale > 0) stopWhere(now, () => true);\n lastScale = 0;\n est = null;\n return;\n }\n\n let moved = lastScale > 0 && scale !== lastScale;\n if (est === null) {\n est = now;\n } else {\n est += (virtualNow - mapVirtual) / scale;\n const residual = now - est;\n if (Math.abs(residual) > RESYNC_MS) {\n est = now;\n moved = true;\n } else {\n est += residual * SLEW;\n }\n }\n mapVirtual = virtualNow;\n lastScale = scale;\n\n const playhead = host.playhead();\n if (moved) {\n stopWhere(now, (b) => Math.abs(whenFor(unwrapped(b), playhead, scale, now) - b.when) > RETIME_MS);\n }\n\n const duration = host.duration();\n const lastLap = host.lap() + (duration > 0 ? host.lapsLeft() : 0);\n visit(host.tracks, 0, playhead + lookahead * scale, lastLap, now, scale);\n },\n retract() {\n stopWhere(opts.clock.now(), () => true);\n },\n seek() {\n bookings = [];\n cursors.clear();\n start = { ...playheadCursor(), open: true };\n },\n rearm() {\n est = null;\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,116 +1,125 @@
|
|
|
1
|
-
import { createBooker as e, firstAfter as t } from "./booking.js";
|
|
2
|
-
import { sampleTrack as
|
|
1
|
+
import { createBooker as e, firstAfter as t, firstAtOrAfter as n } from "./booking.js";
|
|
2
|
+
import { sampleTrack as r } from "./sampleTrack.js";
|
|
3
3
|
//#region src/animation/timeline/createTimeline.ts
|
|
4
|
-
function
|
|
4
|
+
function i(e) {
|
|
5
5
|
switch (e.kind) {
|
|
6
6
|
case "sampled": return e.keys.length ? e.keys[e.keys.length - 1].t : 0;
|
|
7
7
|
case "event": return e.events.length ? e.events[e.events.length - 1].t : 0;
|
|
8
|
-
case "timeline": return e.at +
|
|
8
|
+
case "timeline": return e.at + a(e.timeline.tracks, e.timeline.duration);
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
function
|
|
11
|
+
function a(e, t) {
|
|
12
12
|
if (t != null) return t;
|
|
13
13
|
let n = 0;
|
|
14
|
-
for (let t of e) n = Math.max(n,
|
|
14
|
+
for (let t of e) n = Math.max(n, i(t));
|
|
15
15
|
return n;
|
|
16
16
|
}
|
|
17
|
-
function
|
|
18
|
-
let
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
function o(i, o, s, c) {
|
|
18
|
+
let l = a(s.tracks, s.duration), u = 0, d = 0, f = 0, p = -Infinity, m = !1, h = !1, g = !1, _ = !0, v = !1, y = s.autoplay === !1, b = 1, x = /* @__PURE__ */ new Set(), S = /* @__PURE__ */ new Set(), C = (e) => {
|
|
19
|
+
for (let t of e) try {
|
|
20
|
+
t();
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.error("timeline: subscriber threw", e);
|
|
23
|
+
}
|
|
24
|
+
}, w = () => C(S), T = s.loop ?? !1, E = T === !0 ? Infinity : T === !1 ? 0 : T, D = 0, O = s.booking ? e(s.booking, {
|
|
25
|
+
tracks: s.tracks,
|
|
26
|
+
duration: () => l,
|
|
27
|
+
lapsLeft: () => E,
|
|
28
|
+
lap: () => D,
|
|
29
|
+
playhead: () => f
|
|
30
|
+
}) : null, k = !1, A = /* @__PURE__ */ new WeakMap(), j = (e) => {
|
|
31
|
+
let t = A.get(e);
|
|
32
|
+
return t || (t = /* @__PURE__ */ new Map(), A.set(e, t)), t;
|
|
33
|
+
}, M = (e, t) => {
|
|
34
|
+
for (let n of e) if (n.kind === "sampled") {
|
|
35
|
+
let e = n, i = r(e, t, j(e));
|
|
30
36
|
i !== void 0 && e.onTick(i);
|
|
31
|
-
} else
|
|
32
|
-
},
|
|
33
|
-
for (let
|
|
34
|
-
let
|
|
35
|
-
if (
|
|
36
|
-
let e = t(a.events, r);
|
|
37
|
-
for (let
|
|
38
|
-
let e =
|
|
39
|
-
e.fire?.(
|
|
37
|
+
} else n.kind === "timeline" && M(n.timeline.tracks, t - n.at);
|
|
38
|
+
}, N = [], P = (e, r, i, a) => {
|
|
39
|
+
for (let o = 0; o < e.length; o += 1) {
|
|
40
|
+
let s = e[o];
|
|
41
|
+
if (s.kind === "event") {
|
|
42
|
+
let e = t(s.events, i), l = (a ? n : t)(s.events, r);
|
|
43
|
+
for (let t = l; t < e; t += 1) {
|
|
44
|
+
let e = s.events[t];
|
|
45
|
+
e.fire?.(i - e.t), c?.watched && (N.push(o), c.fire(s, N, e, i - e.t), N.pop()), e.book && !O && !k && (k = !0, console.warn("timeline: an event has `book` but the timeline has no `booking` clock; it never books."));
|
|
40
46
|
}
|
|
41
|
-
} else
|
|
47
|
+
} else s.kind === "timeline" && (N.push(o), P(s.timeline.tracks, r - s.at, i - s.at, a), N.pop());
|
|
42
48
|
}
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
}, F = () => {
|
|
50
|
+
h || P(s.tracks, p, l, m), p = -Infinity, m = !1, c?.watched && c.lap(D);
|
|
51
|
+
}, I = (e, t) => {
|
|
52
|
+
d = e, f = e + u;
|
|
53
|
+
let n = t ?? (z.isPaused() ? 0 : z.timeScale());
|
|
54
|
+
if (h = n === 0, l > 0 && f >= l) {
|
|
55
|
+
if (E === Infinity) {
|
|
56
|
+
let e = Math.floor(f / l);
|
|
57
|
+
u -= e * l, f -= e * l, D += e, F();
|
|
58
|
+
} else for (; f >= l && E > 0;) --E, u -= l, f -= l, D += 1, F();
|
|
51
59
|
}
|
|
52
|
-
let
|
|
53
|
-
return
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
let r = f >= l;
|
|
61
|
+
return f = Math.min(f, l), M(s.tracks, f), h || (P(s.tracks, p, f, m), p = f, m = !1), O?.tick(e, n), r && !g && (g = !0, s.onDone?.(), w()), f < l ? !1 : (_ = !1, !0);
|
|
62
|
+
}, L = () => {
|
|
63
|
+
let e = !v;
|
|
64
|
+
v = !0, _ = !1, O?.retract(), e && w();
|
|
65
|
+
}, R = {
|
|
66
|
+
id: o,
|
|
67
|
+
cancelKey: s.cancelKey,
|
|
68
|
+
tick: I,
|
|
69
|
+
onCancel: L,
|
|
61
70
|
kind: "timeline",
|
|
62
|
-
label:
|
|
63
|
-
progress: () =>
|
|
64
|
-
},
|
|
65
|
-
|
|
66
|
-
let
|
|
67
|
-
|
|
68
|
-
...
|
|
71
|
+
label: s.label,
|
|
72
|
+
progress: () => l > 0 ? f / l : 1
|
|
73
|
+
}, z = i(R);
|
|
74
|
+
s.autoplay === !1 && z.pause();
|
|
75
|
+
let B = () => {
|
|
76
|
+
v || f >= l || (g = !1, !_ && (O?.rearm(), d = 0, u = f, _ = !0, i({
|
|
77
|
+
...R,
|
|
69
78
|
keepExisting: !0
|
|
70
|
-
}),
|
|
79
|
+
}), y && z.pause(), z.setTimeScale(b)));
|
|
71
80
|
};
|
|
72
81
|
return {
|
|
73
|
-
...
|
|
82
|
+
...z,
|
|
74
83
|
cancel() {
|
|
75
|
-
|
|
84
|
+
L(), z.cancel();
|
|
76
85
|
},
|
|
77
86
|
pause() {
|
|
78
|
-
|
|
87
|
+
y = !0, z.pause(), O?.retract(), w();
|
|
79
88
|
},
|
|
80
89
|
resume() {
|
|
81
|
-
|
|
90
|
+
y = !1, z.resume(), w();
|
|
82
91
|
},
|
|
83
92
|
setTimeScale(e) {
|
|
84
|
-
|
|
93
|
+
b = e, z.setTimeScale(e), w();
|
|
85
94
|
},
|
|
86
|
-
timeScale: () =>
|
|
87
|
-
isPaused: () =>
|
|
95
|
+
timeScale: () => _ ? z.timeScale() : b,
|
|
96
|
+
isPaused: () => _ ? z.isPaused() : y,
|
|
88
97
|
seek(e) {
|
|
89
|
-
|
|
98
|
+
O?.retract(), u = e - d, f = e, p = e, m = !0, O?.seek(), B(), w();
|
|
90
99
|
},
|
|
91
|
-
time: () =>
|
|
92
|
-
duration: () =>
|
|
93
|
-
tracks: () =>
|
|
100
|
+
time: () => f,
|
|
101
|
+
duration: () => l,
|
|
102
|
+
tracks: () => s.tracks,
|
|
94
103
|
setLoop(e) {
|
|
95
|
-
|
|
104
|
+
E = e === !0 ? Infinity : e === !1 ? 0 : e, O?.retract(), w();
|
|
96
105
|
},
|
|
97
|
-
loop: () =>
|
|
106
|
+
loop: () => E === Infinity || E !== 0 && E,
|
|
98
107
|
edit(e) {
|
|
99
|
-
e(),
|
|
100
|
-
for (let e of v) try {
|
|
101
|
-
e();
|
|
102
|
-
} catch (e) {
|
|
103
|
-
console.error("timeline: subscriber threw", e);
|
|
104
|
-
}
|
|
108
|
+
e(), A = /* @__PURE__ */ new WeakMap(), l = a(s.tracks, s.duration), O?.retract(), B(), C(x);
|
|
105
109
|
},
|
|
106
110
|
subscribe(e) {
|
|
107
|
-
return
|
|
108
|
-
|
|
111
|
+
return x.add(e), () => {
|
|
112
|
+
x.delete(e);
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
subscribePlayback(e) {
|
|
116
|
+
return S.add(e), () => {
|
|
117
|
+
S.delete(e);
|
|
109
118
|
};
|
|
110
119
|
}
|
|
111
120
|
};
|
|
112
121
|
}
|
|
113
122
|
//#endregion
|
|
114
|
-
export {
|
|
123
|
+
export { o as createTimeline };
|
|
115
124
|
|
|
116
125
|
//# sourceMappingURL=createTimeline.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createTimeline.js","names":["trackEnd","track","tracksEnd","explicit","max","tracks","createTimeline","duration","opts","offset","lastVirtual","playhead","prevPlayhead","done","live","cancelled","wantPaused","wantScale","subscribers","loopOpt","loopsLeft","lap","booker","createBooker","warnedUnbooked","caches","cacheFor","c","applySampled","st","v","sampleTrack","path","fireEvents","k","end","firstAfter","to","i","from","ev","report","onWrap","tick","virtualNow","laps","finished","scale","base","onCancel","seed","register","rearm","s","t","loop","fn","cb","err"],"sources":["../../../src/animation/timeline/createTimeline.ts"],"sourcesContent":["import type { AnimationHandle } from '../types';\nimport { createBooker, firstAfter } from './booking';\nimport { sampleTrack } from './sampleTrack';\nimport type { EventTrack, SampledTrack, TimelineEvent, TimelineHandle, TimelineOptions, Track } from './types';\n\n/** The animator's internal `register`, narrowed to what a timeline needs. */\nexport type TimelineRegister = (seed: {\n id: number;\n cancelKey?: string;\n /** Registers under an existing `cancelKey` without cancelling whoever holds\n * it. A revived timeline is the same animation, not a new claim on the key. */\n keepExisting?: boolean;\n /** `scale` is the effective time scale this frame advanced at, zero while\n * paused at any level. */\n tick: (virtualNow: number, scale?: number) => boolean;\n onCancel?: () => void;\n kind: 'timeline';\n label?: string;\n progress?: () => number;\n}) => AnimationHandle;\n\n/** Where a timeline reports its crossings and laps to `animator.watch`. Each\n * call site checks `watched` first, so an unwatched timeline builds nothing. */\nexport interface TimelineReport {\n readonly watched: boolean;\n /** `path` is a scratch stack the timeline goes on mutating; copy it to keep it. */\n fire(track: EventTrack, path: readonly number[], event: TimelineEvent, lateBy: number): void;\n lap(lap: number): void;\n}\n\n/** End time of a track: its last key/event, or a nested timeline's own end. */\nfunction trackEnd(track: Track): number {\n switch (track.kind) {\n case 'sampled': return track.keys.length ? track.keys[track.keys.length - 1].t : 0;\n case 'event': return track.events.length ? track.events[track.events.length - 1].t : 0;\n case 'timeline': return track.at + tracksEnd(track.timeline.tracks, track.timeline.duration);\n }\n}\n\nfunction tracksEnd(tracks: Track[], explicit?: number): number {\n if (explicit != null) return explicit;\n let max = 0;\n for (const t of tracks) max = Math.max(max, trackEnd(t));\n return max;\n}\n\n/**\n * Create a timeline as a registered animator animation.\n *\n * The playhead is NOT the entry's `virtualNow` directly — it is\n * `virtualNow + offset`, where `offset` is what `seek` and looping move. That\n * keeps seek and wrap-around entirely inside the timeline and needs no setter\n * on the animator's entry.\n *\n * A finished timeline leaves the animator's table, so `seek` and a\n * duration-extending `edit` re-register it. Staying registered instead would\n * hold a slot — and the rAF loop — open for every timeline ever created.\n */\nexport function createTimeline(\n register: TimelineRegister,\n id: number,\n opts: TimelineOptions,\n report?: TimelineReport,\n): TimelineHandle {\n let duration = tracksEnd(opts.tracks, opts.duration);\n let offset = 0;\n let lastVirtual = 0;\n let playhead = 0;\n let prevPlayhead = -Infinity;\n let done = false;\n let live = true;\n let cancelled = false;\n let wantPaused = opts.autoplay === false;\n let wantScale = 1;\n\n const subscribers = new Set<() => void>();\n\n const loopOpt = opts.loop ?? false;\n let loopsLeft = loopOpt === true ? Infinity : loopOpt === false ? 0 : loopOpt;\n let lap = 0;\n\n const booker = opts.booking\n ? createBooker(opts.booking, {\n tracks: opts.tracks,\n duration: () => duration,\n lapsLeft: () => loopsLeft,\n lap: () => lap,\n playhead: () => playhead,\n })\n : null;\n let warnedUnbooked = false;\n\n // Per-sampled-track sampling caches, dropped wholesale by `edit`.\n let caches = new WeakMap<object, Map<number, (u: number) => unknown>>();\n const cacheFor = (track: object): Map<number, (u: number) => unknown> => {\n let c = caches.get(track);\n if (!c) { c = new Map(); caches.set(track, c); }\n return c;\n };\n\n const applySampled = (tracks: Track[], t: number): void => {\n for (const track of tracks) {\n if (track.kind === 'sampled') {\n const st = track as SampledTrack<unknown>;\n const v = sampleTrack(st, t, cacheFor(st));\n if (v !== undefined) st.onTick(v);\n } else if (track.kind === 'timeline') {\n applySampled(track.timeline.tracks, t - track.at);\n }\n }\n };\n\n // Track indexes from the root down to the track being fired, for `report`.\n const path: number[] = [];\n const fireEvents = (tracks: Track[], from: number, to: number): void => {\n for (let k = 0; k < tracks.length; k += 1) {\n const track = tracks[k];\n if (track.kind === 'event') {\n const end = firstAfter(track.events, to);\n for (let i = firstAfter(track.events, from); i < end; i += 1) {\n const ev = track.events[i];\n ev.fire?.(to - ev.t);\n if (report?.watched) {\n path.push(k);\n report.fire(track, path, ev, to - ev.t);\n path.pop();\n }\n if (ev.book && !booker && !warnedUnbooked) {\n warnedUnbooked = true;\n console.warn('timeline: an event has `book` but the timeline has no `booking` clock; it never books.');\n }\n }\n } else if (track.kind === 'timeline') {\n path.push(k);\n fireEvents(track.timeline.tracks, from - track.at, to - track.at);\n path.pop();\n }\n }\n };\n\n // Flush the outgoing pass's tail before re-arming, or an event between the\n // last tick and `duration` is dropped whenever a frame straddles the seam.\n const onWrap = (): void => {\n fireEvents(opts.tracks, prevPlayhead, duration);\n prevPlayhead = -Infinity;\n if (report?.watched) report.lap(lap);\n };\n\n const tick = (virtualNow: number, scale?: number): boolean => {\n lastVirtual = virtualNow;\n playhead = virtualNow + offset;\n\n // A far seek can skip a billion laps of a short duration, so an endless\n // loop takes them in one modulo rather than one iteration each.\n if (duration > 0 && playhead >= duration) {\n if (loopsLeft === Infinity) {\n const laps = Math.floor(playhead / duration);\n offset -= laps * duration;\n playhead -= laps * duration;\n lap += laps;\n onWrap();\n } else {\n while (playhead >= duration && loopsLeft > 0) {\n loopsLeft -= 1;\n offset -= duration;\n playhead -= duration;\n lap += 1;\n onWrap();\n }\n }\n }\n\n const finished = playhead >= duration;\n playhead = Math.min(playhead, duration);\n\n // Sampled before fired, so a handler reads the current frame's values.\n applySampled(opts.tracks, playhead);\n fireEvents(opts.tracks, prevPlayhead, playhead);\n prevPlayhead = playhead;\n booker?.tick(virtualNow, scale ?? (base.isPaused() ? 0 : base.timeScale()));\n\n if (finished && !done) { done = true; opts.onDone?.(); }\n // Re-read: `onDone` may have seeked back or extended the duration, and\n // retiring the entry would strand the replay its own handler just started.\n if (playhead < duration) return false;\n live = false;\n return true;\n };\n\n // Every cancel path inside the animator routes through here, so a timeline\n // cancelled by key or by `cancelAll` is as dead as one cancelled by hand.\n const onCancel = (): void => { cancelled = true; live = false; booker?.retract(); };\n\n const progress = (): number => (duration > 0 ? playhead / duration : 1);\n const seed = { id, cancelKey: opts.cancelKey, tick, onCancel, kind: 'timeline' as const, label: opts.label, progress };\n const base = register(seed);\n\n // A paused entry's scale is zero, so `virtualNow` never advances and the\n // playhead holds at 0 until the consumer resumes.\n if (opts.autoplay === false) base.pause();\n\n /** Put a finished timeline back on the animator's table. A re-registered\n * entry's `virtualNow` restarts at 0, so `offset` carries the playhead. */\n const rearm = (): void => {\n if (cancelled || playhead >= duration) return;\n done = false;\n if (live) return;\n booker?.rearm();\n lastVirtual = 0;\n offset = playhead;\n live = true;\n register({ ...seed, keepExisting: true });\n if (wantPaused) base.pause();\n base.setTimeScale(wantScale);\n };\n\n return {\n ...base,\n // Not just `onCancel`: cancelling a finished timeline never reaches the\n // animator, and must still keep a later seek from reviving it.\n cancel() { onCancel(); base.cancel(); },\n // Playback intent is tracked here, not read back from the entry: a revived\n // one is a fresh registration, and defaults to running at scale 1.\n pause() { wantPaused = true; base.pause(); booker?.retract(); },\n resume() { wantPaused = false; base.resume(); },\n setTimeScale(s) { wantScale = s; base.setTimeScale(s); },\n timeScale: () => (live ? base.timeScale() : wantScale),\n isPaused: () => (live ? base.isPaused() : wantPaused),\n seek(t) {\n booker?.retract();\n offset = t - lastVirtual;\n playhead = t;\n prevPlayhead = t;\n booker?.seek();\n rearm();\n },\n time: () => playhead,\n duration: () => duration,\n tracks: () => opts.tracks,\n setLoop(loop) {\n loopsLeft = loop === true ? Infinity : loop === false ? 0 : loop;\n booker?.retract();\n },\n loop: () => (loopsLeft === Infinity ? true : loopsLeft === 0 ? false : loopsLeft),\n edit(fn) {\n fn();\n caches = new WeakMap();\n duration = tracksEnd(opts.tracks, opts.duration);\n booker?.retract();\n rearm();\n for (const cb of subscribers) {\n try { cb(); } catch (err) { console.error('timeline: subscriber threw', err); }\n }\n },\n subscribe(cb) {\n subscribers.add(cb);\n return () => { subscribers.delete(cb); };\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createTimeline.js","names":["trackEnd","track","tracksEnd","explicit","max","tracks","createTimeline","duration","opts","offset","lastVirtual","playhead","prevPlayhead","prevOpen","held","done","live","cancelled","wantPaused","wantScale","subscribers","playbackSubscribers","notify","cb","set","err","playbackChanged","loopOpt","loopsLeft","lap","booker","createBooker","warnedUnbooked","caches","cacheFor","c","applySampled","st","v","sampleTrack","path","fireEvents","k","end","firstAfter","to","first","fromOpen","firstAtOrAfter","from","i","ev","report","onWrap","tick","virtualNow","rate","scale","base","laps","finished","onCancel","seed","register","rearm","s","t","loop","fn"],"sources":["../../../src/animation/timeline/createTimeline.ts"],"sourcesContent":["import type { AnimationHandle } from '../types';\nimport { createBooker, firstAfter, firstAtOrAfter } from './booking';\nimport { sampleTrack } from './sampleTrack';\nimport type { EventTrack, SampledTrack, TimelineEvent, TimelineHandle, TimelineOptions, Track } from './types';\n\n/** The animator's internal `register`, narrowed to what a timeline needs. */\nexport type TimelineRegister = (seed: {\n id: number;\n cancelKey?: string;\n /** Registers under an existing `cancelKey` without cancelling whoever holds\n * it. A revived timeline is the same animation, not a new claim on the key. */\n keepExisting?: boolean;\n /** `scale` is the effective time scale this frame advanced at, zero while\n * paused at any level. */\n tick: (virtualNow: number, scale?: number) => boolean;\n onCancel?: () => void;\n kind: 'timeline';\n label?: string;\n progress?: () => number;\n}) => AnimationHandle;\n\n/** Where a timeline reports its crossings and laps to `animator.watch`. Each\n * call site checks `watched` first, so an unwatched timeline builds nothing. */\nexport interface TimelineReport {\n readonly watched: boolean;\n /** `path` is a scratch stack the timeline goes on mutating; copy it to keep it. */\n fire(track: EventTrack, path: readonly number[], event: TimelineEvent, lateBy: number): void;\n lap(lap: number): void;\n}\n\n/** End time of a track: its last key/event, or a nested timeline's own end. */\nfunction trackEnd(track: Track): number {\n switch (track.kind) {\n case 'sampled': return track.keys.length ? track.keys[track.keys.length - 1].t : 0;\n case 'event': return track.events.length ? track.events[track.events.length - 1].t : 0;\n case 'timeline': return track.at + tracksEnd(track.timeline.tracks, track.timeline.duration);\n }\n}\n\nfunction tracksEnd(tracks: Track[], explicit?: number): number {\n if (explicit != null) return explicit;\n let max = 0;\n for (const t of tracks) max = Math.max(max, trackEnd(t));\n return max;\n}\n\n/**\n * Create a timeline as a registered animator animation.\n *\n * The playhead is NOT the entry's `virtualNow` directly — it is\n * `virtualNow + offset`, where `offset` is what `seek` and looping move. That\n * keeps seek and wrap-around entirely inside the timeline and needs no setter\n * on the animator's entry.\n *\n * A finished timeline leaves the animator's table, so `seek` and a\n * duration-extending `edit` re-register it. Staying registered instead would\n * hold a slot — and the rAF loop — open for every timeline ever created.\n */\nexport function createTimeline(\n register: TimelineRegister,\n id: number,\n opts: TimelineOptions,\n report?: TimelineReport,\n): TimelineHandle {\n let duration = tracksEnd(opts.tracks, opts.duration);\n let offset = 0;\n let lastVirtual = 0;\n let playhead = 0;\n let prevPlayhead = -Infinity;\n /** A seek leaves the event it landed on unfired, so the next span starts at it. */\n let prevOpen = false;\n /** A held playhead fires nothing: what it sits on waits for playback to move. */\n let held = false;\n let done = false;\n let live = true;\n let cancelled = false;\n let wantPaused = opts.autoplay === false;\n let wantScale = 1;\n\n const subscribers = new Set<() => void>();\n const playbackSubscribers = new Set<() => void>();\n const notify = (set: Set<() => void>): void => {\n for (const cb of set) {\n try { cb(); } catch (err) { console.error('timeline: subscriber threw', err); }\n }\n };\n const playbackChanged = (): void => notify(playbackSubscribers);\n\n const loopOpt = opts.loop ?? false;\n let loopsLeft = loopOpt === true ? Infinity : loopOpt === false ? 0 : loopOpt;\n let lap = 0;\n\n const booker = opts.booking\n ? createBooker(opts.booking, {\n tracks: opts.tracks,\n duration: () => duration,\n lapsLeft: () => loopsLeft,\n lap: () => lap,\n playhead: () => playhead,\n })\n : null;\n let warnedUnbooked = false;\n\n // Per-sampled-track sampling caches, dropped wholesale by `edit`.\n let caches = new WeakMap<object, Map<number, (u: number) => unknown>>();\n const cacheFor = (track: object): Map<number, (u: number) => unknown> => {\n let c = caches.get(track);\n if (!c) { c = new Map(); caches.set(track, c); }\n return c;\n };\n\n const applySampled = (tracks: Track[], t: number): void => {\n for (const track of tracks) {\n if (track.kind === 'sampled') {\n const st = track as SampledTrack<unknown>;\n const v = sampleTrack(st, t, cacheFor(st));\n if (v !== undefined) st.onTick(v);\n } else if (track.kind === 'timeline') {\n applySampled(track.timeline.tracks, t - track.at);\n }\n }\n };\n\n // Track indexes from the root down to the track being fired, for `report`.\n const path: number[] = [];\n const fireEvents = (tracks: Track[], from: number, to: number, fromOpen: boolean): void => {\n for (let k = 0; k < tracks.length; k += 1) {\n const track = tracks[k];\n if (track.kind === 'event') {\n const end = firstAfter(track.events, to);\n const first = (fromOpen ? firstAtOrAfter : firstAfter)(track.events, from);\n for (let i = first; i < end; i += 1) {\n const ev = track.events[i];\n ev.fire?.(to - ev.t);\n if (report?.watched) {\n path.push(k);\n report.fire(track, path, ev, to - ev.t);\n path.pop();\n }\n if (ev.book && !booker && !warnedUnbooked) {\n warnedUnbooked = true;\n console.warn('timeline: an event has `book` but the timeline has no `booking` clock; it never books.');\n }\n }\n } else if (track.kind === 'timeline') {\n path.push(k);\n fireEvents(track.timeline.tracks, from - track.at, to - track.at, fromOpen);\n path.pop();\n }\n }\n };\n\n // Flush the outgoing pass's tail before re-arming, or an event between the\n // last tick and `duration` is dropped whenever a frame straddles the seam.\n const onWrap = (): void => {\n if (!held) fireEvents(opts.tracks, prevPlayhead, duration, prevOpen);\n prevPlayhead = -Infinity;\n prevOpen = false;\n if (report?.watched) report.lap(lap);\n };\n\n const tick = (virtualNow: number, scale?: number): boolean => {\n lastVirtual = virtualNow;\n playhead = virtualNow + offset;\n const rate = scale ?? (base.isPaused() ? 0 : base.timeScale());\n held = rate === 0;\n\n // A far seek can skip a billion laps of a short duration, so an endless\n // loop takes them in one modulo rather than one iteration each.\n if (duration > 0 && playhead >= duration) {\n if (loopsLeft === Infinity) {\n const laps = Math.floor(playhead / duration);\n offset -= laps * duration;\n playhead -= laps * duration;\n lap += laps;\n onWrap();\n } else {\n while (playhead >= duration && loopsLeft > 0) {\n loopsLeft -= 1;\n offset -= duration;\n playhead -= duration;\n lap += 1;\n onWrap();\n }\n }\n }\n\n const finished = playhead >= duration;\n playhead = Math.min(playhead, duration);\n\n // Sampled before fired, so a handler reads the current frame's values.\n applySampled(opts.tracks, playhead);\n if (!held) {\n fireEvents(opts.tracks, prevPlayhead, playhead, prevOpen);\n prevPlayhead = playhead;\n prevOpen = false;\n }\n booker?.tick(virtualNow, rate);\n\n if (finished && !done) { done = true; opts.onDone?.(); playbackChanged(); }\n // Re-read: `onDone` may have seeked back or extended the duration, and\n // retiring the entry would strand the replay its own handler just started.\n if (playhead < duration) return false;\n live = false;\n return true;\n };\n\n // Every cancel path inside the animator routes through here, so a timeline\n // cancelled by key or by `cancelAll` is as dead as one cancelled by hand.\n const onCancel = (): void => {\n const first = !cancelled;\n cancelled = true;\n live = false;\n booker?.retract();\n if (first) playbackChanged();\n };\n\n const progress = (): number => (duration > 0 ? playhead / duration : 1);\n const seed = { id, cancelKey: opts.cancelKey, tick, onCancel, kind: 'timeline' as const, label: opts.label, progress };\n const base = register(seed);\n\n // A paused entry's scale is zero, so `virtualNow` never advances and the\n // playhead holds at 0 until the consumer resumes.\n if (opts.autoplay === false) base.pause();\n\n /** Put a finished timeline back on the animator's table. A re-registered\n * entry's `virtualNow` restarts at 0, so `offset` carries the playhead. */\n const rearm = (): void => {\n if (cancelled || playhead >= duration) return;\n done = false;\n if (live) return;\n booker?.rearm();\n lastVirtual = 0;\n offset = playhead;\n live = true;\n register({ ...seed, keepExisting: true });\n if (wantPaused) base.pause();\n base.setTimeScale(wantScale);\n };\n\n return {\n ...base,\n // Not just `onCancel`: cancelling a finished timeline never reaches the\n // animator, and must still keep a later seek from reviving it.\n cancel() { onCancel(); base.cancel(); },\n // Playback intent is tracked here, not read back from the entry: a revived\n // one is a fresh registration, and defaults to running at scale 1.\n pause() { wantPaused = true; base.pause(); booker?.retract(); playbackChanged(); },\n resume() { wantPaused = false; base.resume(); playbackChanged(); },\n setTimeScale(s) { wantScale = s; base.setTimeScale(s); playbackChanged(); },\n timeScale: () => (live ? base.timeScale() : wantScale),\n isPaused: () => (live ? base.isPaused() : wantPaused),\n seek(t) {\n booker?.retract();\n offset = t - lastVirtual;\n playhead = t;\n prevPlayhead = t;\n prevOpen = true;\n booker?.seek();\n rearm();\n playbackChanged();\n },\n time: () => playhead,\n duration: () => duration,\n tracks: () => opts.tracks,\n setLoop(loop) {\n loopsLeft = loop === true ? Infinity : loop === false ? 0 : loop;\n booker?.retract();\n playbackChanged();\n },\n loop: () => (loopsLeft === Infinity ? true : loopsLeft === 0 ? false : loopsLeft),\n edit(fn) {\n fn();\n caches = new WeakMap();\n duration = tracksEnd(opts.tracks, opts.duration);\n booker?.retract();\n rearm();\n notify(subscribers);\n },\n subscribe(cb) {\n subscribers.add(cb);\n return () => { subscribers.delete(cb); };\n },\n subscribePlayback(cb) {\n playbackSubscribers.add(cb);\n return () => { playbackSubscribers.delete(cb); };\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -13,6 +13,7 @@ function a(r, i) {
|
|
|
13
13
|
t0: o,
|
|
14
14
|
span: l,
|
|
15
15
|
exact: c,
|
|
16
|
+
fresh: null,
|
|
16
17
|
first: a[0].value,
|
|
17
18
|
last: a[a.length - 1].value,
|
|
18
19
|
read: (e) => e
|
|
@@ -36,11 +37,16 @@ function a(r, i) {
|
|
|
36
37
|
value: p(e.value, t.value, n)
|
|
37
38
|
};
|
|
38
39
|
};
|
|
39
|
-
|
|
40
|
+
u.patch = n(1, a.map((t, n) => ({
|
|
40
41
|
at: (t.t - o) / l,
|
|
41
42
|
delta: { v: e[n] },
|
|
42
43
|
ease: d(t)
|
|
43
|
-
})), { lerpBy: () => t }), u.read = (e) => e.value, u;
|
|
44
|
+
})), { lerpBy: () => t }), u.read = (e) => e.value, u.fresh = /* @__PURE__ */ new Map();
|
|
45
|
+
for (let n = 0; n < a.length - 1; n++) {
|
|
46
|
+
let r = a[n].t;
|
|
47
|
+
r > o && r < s && u.fresh.set(r, () => t(e[n], e[n + 1], 0).value);
|
|
48
|
+
}
|
|
49
|
+
return u;
|
|
44
50
|
}
|
|
45
51
|
let m = e(a[0].value);
|
|
46
52
|
if (!m) return u;
|
|
@@ -55,9 +61,11 @@ function a(r, i) {
|
|
|
55
61
|
function o(e, t, n) {
|
|
56
62
|
if (e.keys.length === 0) return;
|
|
57
63
|
let o = n, s = o?.get(i);
|
|
58
|
-
(!s || s.track !== e || s.keys !== e.keys) && (o?.clear(), s = a(e, n), o?.set(i, s));
|
|
59
|
-
let c = s.
|
|
60
|
-
if (c
|
|
64
|
+
if ((!s || s.track !== e || s.keys !== e.keys) && (o?.clear(), s = a(e, n), o?.set(i, s)), Number.isNaN(t)) return s.first;
|
|
65
|
+
let c = s.fresh?.get(t);
|
|
66
|
+
if (c) return c();
|
|
67
|
+
let l = s.exact.get(t);
|
|
68
|
+
if (l !== void 0 || s.exact.has(t)) return l;
|
|
61
69
|
if (!s.patch) {
|
|
62
70
|
if (t < s.t0) return s.first;
|
|
63
71
|
if (t >= s.t0 + s.span) return s.last;
|