@weasel-js/core 1.9.2 → 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 +393 -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 +146 -92
- 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 +11010 -7700
- 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 +13 -2
- 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 -47
- package/dist/tools/prefs.js.map +0 -1
|
@@ -3,65 +3,88 @@ import { translatePoseViaDescriptor as t } from "../../core/geometry/poseDescrip
|
|
|
3
3
|
import { AUTO_POSE_DESCRIPTOR as n } from "../../interactions/actions/resize/autoPoseDescriptor.js";
|
|
4
4
|
import { getScratch as r, scratchKey as i, setScratch as a } from "@weasel-js/routing";
|
|
5
5
|
//#region src/animation/behaviors/momentum.ts
|
|
6
|
-
var o = i("momentum.samples");
|
|
7
|
-
function
|
|
8
|
-
let
|
|
6
|
+
var o = (e, t) => e.x === t.x && e.y === t.y && e.width === t.width && e.height === t.height, s = 0, c = i("momentum.samples");
|
|
7
|
+
function l(i) {
|
|
8
|
+
let l = i.friction ?? .92, u = i.threshold ?? 200, d = i.velocitySampleMs ?? 80, f = i.now ?? (() => Date.now()), p = i.bounds, m = i.boundary ?? "stop", h = i.poseDescriptor ?? n, g = (e, t, n, r) => {
|
|
9
9
|
let i = e + n, a = t + r;
|
|
10
|
-
if (!
|
|
10
|
+
if (!p) return {
|
|
11
11
|
nx: i,
|
|
12
12
|
ny: a,
|
|
13
13
|
hit: !1
|
|
14
14
|
};
|
|
15
15
|
let o = !1;
|
|
16
|
-
return i <
|
|
16
|
+
return i < p.x ? (i = p.x, o = !0) : i > p.x + p.width && (i = p.x + p.width, o = !0), a < p.y ? (a = p.y, o = !0) : a > p.y + p.height && (a = p.y + p.height, o = !0), {
|
|
17
17
|
nx: i,
|
|
18
18
|
ny: a,
|
|
19
19
|
hit: o
|
|
20
20
|
};
|
|
21
|
-
},
|
|
22
|
-
let t = r(e.scratch,
|
|
23
|
-
t || (t = [], a(e.scratch,
|
|
24
|
-
t:
|
|
21
|
+
}, _ = (e) => {
|
|
22
|
+
let t = r(e.scratch, c);
|
|
23
|
+
t || (t = [], a(e.scratch, c, t)), t.push({
|
|
24
|
+
t: f(),
|
|
25
25
|
x: e.pointer.worldX,
|
|
26
26
|
y: e.pointer.worldY
|
|
27
27
|
});
|
|
28
|
-
let n =
|
|
28
|
+
let n = f() - d * 4;
|
|
29
29
|
for (; t.length > 1 && t[0].t < n;) t.shift();
|
|
30
|
-
};
|
|
30
|
+
}, v = /* @__PURE__ */ new Set();
|
|
31
31
|
return {
|
|
32
32
|
onStart(e) {
|
|
33
|
-
|
|
33
|
+
for (let t of [...v]) t.ids.some((t) => e.draggedIds.includes(t)) && t.stop();
|
|
34
|
+
a(e.scratch, c, []), _(e);
|
|
34
35
|
},
|
|
35
36
|
onMove(e) {
|
|
36
|
-
|
|
37
|
+
_(e);
|
|
37
38
|
},
|
|
38
39
|
onEnd(n, a) {
|
|
39
40
|
if (a.answered) return;
|
|
40
|
-
let
|
|
41
|
-
if (
|
|
42
|
-
let
|
|
43
|
-
for (let e of
|
|
44
|
-
|
|
41
|
+
let f = r(n.scratch, c) ?? [];
|
|
42
|
+
if (f.length < 2) return;
|
|
43
|
+
let _ = f[f.length - 1], y = _.t - d, b = f[0];
|
|
44
|
+
for (let e of f) if (e.t >= y) {
|
|
45
|
+
b = e;
|
|
45
46
|
break;
|
|
46
47
|
}
|
|
47
|
-
let
|
|
48
|
-
if (
|
|
49
|
-
let
|
|
50
|
-
if (Math.hypot(
|
|
51
|
-
let
|
|
48
|
+
let x = (_.t - b.t) / 1e3;
|
|
49
|
+
if (x <= 0) return;
|
|
50
|
+
let S = (_.x - b.x) / x, C = (_.y - b.y) / x;
|
|
51
|
+
if (Math.hypot(S, C) < u) return;
|
|
52
|
+
let w = new Map(n.current), T = {
|
|
52
53
|
x: 0,
|
|
53
54
|
y: 0
|
|
54
|
-
},
|
|
55
|
-
|
|
55
|
+
}, E = n.adapter, D = (e) => {
|
|
56
|
+
if (E.previewPoses) E.previewPoses(e);
|
|
57
|
+
else for (let [t, n] of e) n !== null && E.setPose(t, n);
|
|
58
|
+
}, O = new Set(n.draggedIds), k = /* @__PURE__ */ new Map();
|
|
59
|
+
for (let e of O) E.getNode(e) && k.set(e, h.getBounds(E.getPose(e)));
|
|
60
|
+
let A = (e) => {
|
|
61
|
+
let t = k.get(e);
|
|
62
|
+
return t !== void 0 && E.getNode(e) !== void 0 && o(h.getBounds(E.getPose(e)), t);
|
|
63
|
+
}, j = /* @__PURE__ */ new Map(), M = `momentum:${s++}`, N = {
|
|
64
|
+
ids: n.draggedIds.slice(),
|
|
65
|
+
stop: () => {
|
|
66
|
+
if (!i.animator.isActive(M)) {
|
|
67
|
+
v.delete(N);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
P.cancel(), F();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
v.add(N), D(new Map([...O].flatMap((e) => {
|
|
74
|
+
let t = w.get(e);
|
|
75
|
+
return t === void 0 ? [] : [[e, t]];
|
|
76
|
+
})));
|
|
77
|
+
let P = i.animator.decay({
|
|
56
78
|
from: {
|
|
57
79
|
x: 0,
|
|
58
80
|
y: 0
|
|
59
81
|
},
|
|
60
82
|
velocity: {
|
|
61
|
-
x:
|
|
62
|
-
y:
|
|
83
|
+
x: S,
|
|
84
|
+
y: C
|
|
63
85
|
},
|
|
64
|
-
friction:
|
|
86
|
+
friction: l,
|
|
87
|
+
cancelKey: M,
|
|
65
88
|
add: (e, t) => ({
|
|
66
89
|
x: e.x + t.x,
|
|
67
90
|
y: e.y + t.y
|
|
@@ -72,47 +95,62 @@ function s(i) {
|
|
|
72
95
|
}),
|
|
73
96
|
magnitude: (e) => Math.hypot(e.x, e.y),
|
|
74
97
|
onTick: (e) => {
|
|
75
|
-
|
|
76
|
-
let
|
|
77
|
-
for (let i of
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
98
|
+
T = e;
|
|
99
|
+
let n = p !== void 0, r = /* @__PURE__ */ new Map();
|
|
100
|
+
for (let i of [...O]) {
|
|
101
|
+
if (!A(i)) {
|
|
102
|
+
O.delete(i), r.set(i, null);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
let a = w.get(i);
|
|
106
|
+
if (!a) continue;
|
|
107
|
+
let o = h.getBounds(a), { nx: s, ny: c, hit: l } = g(o.x, o.y, e.x, e.y);
|
|
108
|
+
l || (n = !1), j.set(i, {
|
|
109
|
+
x: s,
|
|
110
|
+
y: c
|
|
111
|
+
}), r.set(i, t(a, s - o.x, c - o.y, h));
|
|
85
112
|
}
|
|
86
|
-
|
|
113
|
+
D(r);
|
|
114
|
+
for (let e of O) k.set(e, h.getBounds(E.getPose(e)));
|
|
115
|
+
if (O.size === 0) {
|
|
116
|
+
v.delete(N), P.cancel();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
m === "stop" && n && N.stop();
|
|
87
120
|
},
|
|
88
121
|
onDone: () => {
|
|
89
|
-
|
|
122
|
+
F();
|
|
90
123
|
}
|
|
91
124
|
});
|
|
92
|
-
function
|
|
93
|
-
if (!
|
|
94
|
-
let r = [];
|
|
95
|
-
for (let
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
125
|
+
function F() {
|
|
126
|
+
if (!v.delete(N)) return;
|
|
127
|
+
let r = [], i = /* @__PURE__ */ new Map();
|
|
128
|
+
for (let a of O) {
|
|
129
|
+
if (i.set(a, null), !A(a)) continue;
|
|
130
|
+
let o = w.get(a);
|
|
131
|
+
if (!o) continue;
|
|
132
|
+
let s = h.getBounds(o), c = j.get(a) ?? {
|
|
133
|
+
x: s.x + T.x,
|
|
134
|
+
y: s.y + T.y
|
|
135
|
+
}, l = t(o, c.x - s.x, c.y - s.y, h), u = n.origin.get(a) ?? o;
|
|
102
136
|
r.push(e({
|
|
103
|
-
id:
|
|
104
|
-
from:
|
|
105
|
-
to:
|
|
137
|
+
id: a,
|
|
138
|
+
from: u,
|
|
139
|
+
to: l,
|
|
106
140
|
label: "flick"
|
|
107
141
|
}));
|
|
108
142
|
}
|
|
109
|
-
r.length > 0
|
|
143
|
+
if (r.length > 0) {
|
|
144
|
+
if (E.applyOps) E.applyOps(r, "flick");
|
|
145
|
+
else if (E.previewPoses) for (let e of r) e.apply(E);
|
|
146
|
+
}
|
|
147
|
+
E.previewPoses?.(i);
|
|
110
148
|
}
|
|
111
149
|
return null;
|
|
112
150
|
}
|
|
113
151
|
};
|
|
114
152
|
}
|
|
115
153
|
//#endregion
|
|
116
|
-
export {
|
|
154
|
+
export { l as momentum };
|
|
117
155
|
|
|
118
156
|
//# sourceMappingURL=momentum.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"momentum.js","names":["SAMPLES","scratchKey","momentum","friction","opts","threshold","sampleMs","now","bounds","boundaryPolicy","d","AUTO_POSE_DESCRIPTOR","clampToBounds","nx","sx","dx","ny","sy","dy","hit","recordSample","samples","getScratch","ctx","setScratch","cutoff","end","last","first","s","dt","vx","vy","startPoses","lastValue","adapter","finalPositions","decayHandle","a","b","v","k","delta","allHit","id","start","o","translatePoseViaDescriptor","commitFlick","ops","fp","finalPose","createTransformOp"],"sources":["../../../src/animation/behaviors/momentum.ts"],"sourcesContent":["import { createTransformOp } from 'core/ops/transform';\nimport type { Op } from 'core/ops/types';\nimport type { MoveBehavior, GestureContext } from 'interactions/gestures/types';\nimport { scratchKey, getScratch, setScratch } from '@weasel-js/routing';\nimport type { PoseDescriptor } from 'core/geometry/poseDescriptor';\nimport { translatePoseViaDescriptor } from 'core/geometry/poseDescriptor';\nimport { AUTO_POSE_DESCRIPTOR } from 'interactions/actions/resize/autoPoseDescriptor';\nimport type { Animator } from '../types';\n\n/** Options for the `momentum` move behavior. */\nexport interface MomentumOptions {\n /** Required: the per-Canvas animator that will own the decay. */\n animator: Animator;\n friction?: number; // default 0.92 (per second)\n threshold?: number; // default 200 px/sec\n /** Sample window in ms for velocity computation. Default 80ms. */\n velocitySampleMs?: number;\n /** Optional clock override for tests. Defaults to `Date.now`. */\n now?: () => number;\n /**\n * Optional bounds for the object's top-left corner (in world units). When\n * supplied, momentum-driven translation is clamped: each tick's new\n * position is constrained so the object's `(x, y)` stays inside the rect.\n * Without bounds, a hard flick carries the object indefinitely until\n * friction dampens velocity below `threshold`.\n *\n * Note: ignores object size for now — the bound is on the top-left, not\n * the visible edges. A consumer wanting \"object stays fully inside\" should\n * pass `bounds = { x: canvas.x, y: canvas.y, width: canvas.w - obj.w,\n * height: canvas.h - obj.h }` (and accept that it doesn't adapt to\n * variable-sized objects mid-flight).\n */\n bounds?: { x: number; y: number; width: number; height: number };\n /**\n * Boundary policy when the clamped position hits an edge. 'stop' cancels\n * the decay (instant settle at the edge). 'continue' keeps decaying but\n * subsequent ticks stay clamped (object drifts along the edge as friction\n * decays the velocity). Default 'stop'.\n */\n boundary?: 'stop' | 'continue';\n /** How to translate poses. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<unknown>;\n}\n\ninterface PointerSample {\n t: number; // ms timestamp\n x: number;\n y: number;\n}\n\ninterface RectLike { x: number; y: number }\n\nconst SAMPLES = scratchKey<PointerSample[]>('momentum.samples');\n\n/**\n * Move behavior that keeps a dragged node coasting after the pointer is\n * released, at the velocity it was travelling, until friction brings it below\n * `threshold`.\n *\n * Plugs into the move action rather than replacing it, so the drag itself is\n * unchanged — this only decides what happens after the release. The whole\n * flick, coast included, records as one undoable transform.\n */\nexport function momentum<TPose>(opts: MomentumOptions): MoveBehavior<TPose> {\n const friction = opts.friction ?? 0.92;\n const threshold = opts.threshold ?? 200;\n const sampleMs = opts.velocitySampleMs ?? 80;\n const now = opts.now ?? (() => Date.now());\n const bounds = opts.bounds;\n const boundaryPolicy = opts.boundary ?? 'stop';\n const d = (opts.poseDescriptor ?? AUTO_POSE_DESCRIPTOR) as PoseDescriptor<TPose>;\n\n /** Apply bounds clamp to (sx + dx, sy + dy). Returns clamped (nx, ny) and\n * whether either axis was clamped (signalling boundary hit). */\n const clampToBounds = (sx: number, sy: number, dx: number, dy: number): { nx: number; ny: number; hit: boolean } => {\n let nx = sx + dx;\n let ny = sy + dy;\n if (!bounds) return { nx, ny, hit: false };\n let hit = false;\n if (nx < bounds.x) { nx = bounds.x; hit = true; }\n else if (nx > bounds.x + bounds.width) { nx = bounds.x + bounds.width; hit = true; }\n if (ny < bounds.y) { ny = bounds.y; hit = true; }\n else if (ny > bounds.y + bounds.height) { ny = bounds.y + bounds.height; hit = true; }\n return { nx, ny, hit };\n };\n\n const recordSample = (ctx: GestureContext<TPose>): void => {\n let samples = getScratch(ctx.scratch, SAMPLES);\n if (!samples) {\n samples = [];\n setScratch(ctx.scratch, SAMPLES, samples);\n }\n samples.push({\n t: now(),\n x: ctx.pointer.worldX,\n y: ctx.pointer.worldY,\n });\n // Trim anything older than 4× the sample window — bounded memory.\n const cutoff = now() - sampleMs * 4;\n while (samples.length > 1 && samples[0].t < cutoff) samples.shift();\n };\n\n return {\n onStart(ctx) {\n setScratch(ctx.scratch, SAMPLES, []);\n recordSample(ctx);\n },\n onMove(ctx) {\n recordSample(ctx);\n },\n onEnd(ctx, end): Op[] | null | void {\n if (end.answered) return undefined;\n const samples = getScratch(ctx.scratch, SAMPLES) ?? [];\n if (samples.length < 2) return undefined;\n const last = samples[samples.length - 1];\n // Find the oldest sample within `sampleMs` of `last`.\n const cutoff = last.t - sampleMs;\n let first = samples[0];\n for (const s of samples) {\n if (s.t >= cutoff) { first = s; break; }\n }\n const dt = (last.t - first.t) / 1000;\n if (dt <= 0) return undefined;\n const vx = (last.x - first.x) / dt;\n const vy = (last.y - first.y) / dt;\n const speed = Math.hypot(vx, vy);\n if (speed < threshold) return undefined;\n\n // Suppress default commit and fire decay. We translate each dragged id\n // by the per-frame delta and commit one transform op per id when done.\n const startPoses = new Map<string, TPose>(ctx.current);\n let lastValue = { x: 0, y: 0 };\n const adapter = ctx.adapter as { setPose(id: string, p: TPose): void; applyOps?(ops: Op[], label: string): void };\n // Track per-id final positions when bounds clamping is active — used\n // by onDone to compute the correct final transform op (not just\n // start + decay's last delta, which may overshoot the boundary).\n const finalPositions = new Map<string, { x: number; y: number }>();\n let decayHandle: { cancel(): void } | null = null;\n decayHandle = opts.animator.decay<RectLike>({\n from: { x: 0, y: 0 },\n velocity: { x: vx, y: vy },\n friction,\n add: (a, b) => ({ x: a.x + b.x, y: a.y + b.y }),\n scale: (v, k) => ({ x: v.x * k, y: v.y * k }),\n magnitude: (v) => Math.hypot(v.x, v.y),\n onTick: (delta) => {\n lastValue = delta;\n let allHit = bounds !== undefined;\n for (const id of ctx.draggedIds) {\n const start = startPoses.get(id);\n if (!start) continue;\n const o = d.getBounds(start);\n const { nx, ny, hit } = clampToBounds(o.x, o.y, delta.x, delta.y);\n if (!hit) allHit = false;\n finalPositions.set(id, { x: nx, y: ny });\n adapter.setPose(id, translatePoseViaDescriptor(start, nx - o.x, ny - o.y, d));\n }\n // If 'stop' policy and every dragged id's clamped position hit\n // the boundary, cancel the decay so the animation settles instantly\n // instead of drifting along the edge as friction wears off.\n if (boundaryPolicy === 'stop' && allHit && decayHandle) {\n decayHandle.cancel();\n // Manually fire onDone since cancel() bypasses it.\n commitFlick();\n }\n },\n onDone: () => {\n commitFlick();\n },\n });\n\n function commitFlick(): void {\n if (!adapter.applyOps) return;\n const ops: Op[] = [];\n for (const id of ctx.draggedIds) {\n const start = startPoses.get(id);\n if (!start) continue;\n const o = d.getBounds(start);\n const fp = finalPositions.get(id) ?? { x: o.x + lastValue.x, y: o.y + lastValue.y };\n const finalPose = translatePoseViaDescriptor(start, fp.x - o.x, fp.y - o.y, d);\n ops.push(createTransformOp<TPose>({ id, from: start, to: finalPose, label: 'flick' }));\n }\n if (ops.length > 0) adapter.applyOps(ops, 'flick');\n }\n\n return null;\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"momentum.js","names":["sameBounds","a","b","nextCoast","SAMPLES","scratchKey","momentum","friction","opts","threshold","sampleMs","now","bounds","boundaryPolicy","d","AUTO_POSE_DESCRIPTOR","clampToBounds","nx","sx","dx","ny","sy","dy","hit","recordSample","samples","getScratch","ctx","setScratch","cutoff","coasts","coast","id","end","last","first","s","dt","vx","vy","startPoses","lastValue","adapter","show","poses","pose","riding","lastSeen","stillOurs","seen","finalPositions","cancelKey","decayHandle","commitFlick","start","v","k","delta","allHit","frame","translatePoseViaDescriptor","ops","shown","o","fp","finalPose","from","createTransformOp","op"],"sources":["../../../src/animation/behaviors/momentum.ts"],"sourcesContent":["import { createTransformOp } from 'core/ops/transform';\nimport type { Op } from 'core/ops/types';\nimport type { MoveBehavior, GestureContext } from 'interactions/gestures/types';\nimport { scratchKey, getScratch, setScratch } from '@weasel-js/routing';\nimport type { PoseDescriptor } from 'core/geometry/poseDescriptor';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport { translatePoseViaDescriptor } from 'core/geometry/poseDescriptor';\nimport { AUTO_POSE_DESCRIPTOR } from 'interactions/actions/resize/autoPoseDescriptor';\nimport type { Animator } from '../types';\n\n/** Options for the `momentum` move behavior. */\nexport interface MomentumOptions {\n /** Required: the per-Canvas animator that will own the decay. */\n animator: Animator;\n friction?: number; // default 0.92 (per second)\n threshold?: number; // default 200 world units/sec; the slowest release that coasts\n /** Sample window in ms for velocity computation. Default 80ms. */\n velocitySampleMs?: number;\n /** Optional clock override for tests. Defaults to `Date.now`. */\n now?: () => number;\n /**\n * Optional bounds for the object's top-left corner (in world units). When\n * supplied, momentum-driven translation is clamped: each tick's new\n * position is constrained so the object's `(x, y)` stays inside the rect.\n * Without bounds, a hard flick carries the object indefinitely until\n * friction dampens velocity below `threshold`.\n *\n * Note: ignores object size for now — the bound is on the top-left, not\n * the visible edges. A consumer wanting \"object stays fully inside\" should\n * pass `bounds = { x: canvas.x, y: canvas.y, width: canvas.w - obj.w,\n * height: canvas.h - obj.h }` (and accept that it doesn't adapt to\n * variable-sized objects mid-flight).\n */\n bounds?: { x: number; y: number; width: number; height: number };\n /**\n * Boundary policy when the clamped position hits an edge. 'stop' cancels\n * the decay (instant settle at the edge). 'continue' keeps decaying but\n * subsequent ticks stay clamped (object drifts along the edge as friction\n * decays the velocity). Default 'stop'.\n */\n boundary?: 'stop' | 'continue';\n /** How to translate poses. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<unknown>;\n}\n\ninterface PointerSample {\n t: number; // ms timestamp\n x: number;\n y: number;\n}\n\ninterface RectLike { x: number; y: number }\n\nconst sameBounds = (a: Bounds, b: Bounds): boolean =>\n a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n\nlet nextCoast = 0;\n\nconst SAMPLES = scratchKey<PointerSample[]>('momentum.samples');\n\n/**\n * Move behavior that keeps a dragged node coasting after the pointer is\n * released, at the velocity it was traveling, until friction brings it to\n * rest. A release slower than `threshold` does not coast at all.\n *\n * Plugs into the move action rather than replacing it, so the drag itself is\n * unchanged — this only decides what happens after the release. The whole\n * flick, coast included, records as one undoable transform: under an adapter\n * with `previewPoses` the coast is shown without touching the document, and\n * the transform is written once it comes to rest. Dragging a node\n * again while it coasts stops the coast and records it where it stands. A node\n * something else moves or deletes mid-coast, an undo included, drops out of\n * the coast where that left it, and nothing is recorded for it.\n */\nexport function momentum<TPose>(opts: MomentumOptions): MoveBehavior<TPose> {\n const friction = opts.friction ?? 0.92;\n const threshold = opts.threshold ?? 200;\n const sampleMs = opts.velocitySampleMs ?? 80;\n const now = opts.now ?? (() => Date.now());\n const bounds = opts.bounds;\n const boundaryPolicy = opts.boundary ?? 'stop';\n const d = (opts.poseDescriptor ?? AUTO_POSE_DESCRIPTOR) as PoseDescriptor<TPose>;\n\n /** Apply bounds clamp to (sx + dx, sy + dy). Returns clamped (nx, ny) and\n * whether either axis was clamped (signalling boundary hit). */\n const clampToBounds = (sx: number, sy: number, dx: number, dy: number): { nx: number; ny: number; hit: boolean } => {\n let nx = sx + dx;\n let ny = sy + dy;\n if (!bounds) return { nx, ny, hit: false };\n let hit = false;\n if (nx < bounds.x) { nx = bounds.x; hit = true; }\n else if (nx > bounds.x + bounds.width) { nx = bounds.x + bounds.width; hit = true; }\n if (ny < bounds.y) { ny = bounds.y; hit = true; }\n else if (ny > bounds.y + bounds.height) { ny = bounds.y + bounds.height; hit = true; }\n return { nx, ny, hit };\n };\n\n const recordSample = (ctx: GestureContext<TPose>): void => {\n let samples = getScratch(ctx.scratch, SAMPLES);\n if (!samples) {\n samples = [];\n setScratch(ctx.scratch, SAMPLES, samples);\n }\n samples.push({\n t: now(),\n x: ctx.pointer.worldX,\n y: ctx.pointer.worldY,\n });\n // Trim anything older than 4× the sample window — bounded memory.\n const cutoff = now() - sampleMs * 4;\n while (samples.length > 1 && samples[0].t < cutoff) samples.shift();\n };\n\n const coasts = new Set<{ ids: readonly string[]; stop(): void }>();\n\n return {\n onStart(ctx) {\n for (const coast of [...coasts]) {\n if (coast.ids.some((id) => ctx.draggedIds.includes(id))) coast.stop();\n }\n setScratch(ctx.scratch, SAMPLES, []);\n recordSample(ctx);\n },\n onMove(ctx) {\n recordSample(ctx);\n },\n onEnd(ctx, end): Op[] | null | void {\n if (end.answered) return undefined;\n const samples = getScratch(ctx.scratch, SAMPLES) ?? [];\n if (samples.length < 2) return undefined;\n const last = samples[samples.length - 1];\n // Find the oldest sample within `sampleMs` of `last`.\n const cutoff = last.t - sampleMs;\n let first = samples[0];\n for (const s of samples) {\n if (s.t >= cutoff) { first = s; break; }\n }\n const dt = (last.t - first.t) / 1000;\n if (dt <= 0) return undefined;\n const vx = (last.x - first.x) / dt;\n const vy = (last.y - first.y) / dt;\n const speed = Math.hypot(vx, vy);\n if (speed < threshold) return undefined;\n\n // Suppress default commit and fire decay. We translate each dragged id\n // by the per-frame delta and commit one transform op per id when done.\n const startPoses = new Map<string, TPose>(ctx.current);\n let lastValue = { x: 0, y: 0 };\n const adapter = ctx.adapter;\n const show = (poses: Map<string, TPose | null>): void => {\n if (adapter.previewPoses) adapter.previewPoses(poses);\n else for (const [id, pose] of poses) if (pose !== null) adapter.setPose(id, pose);\n };\n // What the scene held for each node right after the coast last wrote it.\n // A node that is gone, or reads back as anything else, has another\n // writer now, an undo or a delete, and leaves the coast unrecorded.\n const riding = new Set(ctx.draggedIds);\n const lastSeen = new Map<string, Bounds>();\n for (const id of riding) {\n if (adapter.getNode(id)) lastSeen.set(id, d.getBounds(adapter.getPose(id)));\n }\n const stillOurs = (id: string): boolean => {\n const seen = lastSeen.get(id);\n return seen !== undefined && adapter.getNode(id) !== undefined\n && sameBounds(d.getBounds(adapter.getPose(id)), seen);\n };\n // Track per-id final positions when bounds clamping is active — used\n // by onDone to compute the correct final transform op (not just\n // start + decay's last delta, which may overshoot the boundary).\n const finalPositions = new Map<string, { x: number; y: number }>();\n const cancelKey = `momentum:${nextCoast++}`;\n const coast = {\n ids: ctx.draggedIds.slice(),\n stop: (): void => {\n // Canceled from outside (cancelAll, unmount), it stopped long ago and somewhere else.\n if (!opts.animator.isActive(cancelKey)) {\n coasts.delete(coast);\n return;\n }\n decayHandle.cancel();\n commitFlick();\n },\n };\n coasts.add(coast);\n // Held from the release itself, so no frame paints the pre-drag pose\n // between the drag's preview going away and the first coast frame.\n show(new Map([...riding].flatMap((id) => {\n const start = startPoses.get(id);\n return start === undefined ? [] : [[id, start] as const];\n })));\n const decayHandle = opts.animator.decay<RectLike>({\n from: { x: 0, y: 0 },\n velocity: { x: vx, y: vy },\n friction,\n cancelKey,\n add: (a, b) => ({ x: a.x + b.x, y: a.y + b.y }),\n scale: (v, k) => ({ x: v.x * k, y: v.y * k }),\n magnitude: (v) => Math.hypot(v.x, v.y),\n onTick: (delta) => {\n lastValue = delta;\n let allHit = bounds !== undefined;\n const frame = new Map<string, TPose | null>();\n for (const id of [...riding]) {\n if (!stillOurs(id)) {\n riding.delete(id);\n frame.set(id, null);\n continue;\n }\n const start = startPoses.get(id);\n if (!start) continue;\n const o = d.getBounds(start);\n const { nx, ny, hit } = clampToBounds(o.x, o.y, delta.x, delta.y);\n if (!hit) allHit = false;\n finalPositions.set(id, { x: nx, y: ny });\n frame.set(id, translatePoseViaDescriptor(start, nx - o.x, ny - o.y, d));\n }\n show(frame);\n for (const id of riding) lastSeen.set(id, d.getBounds(adapter.getPose(id)));\n if (riding.size === 0) {\n coasts.delete(coast);\n decayHandle.cancel();\n return;\n }\n // If 'stop' policy and every dragged id's clamped position hit\n // the boundary, cancel the decay so the animation settles instantly\n // instead of drifting along the edge as friction wears off.\n if (boundaryPolicy === 'stop' && allHit) coast.stop();\n },\n onDone: () => {\n commitFlick();\n },\n });\n\n function commitFlick(): void {\n if (!coasts.delete(coast)) return;\n const ops: Op[] = [];\n const shown = new Map<string, TPose | null>();\n for (const id of riding) {\n shown.set(id, null);\n if (!stillOurs(id)) continue;\n const start = startPoses.get(id);\n if (!start) continue;\n const o = d.getBounds(start);\n const fp = finalPositions.get(id) ?? { x: o.x + lastValue.x, y: o.y + lastValue.y };\n const finalPose = translatePoseViaDescriptor(start, fp.x - o.x, fp.y - o.y, d);\n const from = ctx.origin.get(id) ?? start;\n ops.push(createTransformOp<TPose>({ id, from, to: finalPose, label: 'flick' }));\n }\n // The document first, so the preview never gives way to the pre-drag pose.\n if (ops.length > 0) {\n if (adapter.applyOps) adapter.applyOps(ops, 'flick');\n else if (adapter.previewPoses) for (const op of ops) op.apply(adapter);\n }\n adapter.previewPoses?.(shown);\n }\n\n return null;\n },\n };\n}\n"],"mappings":"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"}
|
package/dist/animation/loop.js
CHANGED
|
@@ -8,27 +8,25 @@ function e(e, t, n = {}) {
|
|
|
8
8
|
s.setOnCancel(() => {
|
|
9
9
|
a = !0, o?.cancel(), o = null;
|
|
10
10
|
});
|
|
11
|
-
let c = () => {
|
|
11
|
+
let c = (e, t) => {
|
|
12
|
+
o && (e ? o.pause() : o.resume(), o.setTimeScale(t));
|
|
13
|
+
};
|
|
14
|
+
s.setOnRate(c);
|
|
15
|
+
let l = () => {
|
|
12
16
|
if (!a) {
|
|
13
17
|
if (i >= r) {
|
|
14
18
|
o = null, a = !0, s.finish(), n.onDone?.();
|
|
15
19
|
return;
|
|
16
20
|
}
|
|
17
|
-
o = t(i++, c);
|
|
21
|
+
o = t(i++, l), (s.isPaused() || s.timeScale() !== 1) && c(s.isPaused(), s.timeScale());
|
|
18
22
|
}
|
|
19
23
|
};
|
|
20
|
-
return
|
|
24
|
+
return l(), {
|
|
21
25
|
id: s.id,
|
|
22
26
|
cancel: () => s.cancel(),
|
|
23
|
-
pause: () =>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
resume: () => {
|
|
27
|
-
s.resume(), o?.resume();
|
|
28
|
-
},
|
|
29
|
-
setTimeScale: (e) => {
|
|
30
|
-
s.setTimeScale(e), o?.setTimeScale(e);
|
|
31
|
-
},
|
|
27
|
+
pause: () => s.pause(),
|
|
28
|
+
resume: () => s.resume(),
|
|
29
|
+
setTimeScale: (e) => s.setTimeScale(e),
|
|
32
30
|
timeScale: () => s.timeScale(),
|
|
33
31
|
isPaused: () => s.isPaused()
|
|
34
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.js","names":["createLoop","max","opts","iteration","cancelled","current","supervisor","createSupervisor","next","factory","s","createTweenLoop","direction","o","flipped","i","from","to","animator"],"sources":["../../src/animation/loop.ts"],"sourcesContent":["import type { SupervisorFactory } from './supervisor';\nimport type {\n AnimationHandle,\n Animator,\n LoopFactory,\n LoopOptions,\n TweenLoopOptions,\n} from './types';\n\n/**\n * Loop primitive. Repeatedly invokes `factory(i, next)` to produce a child\n * animation. The factory is responsible for wiring its returned handle's\n * `onDone` to call `next` — that's how the loop advances. Pause/resume/\n * setTimeScale
|
|
1
|
+
{"version":3,"file":"loop.js","names":["createLoop","max","opts","iteration","cancelled","current","supervisor","createSupervisor","applyRate","paused","timeScale","next","factory","s","createTweenLoop","direction","o","flipped","i","from","to","animator"],"sources":["../../src/animation/loop.ts"],"sourcesContent":["import type { SupervisorFactory } from './supervisor';\nimport type {\n AnimationHandle,\n Animator,\n LoopFactory,\n LoopOptions,\n TweenLoopOptions,\n} from './types';\n\n/**\n * Loop primitive. Repeatedly invokes `factory(i, next)` to produce a child\n * animation. The factory is responsible for wiring its returned handle's\n * `onDone` to call `next` — that's how the loop advances. Pause/resume/\n * setTimeScale reach the current child and each later one; cancel stops the\n * in-flight child and prevents future iterations.\n *\n * The loop is registered with the animator under a supervisor entry, so\n * `animator.cancel(handle)`, `animator.cancelKey(key)`, and\n * `animator.isActive(key)` all work for it.\n */\nexport function createLoop(\n createSupervisor: SupervisorFactory,\n factory: LoopFactory,\n opts: LoopOptions = {},\n): AnimationHandle {\n const max = opts.count ?? Infinity;\n let iteration = 0;\n let cancelled = false;\n let current: AnimationHandle | null = null;\n\n const supervisor = createSupervisor({ kind: 'loop', cancelKey: opts.cancelKey, label: opts.label });\n supervisor.setOnCancel(() => {\n // External cancel path (animator.cancel/cancelKey or handle.cancel).\n // Mark cancelled so `next` short-circuits; tear down the current child.\n cancelled = true;\n current?.cancel();\n current = null;\n });\n\n const applyRate = (paused: boolean, timeScale: number): void => {\n if (!current) return;\n if (paused) current.pause();\n else current.resume();\n current.setTimeScale(timeScale);\n };\n supervisor.setOnRate(applyRate);\n\n const next = (): void => {\n if (cancelled) return;\n if (iteration >= max) {\n current = null;\n // Natural completion: deregister the supervisor so isActive() goes\n // false. `cancelled` makes a late `next` a no-op.\n cancelled = true;\n supervisor.finish();\n opts.onDone?.();\n return;\n }\n const i = iteration++;\n current = factory(i, next);\n if (supervisor.isPaused() || supervisor.timeScale() !== 1) {\n applyRate(supervisor.isPaused(), supervisor.timeScale());\n }\n };\n\n next();\n\n return {\n id: supervisor.id,\n cancel: () => supervisor.cancel(),\n pause: () => supervisor.pause(),\n resume: () => supervisor.resume(),\n setTimeScale: (s) => supervisor.setTimeScale(s),\n timeScale: () => supervisor.timeScale(),\n isPaused: () => supervisor.isPaused(),\n };\n}\n\n/**\n * Sugar over `createLoop` for the common case of looping a tween between two\n * values. `direction` controls per-iteration from/to:\n * - `restart` (default): from→to every iteration\n * - `reverse`: to→from every iteration\n * - `alternate`: even iterations from→to, odd iterations to→from\n */\nexport function createTweenLoop<T>(\n animator: Animator,\n createSupervisor: SupervisorFactory,\n opts: TweenLoopOptions<T>,\n): AnimationHandle {\n const direction = opts.direction ?? 'restart';\n return createLoop(\n (o) => createSupervisor({ ...o, kind: 'tweenLoop' }),\n (i, next) => {\n const flipped = direction === 'reverse' || (direction === 'alternate' && i % 2 === 1);\n const from = flipped ? opts.to : opts.from;\n const to = flipped ? opts.from : opts.to;\n return animator.tween({\n from,\n to,\n ms: opts.ms,\n easing: opts.easing,\n interpolate: opts.interpolate,\n onTick: opts.onTick,\n onDone: next,\n });\n },\n { count: opts.count, onDone: opts.onDone, cancelKey: opts.cancelKey, label: opts.label },\n );\n}\n"],"mappings":";AAoBA,SAAgBA,EACd,GACA,GACA,IAAoB,CAAC,GACJ;CACjB,IAAMC,IAAMC,EAAK,SAAS,UACtBC,IAAY,GACZC,IAAY,IACZC,IAAkC,MAEhCC,IAAaC,EAAiB;EAAE,MAAM;EAAQ,WAAWL,EAAK;EAAW,OAAOA,EAAK;CAAM,CAAC;CAClG,EAAW,kBAAkB;EAK3B,AAFA,IAAY,IACZG,GAAS,OAAO,GAChB,IAAU;CACZ,CAAC;CAED,IAAMG,KAAa,GAAiB,MAA4B;EAC9D,AAAKH,MACDI,IAAQJ,EAAQ,MAAM,IACrBA,EAAQ,OAAO,GACpBA,EAAQ,aAAaK,CAAS;CAChC;CACA,EAAW,UAAUF,CAAS;CAE9B,IAAMG,UAAmB;EACvB,IAAI,IACJ;OAAIR,KAAaF,GAAK;IAMpB,AALA,IAAU,MAGV,IAAY,IACZK,EAAW,OAAO,GAClBJ,EAAK,SAAS;IACd;GACF;GAGA,AADA,IAAUU,EAAQ,KAAGD,CAAI,IACrBL,EAAW,SAAS,KAAKA,EAAW,UAAU,MAAM,MACtDE,EAAUF,EAAW,SAAS,GAAGA,EAAW,UAAU,CAAC;EAJzD;CAMF;CAIA,OAFAK,EAAK,GAEE;EACL,IAAIL,EAAW;EACf,cAAcA,EAAW,OAAO;EAChC,aAAaA,EAAW,MAAM;EAC9B,cAAcA,EAAW,OAAO;EAChC,eAAe,MAAMA,EAAW,aAAaO,CAAC;EAC9C,iBAAiBP,EAAW,UAAU;EACtC,gBAAgBA,EAAW,SAAS;CACtC;AACF;AASA,SAAgBQ,EACd,GACA,GACA,GACiB;CACjB,IAAMC,IAAYb,EAAK,aAAa;CACpC,OAAOF,GACJ,MAAMO,EAAiB;EAAE,GAAGS;EAAG,MAAM;CAAY,CAAC,IAClD,GAAG,MAAS;EACX,IAAMC,IAAUF,MAAc,aAAcA,MAAc,eAAeG,IAAI,KAAM,GAC7EC,IAAOF,IAAUf,EAAK,KAAKA,EAAK,MAChCkB,IAAKH,IAAUf,EAAK,OAAOA,EAAK;EACtC,OAAOmB,EAAS,MAAM;GACpB;GACA;GACA,IAAInB,EAAK;GACT,QAAQA,EAAK;GACb,aAAaA,EAAK;GAClB,QAAQA,EAAK;GACb,QAAQS;EACV,CAAC;CACH,GACA;EAAE,OAAOT,EAAK;EAAO,QAAQA,EAAK;EAAQ,WAAWA,EAAK;EAAW,OAAOA,EAAK;CAAM,CACzF;AACF"}
|
package/dist/animation/reflow.js
CHANGED
|
@@ -54,13 +54,13 @@ function c(r, i, a) {
|
|
|
54
54
|
onTick: _,
|
|
55
55
|
onDone: v
|
|
56
56
|
}), r.overrides.commit();
|
|
57
|
-
}, h = (e) => {
|
|
57
|
+
}, h = (e, t) => i.isActive(o(e)) || s(t.entry.pose, t.target), g = (e) => {
|
|
58
58
|
let t = c.get(e);
|
|
59
59
|
if (!t) return;
|
|
60
60
|
c.delete(e), t.handle?.cancel();
|
|
61
61
|
let n = e;
|
|
62
62
|
r.overrides.get(n) === t.entry && (r.overrides.clear(n), r.overrides.commit()), f();
|
|
63
|
-
},
|
|
63
|
+
}, _ = (e, n, i, a) => {
|
|
64
64
|
if (i) a !== void 0 && (i.entry.pose = a);
|
|
65
65
|
else {
|
|
66
66
|
let o = a ?? t(r, n);
|
|
@@ -78,28 +78,28 @@ function c(r, i, a) {
|
|
|
78
78
|
let i = r.get(e);
|
|
79
79
|
if (!i) return;
|
|
80
80
|
let a = n?.from, o = c.get(e);
|
|
81
|
-
o && a === void 0 && !o.settling && s(o.target, t) || m(e,
|
|
81
|
+
o && a === void 0 && !o.settling && s(o.target, t) && h(e, o) || m(e, _(e, i, o, a), t, !1);
|
|
82
82
|
},
|
|
83
83
|
settle(t, n) {
|
|
84
84
|
let i = n?.from, a = c.get(t);
|
|
85
85
|
if (!a && i === void 0) return;
|
|
86
86
|
let o = r.get(t);
|
|
87
87
|
if (!o) {
|
|
88
|
-
|
|
88
|
+
g(t);
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
91
|
let l = e(r, o);
|
|
92
92
|
if (a && i === void 0) {
|
|
93
|
-
if (a.settling && s(a.target, l)) return;
|
|
93
|
+
if (a.settling && s(a.target, l) && h(t, a)) return;
|
|
94
94
|
m(t, a, l, !0);
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
|
-
m(t,
|
|
97
|
+
m(t, _(t, o, a, i), l, !0);
|
|
98
98
|
},
|
|
99
|
-
stop:
|
|
99
|
+
stop: g,
|
|
100
100
|
poseOf: (e) => c.get(e)?.entry.pose,
|
|
101
101
|
dispose() {
|
|
102
|
-
for (let e of [...c.keys()])
|
|
102
|
+
for (let e of [...c.keys()]) g(e);
|
|
103
103
|
}
|
|
104
104
|
};
|
|
105
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reflow.js","names":["keyFor","id","samePose","a","b","ka","k","makeReflow","glides","dirty","unsubscribe","subscribe","animator","scene","unsubscribeIfIdle","release","g","nid","run","from","to","settling","o","read","lerp","RECT_POSE_DESCRIPTOR","onTick","p","onDone","cancelKey","label","stop","claim","start","effectivePose","node","opts","pose","home","documentPose","createReflowTransition","useAnimatedReflow","latest","useLatest","enabled","reflow","useMemo","useEffect"],"sources":["../../src/animation/reflow.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { RECT_POSE_DESCRIPTOR, type PoseDescriptor } from '../core/geometry/poseDescriptor';\nimport { documentPose, effectivePose, type PosedNode, type PoseSource } from '../core/scene/effectivePose';\nimport type { NodeId, PoseOverride, PoseOverrides } from '../core/scene/types';\nimport type { ReflowTransition } from '../layout/types';\nimport type { AnimationHandle, Animator, EasingSpec, SpringPresetName } from './types';\n\n/** How a reflowed sibling travels: a duration and easing, or a spring. */\nexport interface ReflowTransitionOptions<TPose> {\n /** Default 200. Ignored under `spring`. */\n ms?: number;\n easing?: EasingSpec;\n /** Travel on a spring instead of a duration. A retarget restarts it from\n * the pose on screen, so position stays continuous and velocity does not\n * carry over. */\n spring?: {\n preset?: SpringPresetName;\n stiffness?: number;\n damping?: number;\n mass?: number;\n };\n /** Supplies the `lerp` between two poses. Default `RECT_POSE_DESCRIPTOR`. */\n geometry?: PoseDescriptor<TPose>;\n /** Names each glide in `animator.watch` and `live()`. Default `'reflow'`. */\n label?: string;\n}\n\n/** A {@link ReflowTransition} the animator drives. `dispose` drops every\n * override it holds; the transition stays usable afterward. */\nexport interface AnimatedReflow<TPose = unknown> extends ReflowTransition<TPose> {\n dispose(): void;\n}\n\n/** The part of a scene a reflow transition reads and overrides. */\nexport interface ReflowScene<TPose> extends PoseSource<TPose> {\n readonly overrides: PoseOverrides<TPose>;\n}\n\ninterface Glide<TPose> {\n entry: PoseOverride<TPose>;\n target: TPose;\n settling: boolean;\n handle: AnimationHandle | null;\n}\n\n/** The animator's cancel-key for one node's glide. */\nconst keyFor = (id: string): string => `reflow:${id}`;\n\nfunction samePose(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a);\n if (ka.length !== Object.keys(b).length) return false;\n for (const k of ka) {\n if (!samePose((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k])) return false;\n }\n return true;\n}\n\nfunction makeReflow<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n read: () => ReflowTransitionOptions<TPose>,\n): AnimatedReflow<TPose> {\n const glides = new Map<string, Glide<TPose>>();\n let dirty = false;\n let unsubscribe: (() => void) | null = null;\n\n // Ticks only mark the frame dirty; one commit per animator frame publishes\n // every glide at once.\n const subscribe = (): void => {\n if (unsubscribe) return;\n unsubscribe = animator.onTick(() => {\n if (!dirty) return;\n dirty = false;\n scene.overrides.commit();\n });\n };\n const unsubscribeIfIdle = (): void => {\n if (glides.size > 0 || !unsubscribe) return;\n unsubscribe();\n unsubscribe = null;\n };\n\n const release = (id: string, g: Glide<TPose>): void => {\n if (glides.get(id) === g) glides.delete(id);\n const nid = id as NodeId;\n if (scene.overrides.get(nid) === g.entry) scene.overrides.clear(nid);\n dirty = true;\n };\n\n const run = (id: string, g: Glide<TPose>, to: TPose, settling: boolean): void => {\n const from = g.entry.pose as TPose;\n g.target = to;\n g.settling = settling;\n if (samePose(from, to)) {\n g.handle?.cancel();\n g.handle = null;\n g.entry.pose = to;\n if (settling) release(id, g);\n scene.overrides.commit();\n unsubscribeIfIdle();\n return;\n }\n const o = read();\n const lerp = (o.geometry ?? (RECT_POSE_DESCRIPTOR as unknown as PoseDescriptor<TPose>)).lerp;\n if (!lerp) throw new Error('useAnimatedReflow: geometry has no lerp; supply geometry: { ..., lerp }');\n const onTick = (p: number): void => {\n g.entry.pose = lerp(from, to, p);\n dirty = true;\n };\n const onDone = (): void => {\n g.handle = null;\n if (!g.settling) return;\n release(id, g);\n unsubscribeIfIdle();\n };\n const cancelKey = keyFor(id);\n const label = o.label ?? 'reflow';\n subscribe();\n // The shared key is what retargets: the new animation interrupts the old.\n g.handle = o.spring\n ? animator.spring<number>({ from: 0, to: 1, ...o.spring, cancelKey, label, onTick, onDone })\n : animator.tween<number>({ from: 0, to: 1, ms: o.ms ?? 200, easing: o.easing, cancelKey, label, onTick, onDone });\n scene.overrides.commit();\n };\n\n const stop = (id: string): void => {\n const g = glides.get(id);\n if (!g) return;\n glides.delete(id);\n g.handle?.cancel();\n const nid = id as NodeId;\n if (scene.overrides.get(nid) === g.entry) {\n scene.overrides.clear(nid);\n scene.overrides.commit();\n }\n unsubscribeIfIdle();\n };\n\n // The glide for `id`, created if absent, starting from `from` when given,\n // and published over whatever override is showing the node.\n const claim = (\n id: string,\n node: PosedNode<TPose>,\n g: Glide<TPose> | undefined,\n from: TPose | undefined,\n ): Glide<TPose> => {\n if (!g) {\n const start = from ?? effectivePose(scene, node);\n g = { entry: { pose: start }, target: start, settling: false, handle: null };\n glides.set(id, g);\n } else if (from !== undefined) {\n g.entry.pose = from;\n }\n if (scene.overrides.get(id as NodeId) !== g.entry) scene.overrides.set(id as NodeId, g.entry);\n return g;\n };\n\n return {\n glide(id, pose, opts) {\n const node = scene.get(id as NodeId);\n if (!node) return;\n const from = opts?.from;\n const g = glides.get(id);\n if (g && from === undefined && !g.settling && samePose(g.target, pose)) return;\n run(id, claim(id, node, g, from), pose, false);\n },\n settle(id, opts) {\n const from = opts?.from;\n const g = glides.get(id);\n if (!g && from === undefined) return;\n const node = scene.get(id as NodeId);\n if (!node) { stop(id); return; }\n const home = documentPose(scene, node);\n if (g && from === undefined) {\n if (g.settling && samePose(g.target, home)) return;\n run(id, g, home, true);\n return;\n }\n run(id, claim(id, node, g, from), home, true);\n },\n stop,\n poseOf: (id) => glides.get(id)?.entry.pose,\n dispose() {\n for (const id of [...glides.keys()]) stop(id);\n },\n };\n}\n\n/**\n * A reflow transition over `animator`: each glide is a tween (or spring) of\n * its own, keyed `reflow:<id>`, so a new target for a node interrupts the\n * glide it is on and `animator.cancelKey` reaches one node's. See\n * {@link useAnimatedReflow} for the hook form.\n */\nexport function createReflowTransition<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n opts: ReflowTransitionOptions<TPose> = {},\n): AnimatedReflow<TPose> {\n return makeReflow(scene, animator, () => opts);\n}\n\n/**\n * Opt a canvas's layout reflow into animation: pass the result to\n * `<SceneCanvas reflowTransition>` and siblings a drag displaces glide to\n * their slots instead of snapping. `null` (or `false`) turns it off, and\n * whatever it was holding snaps home. Option changes apply from the next\n * glide on, without rebuilding.\n */\nexport function useAnimatedReflow<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n opts: ReflowTransitionOptions<TPose> | null | false | undefined,\n): AnimatedReflow<TPose> | null {\n const latest = useLatest(opts || {});\n const enabled = !!opts;\n const reflow = useMemo(\n () => (enabled ? makeReflow(scene, animator, () => latest.current) : null),\n [enabled, scene, animator, latest],\n );\n useEffect(() => () => reflow?.dispose(), [reflow]);\n return reflow;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"reflow.js","names":["keyFor","id","samePose","a","b","ka","k","makeReflow","glides","dirty","unsubscribe","subscribe","animator","scene","unsubscribeIfIdle","release","g","nid","run","from","to","settling","o","read","lerp","RECT_POSE_DESCRIPTOR","onTick","p","onDone","cancelKey","label","onCourse","stop","claim","start","effectivePose","node","opts","pose","home","documentPose","createReflowTransition","useAnimatedReflow","latest","useLatest","enabled","reflow","useMemo","useEffect"],"sources":["../../src/animation/reflow.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { RECT_POSE_DESCRIPTOR, type PoseDescriptor } from '../core/geometry/poseDescriptor';\nimport { documentPose, effectivePose, type PosedNode, type PoseSource } from '../core/scene/effectivePose';\nimport type { NodeId, PoseOverride, PoseOverrides } from '../core/scene/types';\nimport type { ReflowTransition } from '../layout/types';\nimport type { AnimationHandle, Animator, EasingSpec, SpringPresetName } from './types';\n\n/** How a reflowed sibling travels: a duration and easing, or a spring. */\nexport interface ReflowTransitionOptions<TPose> {\n /** Default 200. Ignored under `spring`. */\n ms?: number;\n easing?: EasingSpec;\n /** Travel on a spring instead of a duration. A retarget restarts it from\n * the pose on screen, so position stays continuous and velocity does not\n * carry over. */\n spring?: {\n preset?: SpringPresetName;\n stiffness?: number;\n damping?: number;\n mass?: number;\n };\n /** Supplies the `lerp` between two poses. Default `RECT_POSE_DESCRIPTOR`. */\n geometry?: PoseDescriptor<TPose>;\n /** Names each glide in `animator.watch` and `live()`. Default `'reflow'`. */\n label?: string;\n}\n\n/** A {@link ReflowTransition} the animator drives. `dispose` drops every\n * override it holds; the transition stays usable afterward. */\nexport interface AnimatedReflow<TPose = unknown> extends ReflowTransition<TPose> {\n dispose(): void;\n}\n\n/** The part of a scene a reflow transition reads and overrides. */\nexport interface ReflowScene<TPose> extends PoseSource<TPose> {\n readonly overrides: PoseOverrides<TPose>;\n}\n\ninterface Glide<TPose> {\n entry: PoseOverride<TPose>;\n target: TPose;\n settling: boolean;\n handle: AnimationHandle | null;\n}\n\n/** The animator's cancel-key for one node's glide. */\nconst keyFor = (id: string): string => `reflow:${id}`;\n\nfunction samePose(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a);\n if (ka.length !== Object.keys(b).length) return false;\n for (const k of ka) {\n if (!samePose((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k])) return false;\n }\n return true;\n}\n\nfunction makeReflow<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n read: () => ReflowTransitionOptions<TPose>,\n): AnimatedReflow<TPose> {\n const glides = new Map<string, Glide<TPose>>();\n let dirty = false;\n let unsubscribe: (() => void) | null = null;\n\n // Ticks only mark the frame dirty; one commit per animator frame publishes\n // every glide at once.\n const subscribe = (): void => {\n if (unsubscribe) return;\n unsubscribe = animator.onTick(() => {\n if (!dirty) return;\n dirty = false;\n scene.overrides.commit();\n });\n };\n const unsubscribeIfIdle = (): void => {\n if (glides.size > 0 || !unsubscribe) return;\n unsubscribe();\n unsubscribe = null;\n };\n\n const release = (id: string, g: Glide<TPose>): void => {\n if (glides.get(id) === g) glides.delete(id);\n const nid = id as NodeId;\n if (scene.overrides.get(nid) === g.entry) scene.overrides.clear(nid);\n dirty = true;\n };\n\n const run = (id: string, g: Glide<TPose>, to: TPose, settling: boolean): void => {\n const from = g.entry.pose as TPose;\n g.target = to;\n g.settling = settling;\n if (samePose(from, to)) {\n g.handle?.cancel();\n g.handle = null;\n g.entry.pose = to;\n if (settling) release(id, g);\n scene.overrides.commit();\n unsubscribeIfIdle();\n return;\n }\n const o = read();\n const lerp = (o.geometry ?? (RECT_POSE_DESCRIPTOR as unknown as PoseDescriptor<TPose>)).lerp;\n if (!lerp) throw new Error('useAnimatedReflow: geometry has no lerp; supply geometry: { ..., lerp }');\n const onTick = (p: number): void => {\n g.entry.pose = lerp(from, to, p);\n dirty = true;\n };\n const onDone = (): void => {\n g.handle = null;\n if (!g.settling) return;\n release(id, g);\n unsubscribeIfIdle();\n };\n const cancelKey = keyFor(id);\n const label = o.label ?? 'reflow';\n subscribe();\n // The shared key is what retargets: the new animation interrupts the old.\n g.handle = o.spring\n ? animator.spring<number>({ from: 0, to: 1, ...o.spring, cancelKey, label, onTick, onDone })\n : animator.tween<number>({ from: 0, to: 1, ms: o.ms ?? 200, easing: o.easing, cancelKey, label, onTick, onDone });\n scene.overrides.commit();\n };\n\n // False for a glide canceled through the animator: it stopped short of its\n // target and nothing is carrying it there.\n const onCourse = (id: string, g: Glide<TPose>): boolean =>\n animator.isActive(keyFor(id)) || samePose(g.entry.pose, g.target);\n\n const stop = (id: string): void => {\n const g = glides.get(id);\n if (!g) return;\n glides.delete(id);\n g.handle?.cancel();\n const nid = id as NodeId;\n if (scene.overrides.get(nid) === g.entry) {\n scene.overrides.clear(nid);\n scene.overrides.commit();\n }\n unsubscribeIfIdle();\n };\n\n // The glide for `id`, created if absent, starting from `from` when given,\n // and published over whatever override is showing the node.\n const claim = (\n id: string,\n node: PosedNode<TPose>,\n g: Glide<TPose> | undefined,\n from: TPose | undefined,\n ): Glide<TPose> => {\n if (!g) {\n const start = from ?? effectivePose(scene, node);\n g = { entry: { pose: start }, target: start, settling: false, handle: null };\n glides.set(id, g);\n } else if (from !== undefined) {\n g.entry.pose = from;\n }\n if (scene.overrides.get(id as NodeId) !== g.entry) scene.overrides.set(id as NodeId, g.entry);\n return g;\n };\n\n return {\n glide(id, pose, opts) {\n const node = scene.get(id as NodeId);\n if (!node) return;\n const from = opts?.from;\n const g = glides.get(id);\n if (g && from === undefined && !g.settling && samePose(g.target, pose) && onCourse(id, g)) return;\n run(id, claim(id, node, g, from), pose, false);\n },\n settle(id, opts) {\n const from = opts?.from;\n const g = glides.get(id);\n if (!g && from === undefined) return;\n const node = scene.get(id as NodeId);\n if (!node) { stop(id); return; }\n const home = documentPose(scene, node);\n if (g && from === undefined) {\n if (g.settling && samePose(g.target, home) && onCourse(id, g)) return;\n run(id, g, home, true);\n return;\n }\n run(id, claim(id, node, g, from), home, true);\n },\n stop,\n poseOf: (id) => glides.get(id)?.entry.pose,\n dispose() {\n for (const id of [...glides.keys()]) stop(id);\n },\n };\n}\n\n/**\n * A reflow transition over `animator`: each glide is a tween (or spring) of\n * its own, keyed `reflow:<id>`, so a new target for a node interrupts the\n * glide it is on and `animator.cancelKey` reaches one node's. See\n * {@link useAnimatedReflow} for the hook form.\n */\nexport function createReflowTransition<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n opts: ReflowTransitionOptions<TPose> = {},\n): AnimatedReflow<TPose> {\n return makeReflow(scene, animator, () => opts);\n}\n\n/**\n * Opt a canvas's layout reflow into animation: pass the result to\n * `<SceneCanvas reflowTransition>` and siblings a drag displaces glide to\n * their slots instead of snapping. `null` (or `false`) turns it off, and\n * whatever it was holding snaps home. Option changes apply from the next\n * glide on, without rebuilding.\n */\nexport function useAnimatedReflow<TPose>(\n scene: ReflowScene<TPose>,\n animator: Animator,\n opts: ReflowTransitionOptions<TPose> | null | false | undefined,\n): AnimatedReflow<TPose> | null {\n const latest = useLatest(opts || {});\n const enabled = !!opts;\n const reflow = useMemo(\n () => (enabled ? makeReflow(scene, animator, () => latest.current) : null),\n [enabled, scene, animator, latest],\n );\n useEffect(() => () => reflow?.dispose(), [reflow]);\n return reflow;\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { springPose as e } from "./poseHelpers.js";
|
|
2
2
|
//#region src/animation/stagger.ts
|
|
3
3
|
var t = class {
|
|
4
|
-
timers;
|
|
5
4
|
supervisor;
|
|
6
5
|
id;
|
|
7
6
|
cancelled = !1;
|
|
@@ -11,14 +10,14 @@ var t = class {
|
|
|
11
10
|
pending = [];
|
|
12
11
|
outstanding;
|
|
13
12
|
finished = !1;
|
|
14
|
-
constructor(e, t
|
|
15
|
-
this.
|
|
13
|
+
constructor(e, t) {
|
|
14
|
+
this.supervisor = e, this.id = e.id, this.outstanding = t, e.setOnCancel(() => this.handleSupervisorCancel()), e.setOnRate((e, t) => {
|
|
15
|
+
e ? this.applyPause() : this.applyResume(), this.applyTimeScale(t);
|
|
16
|
+
}), e.setOnFrame((e) => this.fireDue(e));
|
|
16
17
|
}
|
|
17
18
|
handleSupervisorCancel() {
|
|
18
19
|
if (this.cancelled) return;
|
|
19
|
-
this.cancelled = !0;
|
|
20
|
-
for (let e of this.pending) e.timer != null && this.timers.clearTimer(e.timer);
|
|
21
|
-
this.pending = [];
|
|
20
|
+
this.cancelled = !0, this.pending = [];
|
|
22
21
|
let e = this.children.slice();
|
|
23
22
|
this.children = [];
|
|
24
23
|
for (let t of e) t.cancel();
|
|
@@ -34,40 +33,49 @@ var t = class {
|
|
|
34
33
|
this.children.push(e), this.paused_ && e.pause(), this.timeScale_ !== 1 && e.setTimeScale(this.timeScale_);
|
|
35
34
|
}
|
|
36
35
|
schedule(e, t) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
this.cancelled || this.pending.push({
|
|
37
|
+
at: e,
|
|
38
|
+
fire: t
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
fireDue(e) {
|
|
42
|
+
if (this.cancelled || this.pending.length === 0) return;
|
|
43
|
+
let t = this.pending.filter((t) => t.at <= e).sort((e, t) => e.at - t.at);
|
|
44
|
+
this.pending = this.pending.filter((t) => t.at > e);
|
|
45
|
+
for (let e of t) {
|
|
46
46
|
if (this.cancelled) return;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}, this.paused_ ? n.paused = !0 : n.timer = this.timers.setTimer(n.fire, e), this.pending.push(n);
|
|
47
|
+
e.fire();
|
|
48
|
+
}
|
|
50
49
|
}
|
|
51
50
|
cancel() {
|
|
52
51
|
this.supervisor.cancel();
|
|
53
52
|
}
|
|
54
53
|
pause() {
|
|
55
|
-
|
|
56
|
-
this.paused_ = !0;
|
|
57
|
-
let e = this.timers.now();
|
|
58
|
-
for (let t of this.pending) t.timer != null && (t.remainingMs = Math.max(0, t.resolvedAt - e), this.timers.clearTimer(t.timer), t.timer = null, t.paused = !0);
|
|
59
|
-
for (let e of this.children) e.pause();
|
|
54
|
+
this.supervisor.pause();
|
|
60
55
|
}
|
|
61
56
|
resume() {
|
|
62
|
-
|
|
63
|
-
this.paused_ = !1;
|
|
64
|
-
let e = this.timers.now();
|
|
65
|
-
for (let t of this.pending) t.paused &&= (t.resolvedAt = e + t.remainingMs, t.timer = this.timers.setTimer(t.fire, t.remainingMs), !1);
|
|
66
|
-
for (let e of this.children) e.resume();
|
|
57
|
+
this.supervisor.resume();
|
|
67
58
|
}
|
|
68
59
|
setTimeScale(e) {
|
|
69
|
-
this.
|
|
70
|
-
|
|
60
|
+
this.supervisor.setTimeScale(e);
|
|
61
|
+
}
|
|
62
|
+
applyPause() {
|
|
63
|
+
if (!this.paused_) {
|
|
64
|
+
this.paused_ = !0;
|
|
65
|
+
for (let e of this.children) e.pause();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
applyResume() {
|
|
69
|
+
if (this.paused_) {
|
|
70
|
+
this.paused_ = !1;
|
|
71
|
+
for (let e of this.children) e.resume();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
applyTimeScale(e) {
|
|
75
|
+
if (e !== this.timeScale_) {
|
|
76
|
+
this.timeScale_ = e;
|
|
77
|
+
for (let t of this.children) t.setTimeScale(e);
|
|
78
|
+
}
|
|
71
79
|
}
|
|
72
80
|
timeScale() {
|
|
73
81
|
return this.timeScale_;
|
|
@@ -79,22 +87,22 @@ var t = class {
|
|
|
79
87
|
function n(e, t) {
|
|
80
88
|
return typeof e == "function" ? e(t) : e * t;
|
|
81
89
|
}
|
|
82
|
-
function r(e, t, n, r, a, o, c
|
|
83
|
-
return
|
|
90
|
+
function r(e, t, n, r, a, o, c) {
|
|
91
|
+
return o ? i(t, n, r, a, o, c) : s(e, t, n, r, a);
|
|
84
92
|
}
|
|
85
|
-
function i(e, r, i, a, o, s
|
|
86
|
-
let
|
|
93
|
+
function i(e, r, i, a, o, s) {
|
|
94
|
+
let c = e({
|
|
87
95
|
kind: "stagger",
|
|
88
|
-
cancelKey:
|
|
89
|
-
label:
|
|
90
|
-
}),
|
|
91
|
-
return
|
|
92
|
-
let
|
|
93
|
-
let n =
|
|
94
|
-
|
|
96
|
+
cancelKey: s?.cancelKey,
|
|
97
|
+
label: s?.label
|
|
98
|
+
}), l = new t(c, i.length);
|
|
99
|
+
return i.length === 0 ? (c.finish(), l) : (i.forEach((e, t) => {
|
|
100
|
+
let i = n(a, t), s = () => {
|
|
101
|
+
let n = o(e, t);
|
|
102
|
+
r(n.id, () => l.noteChildDone()), l.addChild(n);
|
|
95
103
|
};
|
|
96
|
-
|
|
97
|
-
}),
|
|
104
|
+
i <= 0 ? s() : l.schedule(i, s);
|
|
105
|
+
}), l);
|
|
98
106
|
}
|
|
99
107
|
function a(e, t, n) {
|
|
100
108
|
return typeof e == "function" ? e(t, n) : e;
|
|
@@ -107,10 +115,10 @@ function o(e) {
|
|
|
107
115
|
if (typeof e == "string" || typeof e == "number") return String(e);
|
|
108
116
|
throw Error("stagger().springPose: each item must either be a primitive (string/number) or have a string `id` field. Otherwise pose ids would collide.");
|
|
109
117
|
}
|
|
110
|
-
function s(t, n, r, s, c
|
|
118
|
+
function s(t, n, r, s, c) {
|
|
111
119
|
return {
|
|
112
|
-
each: (e, t) => i(n, r, s, c,
|
|
113
|
-
tween: (e) => i(n, r, s, c,
|
|
120
|
+
each: (e, t) => i(n, r, s, c, e, t),
|
|
121
|
+
tween: (e) => i(n, r, s, c, (n, r) => t.tween({
|
|
114
122
|
from: a(e.from, n, r),
|
|
115
123
|
to: a(e.to, n, r),
|
|
116
124
|
ms: a(e.ms, n, r),
|
|
@@ -119,17 +127,17 @@ function s(t, n, r, s, c, l) {
|
|
|
119
127
|
onTick: (t) => e.onTick(t, n, r),
|
|
120
128
|
onDone: e.onDone ? () => e.onDone(n, r) : void 0
|
|
121
129
|
}), e),
|
|
122
|
-
springPose: (a,
|
|
130
|
+
springPose: (a, l, u = {}) => i(n, r, s, c, (n, r) => e(t, a, {
|
|
123
131
|
id: o(n),
|
|
124
|
-
to:
|
|
125
|
-
preset:
|
|
126
|
-
stiffness:
|
|
127
|
-
damping:
|
|
128
|
-
mass:
|
|
129
|
-
geometry:
|
|
130
|
-
recordOp:
|
|
131
|
-
opLabel:
|
|
132
|
-
}),
|
|
132
|
+
to: l(n, r),
|
|
133
|
+
preset: u.preset,
|
|
134
|
+
stiffness: u.stiffness,
|
|
135
|
+
damping: u.damping,
|
|
136
|
+
mass: u.mass,
|
|
137
|
+
geometry: u.geometry,
|
|
138
|
+
recordOp: u.recordOp,
|
|
139
|
+
opLabel: u.opLabel
|
|
140
|
+
}), u)
|
|
133
141
|
};
|
|
134
142
|
}
|
|
135
143
|
//#endregion
|