@weasel-js/core 1.9.4 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +750 -0
- package/README.md +5 -3
- package/dist/WeaselProvider.js +5 -7
- package/dist/WeaselProvider.js.map +1 -1
- package/dist/affordances/composeAffordanceLayer.js +91 -83
- package/dist/affordances/composeAffordanceLayer.js.map +1 -1
- package/dist/affordances/cornerResize.js +3 -2
- package/dist/affordances/cornerResize.js.map +1 -1
- package/dist/affordances/hitAffordanceRegions.js +54 -100
- package/dist/affordances/hitAffordanceRegions.js.map +1 -1
- package/dist/affordances/pathAnchors.js.map +1 -1
- package/dist/affordances/rotationHandle.js +5 -4
- package/dist/affordances/rotationHandle.js.map +1 -1
- package/dist/animation/behaviors/coast.js +21 -0
- package/dist/animation/behaviors/coast.js.map +1 -0
- package/dist/animation/behaviors/coastByWrite.js +107 -0
- package/dist/animation/behaviors/coastByWrite.js.map +1 -0
- package/dist/animation/behaviors/coastOnTargets.js +94 -0
- package/dist/animation/behaviors/coastOnTargets.js.map +1 -0
- package/dist/animation/behaviors/momentum.js +48 -136
- package/dist/animation/behaviors/momentum.js.map +1 -1
- package/dist/animation/clipTargets.js +12 -0
- package/dist/animation/clipTargets.js.map +1 -0
- package/dist/animation/index.js +15 -20
- package/dist/animation/poseHelpers.js +112 -33
- package/dist/animation/poseHelpers.js.map +1 -1
- package/dist/animation/poseTarget.js +115 -0
- package/dist/animation/poseTarget.js.map +1 -0
- package/dist/animation/reflow.js +113 -83
- package/dist/animation/reflow.js.map +1 -1
- package/dist/animation/rewind.js +66 -0
- package/dist/animation/rewind.js.map +1 -0
- package/dist/animation/rig/bindRig.js +85 -53
- package/dist/animation/rig/bindRig.js.map +1 -1
- package/dist/animation/rig/rigNode.js +93 -0
- package/dist/animation/rig/rigNode.js.map +1 -0
- package/dist/animation/rig/rigSeat.js +26 -0
- package/dist/animation/rig/rigSeat.js.map +1 -0
- package/dist/animation/rig/skinBinding.js +56 -0
- package/dist/animation/rig/skinBinding.js.map +1 -0
- package/dist/animation/rig/useRig.js +31 -16
- package/dist/animation/rig/useRig.js.map +1 -1
- package/dist/animation/wrappers/animateLifecycle.js +8 -7
- package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
- package/dist/animation/wrappers/animateOnSetPose.js +31 -31
- package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
- package/dist/animation/wrappers/instantPose.js.map +1 -1
- package/dist/animation/writtenPoseTarget.js +33 -0
- package/dist/animation/writtenPoseTarget.js.map +1 -0
- package/dist/autoPoseDescriptor-DHg5KqaJ.d.ts +27 -0
- package/dist/barrel/canvas.js +31 -0
- package/dist/barrel/chrome.js +10 -10
- package/dist/barrel/input.js +16 -17
- package/dist/barrel/interactions.js +35 -39
- package/dist/barrel/paint.js +11 -18
- package/dist/barrel/paths.js +12 -19
- package/dist/barrel/renderer.js +14 -20
- package/dist/barrel/routing.js +42 -36
- package/dist/barrel/scene.js +37 -0
- package/dist/barrel/text.js +9 -18
- package/dist/barrel/viewport.js +41 -51
- package/dist/canvas/Canvas.js +281 -475
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +169 -188
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/CursorCoordsHud.js +22 -23
- package/dist/canvas/CursorCoordsHud.js.map +1 -1
- package/dist/canvas/DrawCanvas.js +39 -56
- package/dist/canvas/DrawCanvas.js.map +1 -1
- package/dist/canvas/ModalityHud.js.map +1 -1
- package/dist/canvas/NodeShape.js +28 -29
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/PickHud.js.map +1 -1
- package/dist/canvas/SceneCanvas/DevHuds.js +40 -0
- package/dist/canvas/SceneCanvas/DevHuds.js.map +1 -0
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +66 -107
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -1
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +27 -31
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +51 -54
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -1
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +3 -3
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -1
- package/dist/canvas/SceneCanvas/coordTrace.js +37 -1
- package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +40 -29
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
- package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js.map +1 -1
- package/dist/canvas/SceneCanvas/features.js +73 -43
- package/dist/canvas/SceneCanvas/features.js.map +1 -1
- package/dist/canvas/SceneCanvas/isDev.js.map +1 -1
- package/dist/canvas/SceneCanvas/poseGeometry.js +33 -37
- package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
- package/dist/canvas/SceneCanvas/props.js +15 -14
- package/dist/canvas/SceneCanvas/props.js.map +1 -1
- package/dist/canvas/SceneCanvas/toolRegistry.js +23 -0
- package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -0
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js +6 -1
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -1
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useBuiltinTools.js +21 -0
- package/dist/canvas/SceneCanvas/useBuiltinTools.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasCamera.js +38 -0
- package/dist/canvas/SceneCanvas/useCanvasCamera.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasDispatcher.js +20 -0
- package/dist/canvas/SceneCanvas/useCanvasDispatcher.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasSelection.js +16 -0
- package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasTools.js +67 -0
- package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -0
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +29 -29
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useHeldModifiers.js +20 -0
- package/dist/canvas/SceneCanvas/useHeldModifiers.js.map +1 -0
- package/dist/canvas/SceneCanvas/useNodeAtPoint.js +26 -0
- package/dist/canvas/SceneCanvas/useNodeAtPoint.js.map +1 -0
- package/dist/canvas/SceneCanvas/useNodeKinds.js +26 -0
- package/dist/canvas/SceneCanvas/useNodeKinds.js.map +1 -0
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +39 -37
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +47 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +66 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneChrome.js +59 -0
- package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneRedrawSources.js +23 -0
- package/dist/canvas/SceneCanvas/useSceneRedrawSources.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +76 -80
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSlotLayers.js +37 -0
- package/dist/canvas/SceneCanvas/useSceneSlotLayers.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js +38 -0
- package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js.map +1 -0
- package/dist/canvas/SceneCanvas/useViewLayerGate.js +20 -0
- package/dist/canvas/SceneCanvas/useViewLayerGate.js.map +1 -0
- package/dist/canvas/SceneCanvas/useViewportActions.js +9 -1
- package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -1
- package/dist/canvas/SceneCanvas/worldPointAt.js +9 -0
- package/dist/canvas/SceneCanvas/worldPointAt.js.map +1 -0
- package/dist/canvas/SceneCanvas.js +303 -707
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SceneViewCanvas.js +41 -47
- package/dist/canvas/SceneViewCanvas.js.map +1 -1
- package/dist/canvas/adapterDerivedPath.js +26 -0
- package/dist/canvas/adapterDerivedPath.js.map +1 -0
- package/dist/canvas/affordanceAt.js +11 -1
- package/dist/canvas/affordanceAt.js.map +1 -1
- package/dist/canvas/buildSceneLayer.js +81 -61
- package/dist/canvas/buildSceneLayer.js.map +1 -1
- package/dist/canvas/buildSceneTree.js.map +1 -1
- package/dist/canvas/canvasRenderer.js +40 -44
- package/dist/canvas/canvasRenderer.js.map +1 -1
- package/dist/canvas/colorOverrides.js.map +1 -1
- package/dist/canvas/defaultDrawOne.js +12 -12
- package/dist/canvas/defaultDrawOne.js.map +1 -1
- package/dist/canvas/deps/areaSelect.js +4 -4
- package/dist/canvas/deps/areaSelect.js.map +1 -1
- package/dist/canvas/deps/debug.js.map +1 -1
- package/dist/canvas/deps/editAnchors.js +49 -68
- package/dist/canvas/deps/editAnchors.js.map +1 -1
- package/dist/canvas/deps/geometryProjection.js.map +1 -1
- package/dist/canvas/deps/hitTestArea.js +31 -26
- package/dist/canvas/deps/hitTestArea.js.map +1 -1
- package/dist/canvas/deps/insert.js +65 -54
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/lassoSelect.js +5 -5
- package/dist/canvas/deps/lassoSelect.js.map +1 -1
- package/dist/canvas/deps/poseDescriptor.js +1 -1
- package/dist/canvas/deps/poseDescriptor.js.map +1 -1
- package/dist/canvas/deps/resizePolicy.js.map +1 -1
- package/dist/canvas/deps/slice.js +44 -45
- package/dist/canvas/deps/slice.js.map +1 -1
- package/dist/canvas/deps/textEdit.js +8 -8
- package/dist/canvas/deps/textEdit.js.map +1 -1
- package/dist/canvas/deps/view.js.map +1 -1
- package/dist/canvas/derivedPath.js +43 -41
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/drawEnvelope.js +8 -4
- package/dist/canvas/drawEnvelope.js.map +1 -1
- package/dist/canvas/getNodeAtPoint.js +2 -6
- package/dist/canvas/getNodeAtPoint.js.map +1 -1
- package/dist/canvas/hud.module.js.map +1 -1
- package/dist/canvas/insertPreviewExtent.js.map +1 -1
- package/dist/canvas/layerOrder.js.map +1 -1
- package/dist/canvas/layerSlots.js +6 -1
- package/dist/canvas/layerSlots.js.map +1 -1
- package/dist/canvas/nodeShapes/derivedPainter.js +12 -12
- package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/imagePainter.js +10 -10
- package/dist/canvas/nodeShapes/imagePainter.js.map +1 -1
- package/dist/canvas/nodeShapes/memo.js.map +1 -1
- package/dist/canvas/nodeShapes/nodePaint.js +34 -23
- package/dist/canvas/nodeShapes/nodePaint.js.map +1 -1
- package/dist/canvas/nodeShapes/pathPainter.js +23 -22
- package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/poseBox.js +6 -6
- package/dist/canvas/nodeShapes/poseBox.js.map +1 -1
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +8 -8
- package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/shapePainter.js +16 -16
- package/dist/canvas/nodeShapes/shapePainter.js.map +1 -1
- package/dist/canvas/nodeShapes/textPainter.js +1 -1
- package/dist/canvas/nodeShapes/textPainter.js.map +1 -1
- package/dist/canvas/overlayRoleStrokes.js.map +1 -1
- package/dist/canvas/paintCull.js +6 -8
- package/dist/canvas/paintCull.js.map +1 -1
- package/dist/{features/cursor → canvas}/paintedCursorLayer.js +2 -2
- package/dist/canvas/paintedCursorLayer.js.map +1 -0
- package/dist/canvas/pickWalk.js +52 -50
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/planeClips.js +18 -19
- package/dist/canvas/planeClips.js.map +1 -1
- package/dist/canvas/poseCascade.js +41 -0
- package/dist/canvas/poseCascade.js.map +1 -0
- package/dist/canvas/poseRotation.js +1 -3
- package/dist/canvas/poseRotation.js.map +1 -1
- package/dist/canvas/rasterReadback.js +22 -0
- package/dist/canvas/rasterReadback.js.map +1 -0
- package/dist/canvas/renderDebugSnapshot.js +12 -12
- package/dist/canvas/renderDebugSnapshot.js.map +1 -1
- package/dist/canvas/renderNeeds.js +3 -3
- package/dist/canvas/renderNeeds.js.map +1 -1
- package/dist/canvas/renderSceneToPixels.js +64 -83
- package/dist/canvas/renderSceneToPixels.js.map +1 -1
- package/dist/canvas/sceneAdapter.js +68 -132
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneClipboard.js +1 -1
- package/dist/canvas/sceneClipboard.js.map +1 -1
- package/dist/canvas/sceneLayerPaint.js +4 -4
- package/dist/canvas/sceneLayerPaint.js.map +1 -1
- package/dist/canvas/sceneSlotWiring.js +4 -4
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +36 -35
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/slopsDebugLayer.js +4 -4
- package/dist/canvas/slopsDebugLayer.js.map +1 -1
- package/dist/canvas/surface.module.js +6 -0
- package/dist/canvas/surface.module.js.map +1 -0
- package/dist/canvas/surfaceBox.js +16 -0
- package/dist/canvas/surfaceBox.js.map +1 -0
- package/dist/canvas/useCanvasRenderer.js +23 -11
- package/dist/canvas/useCanvasRenderer.js.map +1 -1
- package/dist/canvas/useCanvasSurface.js +31 -0
- package/dist/canvas/useCanvasSurface.js.map +1 -0
- package/dist/canvas/useCanvasView.js +46 -37
- package/dist/canvas/useCanvasView.js.map +1 -1
- package/dist/canvas/useFrameLoop.js +11 -12
- package/dist/canvas/useFrameLoop.js.map +1 -1
- package/dist/canvas/useHostAnchor.js +35 -33
- package/dist/canvas/useHostAnchor.js.map +1 -1
- package/dist/canvas/useLateContentRedraw.js +8 -8
- package/dist/canvas/useLateContentRedraw.js.map +1 -1
- package/dist/canvas/useSceneLayerList.js +4 -14
- package/dist/canvas/useSceneLayerList.js.map +1 -1
- package/dist/canvas/useSurfaceInput.js +42 -0
- package/dist/canvas/useSurfaceInput.js.map +1 -0
- package/dist/canvas/useToolCursor.js +29 -0
- package/dist/canvas/useToolCursor.js.map +1 -0
- package/dist/canvas/useViewHelpers.js +46 -85
- package/dist/canvas/useViewHelpers.js.map +1 -1
- package/dist/canvas/viewInputs.js.map +1 -1
- package/dist/canvas/viewRegistry.js +25 -27
- package/dist/canvas/viewRegistry.js.map +1 -1
- package/dist/canvas/watchElementMove.js +43 -0
- package/dist/canvas/watchElementMove.js.map +1 -0
- package/dist/canvas/wrapNodeOutput.js.map +1 -1
- package/dist/clipboard.d.ts +7 -14
- package/dist/{types-B4iJRHC3.d.ts → clone-2a5hVbBd.d.ts} +122 -77
- package/dist/clone.d.ts +4 -8
- package/dist/clone.js +0 -2
- package/dist/core/device/targets.js.map +1 -1
- package/dist/core/device/useDeviceProfile.js +13 -13
- package/dist/core/device/useDeviceProfile.js.map +1 -1
- package/dist/{interactions/actions/resize → core/geometry}/autoPoseDescriptor.js +8 -7
- package/dist/core/geometry/autoPoseDescriptor.js.map +1 -0
- package/dist/core/geometry/pathPoseDescriptor.js +88 -0
- package/dist/core/geometry/pathPoseDescriptor.js.map +1 -0
- package/dist/core/geometry/poseDescriptor.js +61 -14
- package/dist/core/geometry/poseDescriptor.js.map +1 -1
- package/dist/core/geometry/regionHit.js +35 -37
- package/dist/core/geometry/regionHit.js.map +1 -1
- package/dist/core/geometry/targetFrame.js +94 -0
- package/dist/core/geometry/targetFrame.js.map +1 -0
- package/dist/core/geometry/unionBounds.js +4 -5
- package/dist/core/geometry/unionBounds.js.map +1 -1
- package/dist/core/layers/backgroundFill.js +31 -0
- package/dist/core/layers/backgroundFill.js.map +1 -0
- package/dist/{features/groups → core/layers}/children.js +1 -1
- package/dist/core/layers/children.js.map +1 -0
- package/dist/{features/focus → core/layers}/gateLayer.js +2 -2
- package/dist/core/layers/gateLayer.js.map +1 -0
- package/dist/core/layers/layerGroup.js +40 -0
- package/dist/core/layers/layerGroup.js.map +1 -0
- package/dist/core/layers/render.js +50 -76
- package/dist/core/layers/render.js.map +1 -1
- package/dist/core/ops/createHistory.js +9 -9
- package/dist/core/ops/createHistory.js.map +1 -1
- package/dist/core/ops/delete.js.map +1 -1
- package/dist/core/paint/meshKind.js +16 -0
- package/dist/core/paint/meshKind.js.map +1 -0
- package/dist/{features/meshPaint/lazyKind.js → core/paint/meshKindLazy.js} +103 -92
- package/dist/core/paint/meshKindLazy.js.map +1 -0
- package/dist/core/paint/paintKindEntry.js +8 -0
- package/dist/core/paint/paintKindEntry.js.map +1 -0
- package/dist/core/paint/paintKinds.js +144 -0
- package/dist/core/paint/paintKinds.js.map +1 -0
- package/dist/core/paint/registerMesh.js +7 -0
- package/dist/core/paint/registerMesh.js.map +1 -0
- package/dist/core/scene/NodeProperties.js.map +1 -1
- package/dist/core/scene/NodeRouting.js.map +1 -1
- package/dist/core/scene/arrivalWindow.js +65 -64
- package/dist/core/scene/arrivalWindow.js.map +1 -1
- package/dist/core/scene/boundOps.js +40 -0
- package/dist/core/scene/boundOps.js.map +1 -0
- package/dist/core/scene/composeFrame.js +9 -6
- package/dist/core/scene/composeFrame.js.map +1 -1
- package/dist/{features/groups → core/scene}/composePose.js +18 -18
- package/dist/core/scene/composePose.js.map +1 -0
- package/dist/core/scene/depMemo.js +31 -6
- package/dist/core/scene/depMemo.js.map +1 -1
- package/dist/core/scene/derivedPath.js +19 -20
- package/dist/core/scene/derivedPath.js.map +1 -1
- package/dist/core/scene/editMode.js +26 -0
- package/dist/core/scene/editMode.js.map +1 -0
- package/dist/core/scene/effectivePose.js +38 -39
- package/dist/core/scene/effectivePose.js.map +1 -1
- package/dist/core/scene/fieldEdits.js +98 -0
- package/dist/core/scene/fieldEdits.js.map +1 -0
- package/dist/core/scene/historyFacade.js +116 -70
- package/dist/core/scene/historyFacade.js.map +1 -1
- package/dist/core/scene/historyForm.js +6 -0
- package/dist/core/scene/historyForm.js.map +1 -0
- package/dist/core/scene/kitOps.js +83 -71
- package/dist/core/scene/kitOps.js.map +1 -1
- package/dist/core/scene/kitRegistry.js.map +1 -1
- package/dist/core/scene/layerStack.js +105 -12
- package/dist/core/scene/layerStack.js.map +1 -1
- package/dist/core/scene/layoutPass.js +58 -59
- package/dist/core/scene/layoutPass.js.map +1 -1
- package/dist/{features/groups → core/scene}/nestedHit.js +3 -3
- package/dist/core/scene/nestedHit.js.map +1 -0
- package/dist/core/scene/nodeFnFields.js +9 -9
- package/dist/core/scene/nodeFnFields.js.map +1 -1
- package/dist/core/scene/nodeMemo.js.map +1 -1
- package/dist/core/scene/nodeStore.js +72 -71
- package/dist/core/scene/nodeStore.js.map +1 -1
- package/dist/core/scene/notifier.js +37 -0
- package/dist/core/scene/notifier.js.map +1 -0
- package/dist/core/scene/opTable.js +50 -0
- package/dist/core/scene/opTable.js.map +1 -0
- package/dist/core/scene/outerOps.js +66 -0
- package/dist/core/scene/outerOps.js.map +1 -0
- package/dist/core/scene/poseHold.js +39 -0
- package/dist/core/scene/poseHold.js.map +1 -0
- package/dist/core/scene/poseOverrides.js +44 -36
- package/dist/core/scene/poseOverrides.js.map +1 -1
- package/dist/core/scene/poseSnapshot.js.map +1 -1
- package/dist/core/scene/reconcileSpecs.js +3 -2
- package/dist/core/scene/reconcileSpecs.js.map +1 -1
- package/dist/core/scene/recorder.js +86 -0
- package/dist/core/scene/recorder.js.map +1 -0
- package/dist/core/scene/renderOrder.js.map +1 -1
- package/dist/core/scene/scene.js +81 -690
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/sceneEdits.js +58 -0
- package/dist/core/scene/sceneEdits.js.map +1 -0
- package/dist/core/scene/sceneMutators.js +49 -0
- package/dist/core/scene/sceneMutators.js.map +1 -0
- package/dist/core/scene/scenePoseAdapter.js +16 -0
- package/dist/core/scene/scenePoseAdapter.js.map +1 -0
- package/dist/core/scene/sceneRecording.js +90 -0
- package/dist/core/scene/sceneRecording.js.map +1 -0
- package/dist/core/scene/sceneSelection.js +28 -0
- package/dist/core/scene/sceneSelection.js.map +1 -0
- package/dist/core/scene/sceneState.js +49 -0
- package/dist/core/scene/sceneState.js.map +1 -0
- package/dist/core/scene/serialization.js +8 -5
- package/dist/core/scene/serialization.js.map +1 -1
- package/dist/core/scene/staleReplay.js +51 -0
- package/dist/core/scene/staleReplay.js.map +1 -0
- package/dist/core/scene/statedFields.js +9 -0
- package/dist/core/scene/statedFields.js.map +1 -0
- package/dist/core/scene/treeEdits.js +127 -0
- package/dist/core/scene/treeEdits.js.map +1 -0
- package/dist/core/scene/treeReads.js +26 -0
- package/dist/core/scene/treeReads.js.map +1 -0
- package/dist/core/scene/types.js.map +1 -1
- package/dist/{features/groups → core/scene}/unionOfChildren.js +3 -3
- package/dist/core/scene/unionOfChildren.js.map +1 -0
- package/dist/core/scene/unitScopes.js +13 -0
- package/dist/core/scene/unitScopes.js.map +1 -0
- package/dist/core/scene/useScene.js.map +1 -1
- package/dist/core/selection/readOnlySelection.js +32 -0
- package/dist/core/selection/readOnlySelection.js.map +1 -0
- package/dist/core/selection/usePublishSceneSelection.js +26 -0
- package/dist/core/selection/usePublishSceneSelection.js.map +1 -0
- package/dist/core/selection/useSelection.js +34 -25
- package/dist/core/selection/useSelection.js.map +1 -1
- package/dist/core/shapeKinds.js.map +1 -1
- package/dist/core/stylus/stylus.js.map +1 -1
- package/dist/core/stylus/usePointerStylus.js.map +1 -1
- package/dist/core/usePaintKinds.js +1 -1
- package/dist/core/usePaintKinds.js.map +1 -1
- package/dist/core/viewport/clientToWorld.js.map +1 -1
- package/dist/core/viewport/fitViewToBounds.js.map +1 -1
- package/dist/core/viewport/parallax.js.map +1 -1
- package/dist/core/viewport/screenSlop.js +11 -11
- package/dist/core/viewport/screenSlop.js.map +1 -1
- package/dist/core/viewport/useCanvasSize.js.map +1 -1
- package/dist/core/viewport/useDecayLoop.js +8 -8
- package/dist/core/viewport/useDecayLoop.js.map +1 -1
- package/dist/core/viewport/useNodeOverlayFrame.js +84 -0
- package/dist/core/viewport/useNodeOverlayFrame.js.map +1 -0
- package/dist/core/viewport/useViewAnimation.js +102 -43
- package/dist/core/viewport/useViewAnimation.js.map +1 -1
- package/dist/core/viewport/view.js +7 -7
- package/dist/core/viewport/view.js.map +1 -1
- package/dist/core/viewport/wheelHandler.js.map +1 -1
- package/dist/{cornerHandles-CtCb8a3G.d.ts → cornerHandles-BEshc4z3.d.ts} +11 -24
- package/dist/debug/createDebugOverlayLayer.js +100 -100
- package/dist/debug/createDebugOverlayLayer.js.map +1 -1
- package/dist/debug/createDebugSink.js.map +1 -1
- package/dist/debug/frameStats.js.map +1 -1
- package/dist/debug/useDebugSink.js +52 -0
- package/dist/debug/useDebugSink.js.map +1 -0
- package/dist/features/chrome-caps/buildChromeCtx.js.map +1 -1
- package/dist/features/chrome-caps/conditions.js.map +1 -1
- package/dist/features/chrome-caps/defaults.js.map +1 -1
- package/dist/features/chrome-caps/resolve.js.map +1 -1
- package/dist/features/chrome-caps/useChromeCaps.js +54 -0
- package/dist/features/chrome-caps/useChromeCaps.js.map +1 -0
- package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
- package/dist/features/ingestion/contentHandlers.js +25 -19
- package/dist/features/ingestion/contentHandlers.js.map +1 -1
- package/dist/features/ingestion/imageHandler.js +21 -24
- package/dist/features/ingestion/imageHandler.js.map +1 -1
- package/dist/features/ingestion/openFilePicker.js.map +1 -1
- package/dist/features/ingestion/placement.js +16 -0
- package/dist/features/ingestion/placement.js.map +1 -0
- package/dist/features/ingestion/svgHandler.js +5 -0
- package/dist/features/ingestion/svgHandler.js.map +1 -1
- package/dist/features/ingestion/textHandler.js +28 -0
- package/dist/features/ingestion/textHandler.js.map +1 -0
- package/dist/features/ingestion/useCanvasIngestion.js +48 -0
- package/dist/features/ingestion/useCanvasIngestion.js.map +1 -0
- package/dist/features/ingestion/weaselJsonHandler.js +5 -0
- package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
- package/dist/features/longPress/longPressFeedback.js.map +1 -1
- package/dist/features/modes/modeLayers.js +7 -7
- package/dist/features/modes/modeLayers.js.map +1 -1
- package/dist/features/paths/editablePath.js +47 -0
- package/dist/features/paths/editablePath.js.map +1 -0
- package/dist/features/paths/index.js +9 -16
- package/dist/features/paths/pathEditState.js +41 -0
- package/dist/features/paths/pathEditState.js.map +1 -0
- package/dist/features/paths/pathEditingOverlayLayer.js +36 -38
- package/dist/features/paths/pathEditingOverlayLayer.js.map +1 -1
- package/dist/features/paths/pathLayer.js +3 -2
- package/dist/features/paths/pathLayer.js.map +1 -1
- package/dist/features/paths/penPreviewLayer.js +86 -88
- package/dist/features/paths/penPreviewLayer.js.map +1 -1
- package/dist/features/paths/usePathEdit.js +34 -0
- package/dist/features/paths/usePathEdit.js.map +1 -0
- package/dist/features/poseRun/usePoseRun.js +42 -55
- package/dist/features/poseRun/usePoseRun.js.map +1 -1
- package/dist/features/selection/overlay.js +170 -178
- package/dist/features/selection/overlay.js.map +1 -1
- package/dist/features/text/index.js +6 -0
- package/dist/features/text/textLayer.js +1 -1
- package/dist/features/text/textLayer.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +95 -82
- package/dist/features/text/useSceneTextEdit.js.map +1 -1
- package/dist/features/viewports/viewportLayer.js +25 -36
- package/dist/features/viewports/viewportLayer.js.map +1 -1
- package/dist/index.d.ts +4507 -8459
- package/dist/index.js +275 -320
- package/dist/input/keyState.js +14 -14
- package/dist/interactions/actions/actionShortcuts.js.map +1 -1
- package/dist/interactions/actions/{defaults/align.js → align/action.js} +15 -16
- package/dist/interactions/actions/align/action.js.map +1 -0
- package/dist/interactions/actions/align/align.js +23 -23
- package/dist/interactions/actions/align/align.js.map +1 -1
- package/dist/interactions/actions/booleans/action.js +65 -0
- package/dist/interactions/actions/booleans/action.js.map +1 -0
- package/dist/interactions/actions/booleans/booleans.js +69 -78
- package/dist/interactions/actions/booleans/booleans.js.map +1 -1
- package/dist/interactions/actions/booleans/operands.js +40 -0
- package/dist/interactions/actions/booleans/operands.js.map +1 -0
- package/dist/interactions/actions/booleans/pieces.js +45 -0
- package/dist/interactions/actions/booleans/pieces.js.map +1 -0
- package/dist/interactions/actions/booleans/placement.js +24 -0
- package/dist/interactions/actions/booleans/placement.js.map +1 -0
- package/dist/interactions/actions/booleans/useBooleans.js +11 -9
- package/dist/interactions/actions/booleans/useBooleans.js.map +1 -1
- package/dist/interactions/actions/booleans/useBooleansAdapter.js.map +1 -1
- package/dist/interactions/actions/{defaults/clipboard.js → clipboard/action.js} +19 -19
- package/dist/interactions/actions/clipboard/action.js.map +1 -0
- package/dist/interactions/actions/clipboard/clipboardOps.js +15 -15
- package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
- package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
- package/dist/interactions/actions/clone/action.js +98 -0
- package/dist/interactions/actions/clone/action.js.map +1 -0
- package/dist/interactions/actions/clone/behaviors.js +52 -0
- package/dist/interactions/actions/clone/behaviors.js.map +1 -0
- package/dist/interactions/actions/defaultCommitAdapter.js +10 -37
- package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +41 -43
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
- package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -1
- package/dist/interactions/actions/defaults/clearSelection.js.map +1 -1
- package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -1
- package/dist/interactions/actions/defaults/delete.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +19 -19
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
- package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +35 -40
- package/dist/interactions/actions/defaults/group.js.map +1 -1
- package/dist/interactions/actions/defaults/icons/booleanIcons.js +24 -1
- package/dist/interactions/actions/defaults/icons/booleanIcons.js.map +1 -1
- package/dist/interactions/actions/defaults/icons/outlineIcons.js +39 -1
- package/dist/interactions/actions/defaults/icons/outlineIcons.js.map +1 -1
- package/dist/interactions/actions/defaults/ingest.js +19 -15
- package/dist/interactions/actions/defaults/ingest.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +14 -15
- package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
- package/dist/interactions/actions/defaults/nudge.js +30 -31
- package/dist/interactions/actions/defaults/nudge.js.map +1 -1
- package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -1
- package/dist/interactions/actions/defaults/requiresSelection.js.map +1 -1
- package/dist/interactions/actions/defaults/setFill.js +9 -3
- package/dist/interactions/actions/defaults/setFill.js.map +1 -1
- package/dist/interactions/actions/defaults/setFillOpacity.js +4 -1
- package/dist/interactions/actions/defaults/setFillOpacity.js.map +1 -1
- package/dist/interactions/actions/defaults/setStroke.js.map +1 -1
- package/dist/interactions/actions/defaults/sliceOps.js +20 -22
- package/dist/interactions/actions/defaults/sliceOps.js.map +1 -1
- package/dist/interactions/actions/defaults/toolActivate.js.map +1 -1
- package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportDragPan.js +1 -1
- package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
- package/dist/interactions/actions/{defaults/distribute.js → distribute/action.js} +18 -19
- package/dist/interactions/actions/distribute/action.js.map +1 -0
- package/dist/interactions/actions/distribute/distribute.js +11 -11
- package/dist/interactions/actions/distribute/distribute.js.map +1 -1
- package/dist/interactions/actions/{defaults/editAnchors.js → edit-anchors/action.js} +19 -21
- package/dist/interactions/actions/edit-anchors/action.js.map +1 -0
- package/dist/interactions/actions/edit-anchors/geometry.js +2 -4
- package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
- package/dist/interactions/actions/flip/action.js +124 -0
- package/dist/interactions/actions/flip/action.js.map +1 -0
- package/dist/interactions/actions/flip/helpers.js +1 -1
- package/dist/interactions/actions/flip/helpers.js.map +1 -1
- package/dist/interactions/actions/gestureFrames.js +18 -0
- package/dist/interactions/actions/gestureFrames.js.map +1 -0
- package/dist/interactions/actions/gestureLifecycle.js +47 -20
- package/dist/interactions/actions/gestureLifecycle.js.map +1 -1
- package/dist/interactions/actions/insert/action.js +72 -0
- package/dist/interactions/actions/insert/action.js.map +1 -0
- package/dist/interactions/actions/insert/commit.js +28 -0
- package/dist/interactions/actions/insert/commit.js.map +1 -0
- package/dist/interactions/actions/insert/extras.js +65 -0
- package/dist/interactions/actions/insert/extras.js.map +1 -0
- package/dist/interactions/actions/insert/frame.js +48 -0
- package/dist/interactions/actions/insert/frame.js.map +1 -0
- package/dist/interactions/actions/insert/geometry.js +35 -0
- package/dist/interactions/actions/insert/geometry.js.map +1 -0
- package/dist/interactions/actions/insert/rotateAction.js +21 -0
- package/dist/interactions/actions/insert/rotateAction.js.map +1 -0
- package/dist/interactions/actions/insert/session.js +59 -0
- package/dist/interactions/actions/insert/session.js.map +1 -0
- package/dist/interactions/actions/insert/shape.js +34 -0
- package/dist/interactions/actions/insert/shape.js.map +1 -0
- package/dist/interactions/actions/lasso-select/action.js +143 -0
- package/dist/interactions/actions/lasso-select/action.js.map +1 -0
- package/dist/interactions/actions/move/action.js +87 -0
- package/dist/interactions/actions/move/action.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/layoutDrop.js +51 -0
- package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/reparentOnDrop.js +15 -0
- package/dist/interactions/actions/move/behaviors/reparentOnDrop.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +24 -23
- package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
- package/dist/interactions/actions/move/capture.js +99 -0
- package/dist/interactions/actions/move/capture.js.map +1 -0
- package/dist/interactions/actions/move/commit/index.js +41 -0
- package/dist/interactions/actions/move/commit/index.js.map +1 -0
- package/dist/interactions/actions/move/commit/layoutDrop.js +44 -0
- package/dist/interactions/actions/move/commit/layoutDrop.js.map +1 -0
- package/dist/interactions/actions/move/commit/layoutRelease.js +100 -0
- package/dist/interactions/actions/move/commit/layoutRelease.js.map +1 -0
- package/dist/interactions/actions/move/commit/rebase.js +18 -0
- package/dist/interactions/actions/move/commit/rebase.js.map +1 -0
- package/dist/interactions/actions/move/commit/reparent.js +65 -0
- package/dist/interactions/actions/move/commit/reparent.js.map +1 -0
- package/dist/interactions/actions/move/delta.js +51 -0
- package/dist/interactions/actions/move/delta.js.map +1 -0
- package/dist/interactions/actions/move/frame.js +59 -0
- package/dist/interactions/actions/move/frame.js.map +1 -0
- package/dist/interactions/actions/move/gestureAdapter.js +15 -40
- package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
- package/dist/interactions/actions/move/landedDescendants.js +8 -8
- package/dist/interactions/actions/move/layout/container.js +94 -0
- package/dist/interactions/actions/move/layout/container.js.map +1 -0
- package/dist/interactions/actions/move/layout/dragged.js +58 -0
- package/dist/interactions/actions/move/layout/dragged.js.map +1 -0
- package/dist/interactions/actions/move/layout/dropPass.js +122 -0
- package/dist/interactions/actions/move/layout/dropPass.js.map +1 -0
- package/dist/interactions/actions/move/layout/exits.js +38 -0
- package/dist/interactions/actions/move/layout/exits.js.map +1 -0
- package/dist/interactions/actions/move/layout/glide.js +48 -0
- package/dist/interactions/actions/move/layout/glide.js.map +1 -0
- package/dist/interactions/actions/move/session.js +63 -0
- package/dist/interactions/actions/move/session.js.map +1 -0
- package/dist/interactions/actions/move/translate.js +61 -0
- package/dist/interactions/actions/move/translate.js.map +1 -0
- package/dist/interactions/actions/outlines/createOutlines.js +17 -64
- package/dist/interactions/actions/outlines/createOutlines.js.map +1 -1
- package/dist/interactions/actions/outlines/createOutlinesAction.js +51 -0
- package/dist/interactions/actions/outlines/createOutlinesAction.js.map +1 -0
- package/dist/interactions/actions/outlines/outlineStroke.js +72 -0
- package/dist/interactions/actions/outlines/outlineStroke.js.map +1 -0
- package/dist/interactions/actions/outlines/outlineStrokeAction.js +37 -0
- package/dist/interactions/actions/outlines/outlineStrokeAction.js.map +1 -0
- package/dist/interactions/actions/outlines/replaceWithPaths.js +54 -0
- package/dist/interactions/actions/outlines/replaceWithPaths.js.map +1 -0
- package/dist/interactions/actions/outlines/strokeRegion.js +27 -0
- package/dist/interactions/actions/outlines/strokeRegion.js.map +1 -0
- package/dist/interactions/actions/planeInput.js.map +1 -1
- package/dist/interactions/actions/pointerState.js +12 -0
- package/dist/interactions/actions/pointerState.js.map +1 -0
- package/dist/interactions/actions/poseDescriptorDep.js +1 -1
- package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
- package/dist/interactions/actions/poseFrame.js +26 -26
- package/dist/interactions/actions/poseFrame.js.map +1 -1
- package/dist/interactions/actions/resize/action.js +55 -0
- package/dist/interactions/actions/resize/action.js.map +1 -0
- package/dist/interactions/actions/resize/behaviors/lockAspect.js.map +1 -1
- package/dist/interactions/actions/resize/boxFrame.js +16 -0
- package/dist/interactions/actions/resize/boxFrame.js.map +1 -0
- package/dist/interactions/actions/resize/capture.js +85 -0
- package/dist/interactions/actions/resize/capture.js.map +1 -0
- package/dist/interactions/actions/resize/commit.js +69 -0
- package/dist/interactions/actions/resize/commit.js.map +1 -0
- package/dist/interactions/actions/resize/frame.js +74 -0
- package/dist/interactions/actions/resize/frame.js.map +1 -0
- package/dist/interactions/actions/resize/pointSnap.js +111 -0
- package/dist/interactions/actions/resize/pointSnap.js.map +1 -0
- package/dist/interactions/actions/resize/ruleBounds.js +9 -0
- package/dist/interactions/actions/resize/ruleBounds.js.map +1 -0
- package/dist/interactions/actions/resize/session.js +49 -0
- package/dist/interactions/actions/resize/session.js.map +1 -0
- package/dist/interactions/actions/resolveOverlays.js.map +1 -1
- package/dist/interactions/actions/resolvePreviews.js.map +1 -1
- package/dist/interactions/actions/rotate/action.js +56 -0
- package/dist/interactions/actions/rotate/action.js.map +1 -0
- package/dist/interactions/actions/rotate/behaviors/index.js +7 -0
- package/dist/interactions/actions/rotate/behaviors/index.js.map +1 -0
- package/dist/interactions/actions/rotate/behaviors/snapRotation.js +12 -0
- package/dist/interactions/actions/rotate/behaviors/snapRotation.js.map +1 -0
- package/dist/interactions/actions/rotate/commit.js +40 -0
- package/dist/interactions/actions/rotate/commit.js.map +1 -0
- package/dist/interactions/actions/rotate/frame.js +65 -0
- package/dist/interactions/actions/rotate/frame.js.map +1 -0
- package/dist/interactions/actions/rotate/handle.js +12 -12
- package/dist/interactions/actions/rotate/handle.js.map +1 -1
- package/dist/interactions/actions/rotate/session.js +92 -0
- package/dist/interactions/actions/rotate/session.js.map +1 -0
- package/dist/interactions/actions/spatialReference.js.map +1 -1
- package/dist/interactions/actions/useStandardActions.js +77 -72
- package/dist/interactions/actions/useStandardActions.js.map +1 -1
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js +61 -42
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
- package/dist/interactions/gestures/shared/originProjection.js +1 -1
- package/dist/interactions/gestures/shared/originProjection.js.map +1 -1
- package/dist/interactions/gestures/shared/screenTolerance.js +8 -2
- package/dist/interactions/gestures/shared/screenTolerance.js.map +1 -1
- package/dist/interactions/gestures/shared/snap.js.map +1 -1
- package/dist/layout/arrivals.js +20 -23
- package/dist/layout/arrivals.js.map +1 -1
- package/dist/math-CYUjoyyU.d.ts +33 -0
- package/dist/math.d.ts +5 -2
- package/dist/math.js +6 -6
- package/dist/mesh.d.ts +4 -268
- package/dist/mesh.js +3 -7
- package/dist/move.d.ts +6 -4
- package/dist/{originProjection-gHnOup4e.d.ts → originProjection-PPT88jZv.d.ts} +1 -1
- package/dist/patterns-builtin.d.ts +1 -118
- package/dist/patterns-builtin.js +2 -3
- package/dist/poseDescriptor-Bqk-11Rl.d.ts +73 -0
- package/dist/renderer.d.ts +1 -92
- package/dist/renderer.js +2 -19
- package/dist/resize.d.ts +11 -22
- package/dist/resize.js +1 -1
- package/dist/style.css +1 -1
- package/dist/test-hook/install.js.map +1 -1
- package/dist/test-hook/useTestHook.js +22 -0
- package/dist/test-hook/useTestHook.js.map +1 -0
- package/dist/test-seams-D0pyV3pR.d.ts +149 -0
- package/dist/test-seams.d.ts +4 -4
- package/dist/test-seams.js +2 -2
- package/dist/tools/builtin/bone/boneActions.js +130 -0
- package/dist/tools/builtin/bone/boneActions.js.map +1 -0
- package/dist/tools/builtin/bone/boneOverlay.js +58 -0
- package/dist/tools/builtin/bone/boneOverlay.js.map +1 -0
- package/dist/tools/builtin/bone/placedRig.js +24 -0
- package/dist/tools/builtin/bone/placedRig.js.map +1 -0
- package/dist/tools/builtin/bone/rigEditState.js +21 -0
- package/dist/tools/builtin/bone/rigEditState.js.map +1 -0
- package/dist/tools/builtin/bone/useBoneTool.js +98 -0
- package/dist/tools/builtin/bone/useBoneTool.js.map +1 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
- package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
- package/dist/tools/builtin/image/useImageTool.js.map +1 -1
- package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
- package/dist/tools/builtin/line/useLineTool.js.map +1 -1
- package/dist/tools/builtin/pen/usePenTool.js +161 -163
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
- package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
- package/dist/tools/builtin/pickTopMostHit.js.map +1 -1
- package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
- package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
- package/dist/tools/builtin/select/adapterPointQuery.js +36 -0
- package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -0
- package/dist/tools/builtin/select/selectionContributions.js +4 -4
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +43 -71
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/shared/pointerFollower.js.map +1 -1
- package/dist/tools/builtin/slice/useSliceTool.js +67 -72
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
- package/dist/tools/builtin/star/useStarTool.js.map +1 -1
- package/dist/tools/builtin/text/useTextTool.js +8 -0
- package/dist/tools/builtin/text/useTextTool.js.map +1 -1
- package/dist/tools/builtin/weight/useWeightTool.js +77 -0
- package/dist/tools/builtin/weight/useWeightTool.js.map +1 -0
- package/dist/tools/builtin/weight/weightActions.js +112 -0
- package/dist/tools/builtin/weight/weightActions.js.map +1 -0
- package/dist/tools/builtin/weight/weightOverlay.js +61 -0
- package/dist/tools/builtin/weight/weightOverlay.js.map +1 -0
- package/dist/tools/overlayBinding.js.map +1 -1
- package/dist/tools/useKeybindings.js +20 -14
- package/dist/tools/useKeybindings.js.map +1 -1
- package/dist/{types-k-5Oqh-U.d.ts → types-CIKDwlsP.d.ts} +84 -164
- package/dist/util/paint.js +1 -1
- package/dist/util/paint.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +26 -21
- package/dist/animation/colorHelpers.js +0 -135
- package/dist/animation/colorHelpers.js.map +0 -1
- package/dist/animation/colorRegistry.js +0 -37
- package/dist/animation/colorRegistry.js.map +0 -1
- package/dist/animation/engine/axes.js +0 -36
- package/dist/animation/engine/axes.js.map +0 -1
- package/dist/animation/engine/codec.js +0 -170
- package/dist/animation/engine/codec.js.map +0 -1
- package/dist/animation/engine/integrator.js +0 -12
- package/dist/animation/engine/integrator.js.map +0 -1
- package/dist/animation/loop.js +0 -60
- package/dist/animation/loop.js.map +0 -1
- package/dist/animation/observe.js +0 -23
- package/dist/animation/observe.js.map +0 -1
- package/dist/animation/rig/blendPoses.js +0 -43
- package/dist/animation/rig/blendPoses.js.map +0 -1
- package/dist/animation/rig/mirrorPose.js +0 -19
- package/dist/animation/rig/mirrorPose.js.map +0 -1
- package/dist/animation/rig/resolveSkeleton.js +0 -33
- package/dist/animation/rig/resolveSkeleton.js.map +0 -1
- package/dist/animation/rig/solveIk.js +0 -103
- package/dist/animation/rig/solveIk.js.map +0 -1
- package/dist/animation/rig/types.js +0 -12
- package/dist/animation/rig/types.js.map +0 -1
- package/dist/animation/slew.js +0 -27
- package/dist/animation/slew.js.map +0 -1
- package/dist/animation/stagger.js +0 -146
- package/dist/animation/stagger.js.map +0 -1
- package/dist/animation/timeline/booking.js +0 -114
- package/dist/animation/timeline/booking.js.map +0 -1
- package/dist/animation/timeline/createTimeline.js +0 -125
- package/dist/animation/timeline/createTimeline.js.map +0 -1
- package/dist/animation/timeline/sampleTrack.js +0 -79
- package/dist/animation/timeline/sampleTrack.js.map +0 -1
- package/dist/animation/useAnimator.js +0 -388
- package/dist/animation/useAnimator.js.map +0 -1
- package/dist/autoPoseDescriptor-Ct7yqivU.d.ts +0 -108
- package/dist/builtins-DPcdghtB.d.ts +0 -1223
- package/dist/canvas/MinimapCanvas.js +0 -140
- package/dist/canvas/MinimapCanvas.js.map +0 -1
- package/dist/canvas/deps/poseComposition.js +0 -11
- package/dist/canvas/deps/poseComposition.js.map +0 -1
- package/dist/canvas/minimapMath.js +0 -82
- package/dist/canvas/minimapMath.js.map +0 -1
- package/dist/canvas/toolPreview.js +0 -39
- package/dist/canvas/toolPreview.js.map +0 -1
- package/dist/core/adapters/arrayAdapter.js +0 -94
- package/dist/core/adapters/arrayAdapter.js.map +0 -1
- package/dist/core/adapters/useArrayAdapter.js +0 -13
- package/dist/core/adapters/useArrayAdapter.js.map +0 -1
- package/dist/core/fillInPoseFrame.js +0 -102
- package/dist/core/fillInPoseFrame.js.map +0 -1
- package/dist/core/geometry/poseFrame.js +0 -44
- package/dist/core/geometry/poseFrame.js.map +0 -1
- package/dist/core/geometry/poseRotation.js +0 -58
- package/dist/core/geometry/poseRotation.js.map +0 -1
- package/dist/core/gradient.js +0 -136
- package/dist/core/gradient.js.map +0 -1
- package/dist/core/markerInset.js +0 -24
- package/dist/core/markerInset.js.map +0 -1
- package/dist/core/mixed.js +0 -6
- package/dist/core/mixed.js.map +0 -1
- package/dist/core/paintKinds.js +0 -156
- package/dist/core/paintKinds.js.map +0 -1
- package/dist/core/scene/pickability.js +0 -6
- package/dist/core/scene/pickability.js.map +0 -1
- package/dist/core/strokeMarkerShapes.js +0 -139
- package/dist/core/strokeMarkerShapes.js.map +0 -1
- package/dist/core/strokeMarkers.js +0 -28
- package/dist/core/strokeMarkers.js.map +0 -1
- package/dist/core/viewport/meanScale.js +0 -8
- package/dist/core/viewport/meanScale.js.map +0 -1
- package/dist/core/viewport/pxExtent.js +0 -42
- package/dist/core/viewport/pxExtent.js.map +0 -1
- package/dist/features/cursor/paintedCursorLayer.js.map +0 -1
- package/dist/features/focus/gateLayer.js.map +0 -1
- package/dist/features/focus/useCanvasFocus.js +0 -29
- package/dist/features/focus/useCanvasFocus.js.map +0 -1
- package/dist/features/groups/children.js.map +0 -1
- package/dist/features/groups/composePose.js.map +0 -1
- package/dist/features/groups/nestedHit.js.map +0 -1
- package/dist/features/groups/unionOfChildren.js.map +0 -1
- package/dist/features/images/imageCache.js +0 -104
- package/dist/features/images/imageCache.js.map +0 -1
- package/dist/features/ingestion/index.js +0 -8
- package/dist/features/meshPaint/bake.js +0 -79
- package/dist/features/meshPaint/bake.js.map +0 -1
- package/dist/features/meshPaint/bakeCache.js +0 -59
- package/dist/features/meshPaint/bakeCache.js.map +0 -1
- package/dist/features/meshPaint/handles.js +0 -86
- package/dist/features/meshPaint/handles.js.map +0 -1
- package/dist/features/meshPaint/lazyKind.js.map +0 -1
- package/dist/features/meshPaint/meshPaint.js +0 -239
- package/dist/features/meshPaint/meshPaint.js.map +0 -1
- package/dist/features/meshPaint/meshShader.js +0 -6
- package/dist/features/meshPaint/meshShader.js.map +0 -1
- package/dist/features/meshPaint/register.js +0 -7
- package/dist/features/meshPaint/register.js.map +0 -1
- package/dist/features/meshPaint/surface.js +0 -110
- package/dist/features/meshPaint/surface.js.map +0 -1
- package/dist/features/minimap/actions.js +0 -53
- package/dist/features/minimap/actions.js.map +0 -1
- package/dist/features/minimap/createMinimapContribution.js +0 -96
- package/dist/features/minimap/createMinimapContribution.js.map +0 -1
- package/dist/features/minimap/layers.js +0 -85
- package/dist/features/minimap/layers.js.map +0 -1
- package/dist/features/overlays/useNodeOverlayFrame.js +0 -103
- package/dist/features/overlays/useNodeOverlayFrame.js.map +0 -1
- package/dist/features/parallax/createParallaxLayer.js +0 -26
- package/dist/features/parallax/createParallaxLayer.js.map +0 -1
- package/dist/features/parallax/createParallaxPlane.js +0 -22
- package/dist/features/parallax/createParallaxPlane.js.map +0 -1
- package/dist/features/paths/anchorEdits.js +0 -167
- package/dist/features/paths/anchorEdits.js.map +0 -1
- package/dist/features/paths/anchors.js +0 -159
- package/dist/features/paths/anchors.js.map +0 -1
- package/dist/features/paths/booleans.js +0 -2
- package/dist/features/paths/markerCommands.js +0 -149
- package/dist/features/paths/markerCommands.js.map +0 -1
- package/dist/features/paths/markerSites.js +0 -59
- package/dist/features/paths/markerSites.js.map +0 -1
- package/dist/features/paths/markers.js +0 -95
- package/dist/features/paths/markers.js.map +0 -1
- package/dist/features/paths/nearestAnchor.js +0 -36
- package/dist/features/paths/nearestAnchor.js.map +0 -1
- package/dist/features/paths/pathInWorld.js +0 -41
- package/dist/features/paths/pathInWorld.js.map +0 -1
- package/dist/features/paths/poseDescriptor.js +0 -39
- package/dist/features/paths/poseDescriptor.js.map +0 -1
- package/dist/features/paths/strokeToPath.js +0 -40
- package/dist/features/paths/strokeToPath.js.map +0 -1
- package/dist/features/paths/tessellate/dash.js +0 -52
- package/dist/features/paths/tessellate/dash.js.map +0 -1
- package/dist/features/paths/tessellate/insets.js +0 -32
- package/dist/features/paths/tessellate/insets.js.map +0 -1
- package/dist/features/paths/tessellate/metric.js +0 -72
- package/dist/features/paths/tessellate/metric.js.map +0 -1
- package/dist/features/paths/tessellate/stroke.js +0 -170
- package/dist/features/paths/tessellate/stroke.js.map +0 -1
- package/dist/features/paths/tessellate/vertexWidths.js +0 -32
- package/dist/features/paths/tessellate/vertexWidths.js.map +0 -1
- package/dist/features/patterns/commandPaint.js +0 -18
- package/dist/features/patterns/commandPaint.js.map +0 -1
- package/dist/features/patterns/index.js +0 -11
- package/dist/features/patterns/index.js.map +0 -1
- package/dist/features/patterns/patterns-builtin.js +0 -38
- package/dist/features/patterns/patterns-builtin.js.map +0 -1
- package/dist/features/patterns/rasterizeTile.js +0 -17
- package/dist/features/patterns/rasterizeTile.js.map +0 -1
- package/dist/features/patterns/resolveSpec.js +0 -65
- package/dist/features/patterns/resolveSpec.js.map +0 -1
- package/dist/features/patterns/tileGeometry.js +0 -158
- package/dist/features/patterns/tileGeometry.js.map +0 -1
- package/dist/features/pointer/PointerContext.js +0 -45
- package/dist/features/pointer/PointerContext.js.map +0 -1
- package/dist/features/selection/SelectionContext.js +0 -51
- package/dist/features/selection/SelectionContext.js.map +0 -1
- package/dist/features/simulation/createSimulation.js +0 -61
- package/dist/features/simulation/createSimulation.js.map +0 -1
- package/dist/features/simulation/types.js +0 -6
- package/dist/features/simulation/types.js.map +0 -1
- package/dist/features/simulation/useSimulation.js +0 -74
- package/dist/features/simulation/useSimulation.js.map +0 -1
- package/dist/features/text/domOffsets.js +0 -82
- package/dist/features/text/domOffsets.js.map +0 -1
- package/dist/features/text/domRuns.js +0 -230
- package/dist/features/text/domRuns.js.map +0 -1
- package/dist/features/text/fitTextPose.js +0 -38
- package/dist/features/text/fitTextPose.js.map +0 -1
- package/dist/features/text/hitTest.js +0 -48
- package/dist/features/text/hitTest.js.map +0 -1
- package/dist/features/text/isTextData.js +0 -8
- package/dist/features/text/isTextData.js.map +0 -1
- package/dist/features/text/overlayDirection.js +0 -15
- package/dist/features/text/overlayDirection.js.map +0 -1
- package/dist/features/text/renderLabel.js +0 -14
- package/dist/features/text/renderLabel.js.map +0 -1
- package/dist/features/text/runs/effectiveRangeStyle.js +0 -66
- package/dist/features/text/runs/effectiveRangeStyle.js.map +0 -1
- package/dist/features/text/runs/flagRange.js +0 -53
- package/dist/features/text/runs/flagRange.js.map +0 -1
- package/dist/features/text/runs/rangeStyle.js +0 -133
- package/dist/features/text/runs/rangeStyle.js.map +0 -1
- package/dist/features/text/textCommand.js +0 -60
- package/dist/features/text/textCommand.js.map +0 -1
- package/dist/features/text/textToPath.js +0 -181
- package/dist/features/text/textToPath.js.map +0 -1
- package/dist/features/text/useTextEdit.js +0 -491
- package/dist/features/text/useTextEdit.js.map +0 -1
- package/dist/features/tiling/createTiledLayer.js +0 -65
- package/dist/features/tiling/createTiledLayer.js.map +0 -1
- package/dist/features/tiling/tiledProject.js +0 -14
- package/dist/features/tiling/tiledProject.js.map +0 -1
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js +0 -26
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +0 -1
- package/dist/interactions/actions/defaults/align.js.map +0 -1
- package/dist/interactions/actions/defaults/booleans.js +0 -52
- package/dist/interactions/actions/defaults/booleans.js.map +0 -1
- package/dist/interactions/actions/defaults/clipboard.js.map +0 -1
- package/dist/interactions/actions/defaults/clone.js +0 -91
- package/dist/interactions/actions/defaults/clone.js.map +0 -1
- package/dist/interactions/actions/defaults/createOutlines.js +0 -47
- package/dist/interactions/actions/defaults/createOutlines.js.map +0 -1
- package/dist/interactions/actions/defaults/distribute.js.map +0 -1
- package/dist/interactions/actions/defaults/editAnchors.js.map +0 -1
- package/dist/interactions/actions/defaults/flip.js +0 -125
- package/dist/interactions/actions/defaults/flip.js.map +0 -1
- package/dist/interactions/actions/defaults/insert.js +0 -287
- package/dist/interactions/actions/defaults/insert.js.map +0 -1
- package/dist/interactions/actions/defaults/lassoSelect.js +0 -153
- package/dist/interactions/actions/defaults/lassoSelect.js.map +0 -1
- package/dist/interactions/actions/defaults/move.js +0 -778
- package/dist/interactions/actions/defaults/move.js.map +0 -1
- package/dist/interactions/actions/defaults/resize.js +0 -341
- package/dist/interactions/actions/defaults/resize.js.map +0 -1
- package/dist/interactions/actions/defaults/rotate.js +0 -185
- package/dist/interactions/actions/defaults/rotate.js.map +0 -1
- package/dist/interactions/actions/previewOverrides.js +0 -25
- package/dist/interactions/actions/previewOverrides.js.map +0 -1
- package/dist/interactions/actions/resize/autoPoseDescriptor.js.map +0 -1
- package/dist/math-J-ACHyEg.d.ts +0 -159
- package/dist/registerProgram-T9S_PfAX.d.ts +0 -208
- package/dist/renderer/DrawCommand.js +0 -6
- package/dist/renderer/DrawCommand.js.map +0 -1
- package/dist/renderer/WeaselRenderer.js +0 -333
- package/dist/renderer/WeaselRenderer.js.map +0 -1
- package/dist/renderer/batchClip.js +0 -46
- package/dist/renderer/batchClip.js.map +0 -1
- package/dist/renderer/cache/GLImageCache.js +0 -74
- package/dist/renderer/cache/GLImageCache.js.map +0 -1
- package/dist/renderer/cache/GLMeshCache.js +0 -102
- package/dist/renderer/cache/GLMeshCache.js.map +0 -1
- package/dist/renderer/cache/GLTextureCache.js +0 -68
- package/dist/renderer/cache/GLTextureCache.js.map +0 -1
- package/dist/renderer/cache/GradientRampAtlas.js +0 -82
- package/dist/renderer/cache/GradientRampAtlas.js.map +0 -1
- package/dist/renderer/cache/cache.js +0 -13
- package/dist/renderer/cache/cache.js.map +0 -1
- package/dist/renderer/cache/markerCommandCache.js +0 -63
- package/dist/renderer/cache/markerCommandCache.js.map +0 -1
- package/dist/renderer/cache/outlineMeshCache.js +0 -15
- package/dist/renderer/cache/outlineMeshCache.js.map +0 -1
- package/dist/renderer/cache/outlineStrokeMeshCache.js +0 -36
- package/dist/renderer/cache/outlineStrokeMeshCache.js.map +0 -1
- package/dist/renderer/cache/strokeMeshCache.js +0 -55
- package/dist/renderer/cache/strokeMeshCache.js.map +0 -1
- package/dist/renderer/cullDrawCommands.js +0 -90
- package/dist/renderer/cullDrawCommands.js.map +0 -1
- package/dist/renderer/draw/batch.js +0 -133
- package/dist/renderer/draw/batch.js.map +0 -1
- package/dist/renderer/draw/clip.js +0 -89
- package/dist/renderer/draw/clip.js.map +0 -1
- package/dist/renderer/draw/customShader.js +0 -230
- package/dist/renderer/draw/customShader.js.map +0 -1
- package/dist/renderer/draw/drawTriangles.js +0 -8
- package/dist/renderer/draw/drawTriangles.js.map +0 -1
- package/dist/renderer/draw/effects.js +0 -28
- package/dist/renderer/draw/effects.js.map +0 -1
- package/dist/renderer/draw/flushBatch.js +0 -35
- package/dist/renderer/draw/flushBatch.js.map +0 -1
- package/dist/renderer/draw/gradient.js +0 -90
- package/dist/renderer/draw/gradient.js.map +0 -1
- package/dist/renderer/draw/image.js +0 -38
- package/dist/renderer/draw/image.js.map +0 -1
- package/dist/renderer/draw/mesh.js +0 -16
- package/dist/renderer/draw/mesh.js.map +0 -1
- package/dist/renderer/draw/paintBind.js +0 -70
- package/dist/renderer/draw/paintBind.js.map +0 -1
- package/dist/renderer/draw/pathPaint.js +0 -142
- package/dist/renderer/draw/pathPaint.js.map +0 -1
- package/dist/renderer/draw/scratchPass.js +0 -83
- package/dist/renderer/draw/scratchPass.js.map +0 -1
- package/dist/renderer/draw/stencil.js +0 -28
- package/dist/renderer/draw/stencil.js.map +0 -1
- package/dist/renderer/draw/text.js +0 -167
- package/dist/renderer/draw/text.js.map +0 -1
- package/dist/renderer/draw/uniforms.js +0 -77
- package/dist/renderer/draw/uniforms.js.map +0 -1
- package/dist/renderer/draw.js +0 -79
- package/dist/renderer/draw.js.map +0 -1
- package/dist/renderer/drawBatch.js +0 -198
- package/dist/renderer/drawBatch.js.map +0 -1
- package/dist/renderer/effects/EffectTargets.js +0 -48
- package/dist/renderer/effects/EffectTargets.js.map +0 -1
- package/dist/renderer/effects/builtins.js +0 -31
- package/dist/renderer/effects/builtins.js.map +0 -1
- package/dist/renderer/effects/composite.js +0 -11
- package/dist/renderer/effects/composite.js.map +0 -1
- package/dist/renderer/effects/effectPrelude.js +0 -10
- package/dist/renderer/effects/effectPrelude.js.map +0 -1
- package/dist/renderer/effects/types.js +0 -10
- package/dist/renderer/effects/types.js.map +0 -1
- package/dist/renderer/glyphOutlineMesh.js +0 -67
- package/dist/renderer/glyphOutlineMesh.js.map +0 -1
- package/dist/renderer/index.js +0 -20
- package/dist/renderer/math/color.js +0 -321
- package/dist/renderer/math/color.js.map +0 -1
- package/dist/renderer/math/mat3.js +0 -80
- package/dist/renderer/math/mat3.js.map +0 -1
- package/dist/renderer/math/patternSpace.js +0 -22
- package/dist/renderer/math/patternSpace.js.map +0 -1
- package/dist/renderer/math/viewToMat3.js +0 -19
- package/dist/renderer/math/viewToMat3.js.map +0 -1
- package/dist/renderer/paintResources.js +0 -18
- package/dist/renderer/paintResources.js.map +0 -1
- package/dist/renderer/paintScratch.js +0 -37
- package/dist/renderer/paintScratch.js.map +0 -1
- package/dist/renderer/shaders/ShaderProgram.js +0 -74
- package/dist/renderer/shaders/ShaderProgram.js.map +0 -1
- package/dist/renderer/shaders/batchFill.js +0 -119
- package/dist/renderer/shaders/batchFill.js.map +0 -1
- package/dist/renderer/shaders/customPrelude.js +0 -34
- package/dist/renderer/shaders/customPrelude.js.map +0 -1
- package/dist/renderer/shaders/extractUniformNames.js +0 -184
- package/dist/renderer/shaders/extractUniformNames.js.map +0 -1
- package/dist/renderer/shaders/glyphPaint.js +0 -61
- package/dist/renderer/shaders/glyphPaint.js.map +0 -1
- package/dist/renderer/shaders/gradFill.js +0 -31
- package/dist/renderer/shaders/gradFill.js.map +0 -1
- package/dist/renderer/shaders/pathFill.js +0 -14
- package/dist/renderer/shaders/pathFill.js.map +0 -1
- package/dist/renderer/shaders/patternFill.js +0 -25
- package/dist/renderer/shaders/patternFill.js.map +0 -1
- package/dist/renderer/shaders/registerProgram.js +0 -18
- package/dist/renderer/shaders/registerProgram.js.map +0 -1
- package/dist/renderer/spriteSheet.js +0 -14
- package/dist/renderer/spriteSheet.js.map +0 -1
- package/dist/renderer/state/GroupState.js +0 -77
- package/dist/renderer/state/GroupState.js.map +0 -1
- package/dist/renderer/strokeLengths.js +0 -50
- package/dist/renderer/strokeLengths.js.map +0 -1
- package/dist/renderer/syntheticItalic.js +0 -6
- package/dist/renderer/syntheticItalic.js.map +0 -1
- package/dist/renderer/textures/registerTexture.js +0 -34
- package/dist/renderer/textures/registerTexture.js.map +0 -1
- package/dist/scheduling/useVisibleRaf.js +0 -69
- package/dist/scheduling/useVisibleRaf.js.map +0 -1
- package/dist/test-seams-DM2B87-g.d.ts +0 -356
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,755 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.10.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- dfc0dda: Fixes: on a node whose pose carries a `transform`, the corner handles, the rotate ring, and the rotate badge took presses where they would sit on the unskewed box. Each is hit and painted where the node is drawn, and a corner-resize hit names its fixed corner there.
|
|
8
|
+
|
|
9
|
+
Breaking: `TargetTransform` is the target's frame as two matrices, `{ identity, toWorld, toLocal }`, where it was a pivot with a cosine and a sine, and `annulusSemiAxes` takes one as its third argument where it took a rotation in radians. An `AffordanceRegion`'s local frame is its target bounds' `rotation` and `transform` together.
|
|
10
|
+
- cd8cbbd: Fixes: a key typed with AltGr could not match a key binding. A layout that types `[` with AltGr reports Ctrl and Alt held with it, and the strict modifier match read that as a chord. The dispatcher still tries the chord as reported first, so a binding that names Ctrl+Alt keeps it; when nothing takes it and the browser reports AltGraph, it tries again without Ctrl and Alt. A key that reports its own letter or digit is left a chord, because Firefox on Windows reports AltGraph for a plain Ctrl+Alt as well. Checked in jsdom only, not on a Windows browser.
|
|
11
|
+
- 1f7548d: routing: the pointer store and the selection context live in `@weasel-js/routing/react` now. That is `PointerContextProvider`, `createPointerStore`, `usePointerContext`, `usePointerPosition`, `SelectionContextProvider`, `SelectionContextProviderIfRoot`, `useSelectionContext`, and `usePublishSelection`, with the `PointerContextValue`, `PointerWorldPos`, and `SelectionContextValue` types. `@weasel-js/core` still exports every one of them.
|
|
12
|
+
- a86d79f: geom: the anchor-set edits live here now (`editAnchorSet`, `translateAnchorBy`, `moveHandleTo`, `insertAnchorOnSegment`, `deleteAnchorsAt`, `openSubpathAt`, `segmentAt`, `anchorsInRect`, `anchorAt`, `anchorCount`, `locateAnchor`, `flatAnchorIndex`, with `AnchorSet`, `AnchorRect`, and `SegmentHit`), beside `pathInWorld`, `pathInPoseFrame`, `worldEditToStorage`, and `PathInWorldPose`. `nearestPathAnchor`, `reverseAnchors`, and `PathAnchorHit` are exported here; they were not exports of `@weasel-js/core` before.
|
|
13
|
+
|
|
14
|
+
text: `textToPath`, `textToPathsByPaint`, `loadTextOutlines`, and `TextOutlinesError` live here now, with `TextOutlineSource`, `TextNodeSource`, `TextPaintPath`, `TextToPathOptions`, and `TextOutlinesFailure`. `SYNTHETIC_ITALIC_RADIANS`, the lean a faked italic takes, is exported here; it was not an export of `@weasel-js/core` before.
|
|
15
|
+
|
|
16
|
+
`@weasel-js/core` still exports every name it did before.
|
|
17
|
+
- ad15c29: Animations can move a target, and several on one target add. This is new API; nothing existing changes.
|
|
18
|
+
|
|
19
|
+
`createTarget({ get, set, axes?, show? })` wraps one value: `get` and `set` read and write what is committed, the value that shows when nothing is animating. `tween`, `spring`, `physics`, and `decay` take `target` in place of `onTick`. An animation on a target commits its destination as it starts and contributes only what it has left to travel, so a second one started mid-flight bends the motion toward its own destination and neither cancels the other. `target.read()` is the value to show, and `show` is handed it once a frame while the target moves.
|
|
20
|
+
|
|
21
|
+
- `from` defaults to the committed value, so the value on screen does not move as an animation starts.
|
|
22
|
+
- Canceling commits where the animation was. A coast (`decay`, or `physics` with `to: null`) commits where it stops.
|
|
23
|
+
- Under one `cancelKey` the new animation still interrupts the old. A spring interrupting an animation on the same target starts at that one's velocity unless given its own.
|
|
24
|
+
- `axes.angles` names axes that are angles in radians; an animation takes the short way round on them.
|
|
25
|
+
- A target is moved by one animator at a time; a second throws.
|
|
26
|
+
- 90eae1c: `animateOnSetPose` and `animateLifecycle` take any adapter with the methods they use, and return the adapter they were given with those methods replaced. The adapter `sceneToAdapter` and `useSceneAdapter` build now passes without a cast, and keeps its own type on the way out. Adds API: `LifecycleAdapter`, the part of an adapter `animateLifecycle` reads.
|
|
27
|
+
|
|
28
|
+
Breaking for a call that passes type arguments: `animateOnSetPose<TNode, TPose>` is now `animateOnSetPose<TPose, A>`, and `animateLifecycle<TNode, TPose>` gains the adapter's type as a third. A call that leaves them to inference is unaffected, except that a cast to `never` on the adapter now makes the result `never`: drop the cast.
|
|
29
|
+
- 96a63de: add `@weasel-js/animator`: the animator moved out of core. `useAnimator`, `createTarget`, `createTargetTable`, the timeline tracks and `sampleTrack`, the skeleton math (`resolveSkeleton`, `skeletonAxes`, `jointAxes`, `solveIk`, `mirrorPose`, `IDENTITY_JOINT`), the vertex-color helpers and `ColorOverrideRegistry`, `createSlew`, and every animator type (`Animator`, `AnimationHandle`, `TimelineHandle`, `Target`, and the rest) are exported from it and no longer from `@weasel-js/core`. Breaking: import those names from `@weasel-js/animator`. It needs geom, paint, react, and registry, and nothing of the scene.
|
|
30
|
+
|
|
31
|
+
core keeps what moves a scene with it: `tweenPose`, `springPose`, `staggerSpringPose`, `createPoseTarget`, `momentum`, the `animate*` adapter wrappers, `useAnimatedReflow`, `bindRig`, and `useRig`, and still exports the easings from geom. The animator also exports `axesOf`, which gives the axes of a number, an array of numbers, or an object of numeric fields.
|
|
32
|
+
|
|
33
|
+
`@weasel-js/ui`, `@weasel-js/diagram`, `@weasel-js/d3`, `@weasel-js/minimap`, and `@weasel-js/labkit` take the animator as a peer beside core. labkit leaves it out of its bundle, as it does core: the animator keeps its record of each target in module scope, so an app has to hold one copy.
|
|
34
|
+
- 7140b5a: Adds API: a hold or a timeline track names the axes it holds. `HoldOptions.axes` and `SampledTrack.axes` take a name wherever they took an index: a plain object's field, `animator.hold({ target, value, axes: ['y'] })`, a rig's joint, `axes: ['armL']`, or one axis of a joint, `axes: ['armL.rotation']`. Names are typed against the target's value where it has fixed fields, and one the target has no axis for throws as the hold starts.
|
|
35
|
+
|
|
36
|
+
A target's axes carry the names: `TargetAxes.names` is one name per axis, where a dot makes a path that a shorter name reaches as a whole. `axesOf` names a plain object's axes by its fields and `skeletonAxes` names a pose's `<joint>.<field>`; axes written by hand name theirs by setting `names`. `target.axisIndexes(['y'])` answers the indexes for a caller that wants the numbers, and `jointAxes` goes through the same lookup. `AxisName` and `AxisRef` are the types.
|
|
37
|
+
|
|
38
|
+
Adds API: the stagger builder moves targets. `.tween` and a new `.spring` move each item where the items are targets, `animator.stagger(targets, 80).spring({ to: (target) => ..., preset: 'wobbly' })`, or the target a `target` option names for the item, one for them all or a function of the item. Both keep the form that hands values to `onTick`, and `.tween` there takes an `interpolator`. The option types are `StaggerTargetTweenOptions`, `StaggerTargetSpringOptions`, and `StaggerSpringOptions`.
|
|
39
|
+
|
|
40
|
+
Breaking, within this unreleased surface: a clip's axis names no longer go through the binder. `ClipBinder.axes`, `SampledTrack.axisNames`, and `sceneClipAxes` in `@weasel-js/core` are gone, since a rig's target answers its own joint names; drop `axes` from a binder and a clip naming joints plays as before. `bindClip` now also throws on a numeric axis out of the target's range, where that used to wait for the playhead to reach the track.
|
|
41
|
+
- 8e00180: A node that derives its path is drawn and picked where the path is on a canvas with no scene behind it. `dependsOn` and `derivePath` used to resolve only where a `Scene` was in scope, so through a bare adapter such a node answered from its own placeholder pose: `drawOne` got no `derivedPath`, a derived container imposed no clip, and `useSelectTool`'s default `pickEvery` tested a zero-sized box. Deriving reads a dependency's node and where it is drawn, which every adapter already answers through `getNode` and `getPose` (`getWorldPose` and `getChildren` where it has them), so the scene layer and `adapterPickSource` now resolve the path from those. Nothing pushes an invalidation on that path: the memo re-checks what the adapter answers each time it is read. The default pick tests a derived leaf against the box of its path, grown by `pickTolerance`, and against its ink under `leafPicking: 'silhouette'`. A `drawOne` on a bare `<Canvas>` now receives a fourth `ctx` argument for a derived node.
|
|
42
|
+
- fc267f3: A gesture behavior can do three more things. Two existing things change with them:
|
|
43
|
+
|
|
44
|
+
- Code that calls a `MoveBehavior`'s `onEnd` directly, such as a consumer's own test, must now pass a `MoveEnd` as the second argument: `{ answered, translateOps }`.
|
|
45
|
+
- For the dragged nodes `snapToContainer` has no slot for, the committed ops now come from the move's default translate. They carry the move's label where they carried the behavior's `moveLabel`, and include the geometry data op when `geometryProjection` is wired.
|
|
46
|
+
|
|
47
|
+
A move behavior that claims the commit can ask for the default translate of the nodes it did not place. Its `onEnd` is handed a `MoveEnd`, and `end.translateOps(ids)` returns the ops the action would have written for those dragged roots and the descendants that follow them, by the drag as the behaviors shaped it. `ActionBehavior` takes the type of that second argument as a fourth parameter, `BehaviorEnd` unless an action says otherwise. `snapToContainer` commits the nodes it has no slot for this way, which fixes undo for a derived node among them: undoing the drop left its authored pose at the derived one.
|
|
48
|
+
|
|
49
|
+
A behavior can act once the gesture's result is in the document. `onSettled(ctx, committed)` runs once per gesture, after the commit's ops have applied or the cancel has run, and after the preview overrides are dropped. `committed` is false when the gesture was canceled, aborted by a behavior, or released with nothing to commit, and true otherwise: the action or a behavior made the commit, a behavior claiming it with no ops included. For move, resize, and rotate it is the value `onGestureEnd` receives. Move, resize, rotate, insert, and lasso-select all call it, and still do when the commit throws. Every behavior's `onSettled` runs even when an earlier one throws, and the same now holds for `onCancel`; the first error is rethrown once all have run.
|
|
50
|
+
|
|
51
|
+
A move behavior can preview a node the drag does not move, and say which previews paint settled. `BehaviorResult.poses` was honored only for dragged ids; a pose for any other id now enters the gesture's previews too, in that node's stored frame, for the frame that returns it. Committing such a node is the behavior's job. `BehaviorResult.opaque` names ids whose preview paints at full opacity that frame, which the move action reports through `previewOpaqueIds` beside the siblings a layout drop reflows.
|
|
52
|
+
- 9f5cdb2: A binding can say it is declared ahead of another on the same input on purpose: `opts: { yields: true }`. The route-conflict check does not report a pair whose earlier binding yields. The dispatcher already fired the next binding when an action declined through `enabled()`; this only tells the check that the order is the design. The slice tool's point drag and the keys `modeShortcuts` binds use it, so a tool set with slice in it, or a mode entered on a key another mode commits on, no longer warns. An entry key shared that way is still reported when `modeShortcuts` is given no `canEnter`, since nothing then keeps it from firing inside the other mode.
|
|
53
|
+
|
|
54
|
+
<!-- bump-approved: minor: maintainer — 1.10.0 release requested 2026-10-13 -->
|
|
55
|
+
- b9fb732: core: depends on `@msb235/blits` 0.10.0, up from 0.8.1. Nothing the animator shows changes: tweens, springs, paths, and holds read the same on both.
|
|
56
|
+
- 67f4d79: Adds API: `useBoneTool({ scene, rig })`, a tool that draws and edits the skeleton in a node's `data.skeleton` on the canvas. `rig` answers the node to edit, usually from the selection; a node with no skeleton gets one when the first bone is drawn. A drag on a joint moves it with the joints under it. A drag from anywhere else draws a bone, from the active joint if there is one and from the press if not. A click picks the active joint or clears it, Delete removes it and everything under it, taking those joints' weights out of every `data.skin` beneath the rig node, and Escape clears it. Each edit is one undo entry. The tool edits the bind pose; its key is J. Mount it with `tools={{ bone }}`.
|
|
57
|
+
|
|
58
|
+
`createRigEditState()` holds the active joint, to share between this tool and the weight tool. `placeSkeleton(skeleton, pose)` and `unplaceSkeleton` carry a skeleton between a rig node's data and the scene's space, and `createBoneOverlay` is the layer that draws one.
|
|
59
|
+
- d137eaf: Each piece of a Divide or a Crop stands in for its own source. `applyBooleanOp` hands `createPathNode` the topmost source a piece was cut from, where it passed the topmost selected one for every piece, so a Crop's pieces no longer take the mask's paint and parent. A `paint` argument is that source's too.
|
|
60
|
+
|
|
61
|
+
Results are placed per parent: those whose sources share a parent land as one block in the slot of the topmost source there. A selection inside one parent lands where it did before.
|
|
62
|
+
|
|
63
|
+
Behavior change for a `BooleansAdapter`: `createPathNode`'s `sourceId` varies between the pieces of one call. An adapter that painted every result from the topmost selected node should read `sourceId`.
|
|
64
|
+
- 99553f7: Fixes: the canvas-2D text paths read a tab as one space, where `layoutRuns` runs it to the next stop. `measureText` and `layoutMarkdown` now measure and wrap a tab to its stop, `tabSize` spaces apart (default 8), so both end a line where the GL tier does. This changes behavior, on an agent's judgment: the alternative was to keep the canvas's own reading of a tab.
|
|
65
|
+
|
|
66
|
+
- `layoutMarkdown` returns a tab as a `PositionedRun` of its own, as wide as its advance, so `createMarkdownRenderer` paints what follows at the stop and a rule runs across it. It takes `tabSize` as a seventh argument, and `MarkdownFontOptions` gains `tabSize`.
|
|
67
|
+
- Adds API: `MeasuredText.spans`, each line's text split at its tabs with the x every piece starts at (type `MeasuredSpan`). `fillText` still draws a tab as a space, so a painter that fills `lines[i]` whole misplaces what follows a tab; fill each span at its `x` instead.
|
|
68
|
+
- 5149cce: Fixes: a canvas font registered while its web font was still loading kept the fallback face's shapes and advances for the session. Measured in Chromium: a canvas draws a family it has not loaded in a fallback, and its `W` at 48px is more than a pixel off the real face's. The canvas tier now listens to `document.fonts` for `loadingdone` and measures the loaded families' faces again, in place, then signals `subscribeGlyphReady` so the text lays out again. The listener is added when the tier makes its first face.
|
|
69
|
+
|
|
70
|
+
Adds API: `refreshCanvasFont(family?)` does the same on request, for one family or for all of them. A `FontFace` loaded before it is added to `document.fonts` is never announced by the document, so that case needs the call.
|
|
71
|
+
- 2c6246d: Breaking, in types only: `CanvasProps` takes one type argument, the pose, where it took the node type and the pose. Its `adapter` is now typed as what the canvas reads of it, `getPose` and an optional `getWorldPose`; it was typed as the move, resize, and rotate adapters together, so an adapter with only pose lookups needed a cast. Write `CanvasProps<TPose>` where you wrote `CanvasProps<TNode, TPose>`. `SceneCanvasProps` is unchanged.
|
|
72
|
+
- de60e10: Adds API: range selection on the canvas. `useSelection({ mode: 'multi', range: 'shift', extend: 'meta' })` selects everything from the last pressed id through the one clicked, and `<SceneCanvas selectionOptions>` takes the same options. The hook now keeps an anchor: a plain or toggling click moves it, a range leaves it where it is, and a selection set by anything else ranges from its last id.
|
|
73
|
+
|
|
74
|
+
`order` names the sequence a range walks, for a host with one of its own, such as a layer panel's rows. Decided on an agent's judgment: with no `order`, a hook bound to a scene walks the order the scene paints in (`scene.renderOrder()`), and a hook with neither replaces on the range key. Nothing ranges unless `range` is set, so existing callers are unchanged.
|
|
75
|
+
- 2892438: Breaking: `WeaselRenderer` no longer writes `width` and `height` as inline style on a canvas it is given, at construction or in `resize`. It sets the drawing buffer and nothing else, so a caller that hands it a canvas, or calls `renderSceneToCanvas`, sizes the element itself.
|
|
76
|
+
|
|
77
|
+
Breaking: `<SceneCanvas>`, `<SceneViewCanvas>`, `<DrawCanvas>`, and `<MinimapCanvas>` size their canvas through a class in `@weasel-js/core/style.css`, which a page now has to import for a canvas to be the right size. Without it the element is as large as its drawing buffer: twice too large at a device pixel ratio of 2. The class has no specificity, so a `className` whose rule sets `width` or `height` now resizes the element, where the inline style used to win. A rule that was written that way and never took effect starts to.
|
|
78
|
+
- b310df0: Several things `<Canvas>` did inline now have one owner each, shared with the other surfaces that did the same thing by hand. Most of it cannot be seen from outside; what can is listed here.
|
|
79
|
+
|
|
80
|
+
Adds API: `<CanvasView>` takes `cameraRef`, which receives `getView`, `setView`, and `subscribeView` for that view's camera (`CanvasViewCamera`), with the contract `<SceneCanvas>`'s own handle keeps: `setView` accepts an updater, subscribers hear every camera change, and an imperative `setView` on a controlled view is forwarded to `onViewChange`, not applied, and warns once. A pan or zoom made by input inside a controlled view is forwarded without the warning, as before. A view's camera is now the same implementation as the canvas's.
|
|
81
|
+
|
|
82
|
+
Changes: a `<CanvasView>` switched from controlled to uncontrolled continues from the last controlled camera, where it used to return to the last camera it held uncontrolled. A view controlled by a plain `view` value no longer repaints on a write it only forwarded; it repaints when the prop changes.
|
|
83
|
+
|
|
84
|
+
Breaking: `onFocus` and `onBlur` on `<SceneCanvas>` are called with the DOM `FocusEvent`, not React's synthetic one, and are typed `(event: FocusEvent) => void`. A handler typed against `React.FocusEvent` needs its parameter type changed; one that reads `event.target` or takes no argument is unaffected.
|
|
85
|
+
|
|
86
|
+
Fixes: `onFocus` and `onBlur` did nothing on a canvas given `paintInto`. They now report focus of its `inputElement`. `className`, `style`, and `tabIndex` still apply only to a canvas element the component renders, and their docs now say so.
|
|
87
|
+
|
|
88
|
+
Changes: the press that focuses the canvas, hover delivery to layers, and context-menu suppression are DOM listeners on the canvas element where they were React handlers, so they run when the event reaches the element instead of when it reaches React's root. A canvas given `paintInto` already worked this way.
|
|
89
|
+
|
|
90
|
+
Fixes: the debug overlay's frame-rate panel lost its history and showed no rate for a frame whenever a layer or a view was registered or removed.
|
|
91
|
+
|
|
92
|
+
Fixes: a `<Canvas>` with no `<SceneCanvas>` around it now repaints when an image finishes decoding, a glyph bake lands, or a paint kind registers late, as `<DrawCanvas>` and `<SceneViewCanvas>` already did.
|
|
93
|
+
|
|
94
|
+
Fixes: a canvas that unmounted left its handle in the view registry around it.
|
|
95
|
+
|
|
96
|
+
Changes: `decorationLayer` is composed as a `layers` entry keyed `decorationLayer` with no anchor, so another custom layer can anchor `before` or `after` it. It paints where it did, except that it now sits beneath a custom layer whose anchor names nothing or forms a cycle, which already warns. Its docs and `backgroundFill`'s described a draw order the code never had: the background sits beneath everything, the grid included, and the decoration layer sits above every slot and custom layer and beneath a tool's `'top'` overlays.
|
|
97
|
+
- 2a5d8ef: core: a batch that posed a container and also its descendants through a cascading adapter (`sceneToAdapter(scene, { cascadeContainerPose: true })`, what `<SceneCanvas>` uses without a composing strategy) came back wrong on undo, because each container's inverse cascaded a second time: A, B, and C at x = 0, 100, and 200 moved by 5 undid to 0, 95, and 190. The scene now records, with each op, every pose that op changed when it carried any for another node, and replaying the op in either direction puts those poses back without working the cascade out again. This holds for `adapter.applyOps`, for ops handed straight to `scene.applyBatch`, and for a history serialized and restored.
|
|
98
|
+
|
|
99
|
+
Additive: `Scene.carry(id, pose)` writes a pose on behalf of the op now applying, for an adapter that moves more than it was asked to. Outside an op it is `setPose`.
|
|
100
|
+
|
|
101
|
+
Changes what a snapshot holds: an op that carried poses serializes as `{ name: 'carry', args: { op, poses } }` around the op it stands for. An op that carried nothing serializes as before, and a snapshot written before this change restores and replays the way it did, the wrong undo of a mixed batch included.
|
|
102
|
+
- 3994be7: Adds: a No fill chip beside the character strip's Color field. On, it sends `{ fill: null }` through `CharacterOptions`' `onPatch`, so it unfills the selected range, or arms no fill for the next character at a caret. It is lit over a range whose fill is `null` and over an unfilled node's, which `effectiveRangeStyle` reports as no `fill` at all, and unlit over a mixed range.
|
|
103
|
+
|
|
104
|
+
Adds API: `useTextTool.options` gains a `noFill` leaf, the one key of that group that is not a `StyledRun` field. A host drawing the group itself maps it to `fill: null`.
|
|
105
|
+
|
|
106
|
+
Fixes: `CharacterOptions` threw on a range style whose `fill` was `null`.
|
|
107
|
+
|
|
108
|
+
Two calls here were made on an agent's judgment and no browser has drawn the chip. Turning it off fills the range with the color the Color field shows beside it, which is that leaf's default (`#000000`) while the range is unfilled, where taking the run's fill off would do nothing over an unfilled node. And the chip is a leaf of the tool's options, drawn by the bar as the Bold and Italic toggles are, with the `paintNone` glyph.
|
|
109
|
+
- e80de55: Fixes: the selection outline, the corner handles, and the rotate badge were drawn on the unskewed box of a node whose pose carries a `transform`. They are drawn on the shape as `poseFrameOf` draws it.
|
|
110
|
+
|
|
111
|
+
Adds API: `Bounds` carries an optional `transform` beside its `rotation`, and the bounds a canvas hands its chrome carry the pose's. `rotationHandle` reads it.
|
|
112
|
+
- b3ba3d9: Fixes: a `clientToWorld` override on the canvas was ignored by `<SceneCanvas>`'s own pointer handling. Gesture dispatch, the pointer store, and hover now convert through the canvas handle, so the override applies to all three.
|
|
113
|
+
|
|
114
|
+
Breaking: `CanvasExtensionApi.clientToWorld` is required where it was optional. It only affects code that builds a handle by hand, such as a test fake.
|
|
115
|
+
|
|
116
|
+
Removes: `canvas/toolPreview.ts`, which had no caller once tools stopped publishing previews.
|
|
117
|
+
- 9296fb4: Adds API: a clip can name the part of a target a track holds. `ClipSampledTrack.axes` takes names as well as numbers, `axes: ['armL', 'foreL']`, which the track's target resolves against its own axes, so a track over some of a rig's joints holds the same joints after the skeleton's joint order changes. The live track carries the names as its `axes`, and `toClip` writes them back. `bindClip` throws when a track names axes and has no target, or names one its target does not have.
|
|
118
|
+
|
|
119
|
+
Numbers go on working as positions in the target's axes, for a target that has no names, and a clip written with them binds as before.
|
|
120
|
+
- 0e46e02: The `clone` action runs the behaviors on its binding, as move, rotate, and insert do. A `CloneBehavior<TPose>` is told the originals, reshapes the drag's translation from `onMove`, and may claim or abort the commit from `onEnd`; `onCancel` and `onSettled` run as they do for a move. A move behavior that only reshapes the translation works as one, so `behaviors: [snap(strategy)]` on the alt-drag binding lands the copy on the grid.
|
|
121
|
+
|
|
122
|
+
Breaking: `CloneBehavior` is that `ActionBehavior` now, not the `{ id, activates, onEnd(pose, { adapter }) }` shape no action had read since `useClone` was removed. `cloneByAltDrag`, `ClonePose`, and `CloneLayer` are gone: the binding's `mods: { alt: true }` is what gates the clone. `CloneBehaviorResult` is new. `@weasel-js/core/clone` still resolves and now exports those two types and no values. Built on an agent's judgment, over deleting the contract.
|
|
123
|
+
- dee0a3b: A `tweenPose` or `springPose` of a node that `momentum` is coasting no longer makes it jump. The coast still ends, and the distance it had traveled now springs to nothing from the coast's speed, under the node's `pose:<id>` key, where it used to vanish in one frame.
|
|
124
|
+
- b1f7521: paint: the CSS color parser and the gradient helpers live here now. `parseColor`, `parseColorToRgba255`, `resolveColor`, `normalizeHex`, `hexToRgba`, `rgbaToHex`, `isGradientFill`, `sampleGradientStops`, `withGradientKind`, `gradientGeometry`, and `gradientForBounds` moved from `@weasel-js/core`, which still exports every one of them. New from paint: `resolveGradientStops` and `sampleResolvedStops`, with the `ResolvedGradientStop` type.
|
|
125
|
+
- e77f185: The camera and the vertex color helpers run on animation targets, so another animation on the same view or the same node's colors adds to them.
|
|
126
|
+
|
|
127
|
+
**Camera.** `useViewAnimation` and `useViewAnimationOn` return a new `viewTarget`, the view as a `Target<View>`. Run a shake or a nudge on it with the animator the hook was given, without the hook's cancel key, and it adds to a camera animation in flight. `stop()` and an outside write to the view cancel the hook's own animation and leave that one running; after an outside write it carries on from where the writer put the view. `viewAxes` is exported for building a view target of your own. `animate`, `animateToBounds`, `stop`, `target`, and `isAnimating` behave as before, and the channel still reads the live view mid-flight. A `<SceneCanvas>` keeps its camera animator private, so its `animateView` gains nothing new here.
|
|
128
|
+
|
|
129
|
+
**Colors.** `animator.colorOverrides.target(id, channel, length)` is the target for one node's colors on one channel; every caller gets the same one. `release(id, channel)` drops the colors a finished or canceled animation left painted. `tweenVertexColors`, `springVertexColors`, and `staggerVertexColors` move that target. What a consumer would notice:
|
|
130
|
+
|
|
131
|
+
- Breaking: a second `tweenVertexColors` or `staggerVertexColors` on a node and channel no longer cancels the first. Both run and add, which can paint colors outside 0..1 while they overlap.
|
|
132
|
+
- Breaking: `springVertexColors` springs each number on its own and drops its `interpolation` and `interpolate` options. An underdamped spring now overshoots `to` where it was clamped before. It still interrupts what is running, and now starts at the velocity of what it interrupts.
|
|
133
|
+
- A color animation over an override stored with `colorOverrides.set` (a `cycleVertexColors`, or your own array or function) adds what it has left to travel on top of the override and no longer replaces it. When it finishes, the override is still there.
|
|
134
|
+
- `colorOverrides.get` answers the colors a target is painting where `set` stored nothing, so reading mid-animation works as before. Nothing is stored with `set` by these helpers any more.
|
|
135
|
+
- As before, the painted colors are dropped when the animation finishes, and a canceled one holds its colors until `colorOverrides.clear`.
|
|
136
|
+
|
|
137
|
+
Animations on a target take `interrupt: false` to join their `cancelKey` without canceling whoever holds it, so one key can group animations that add.
|
|
138
|
+
- d635e84: Fixes: a combining mark was never drawn from an atlas. A glyph with a rect and no advance, which is what a combining accent is, was given no quad, so `e` followed by U+0301 painted a bare `e`. It is drawn now, where its offsets put it.
|
|
139
|
+
- dc1f09c: A container can declare the unit system its contents are written in. `ContainerNode.units` holds a `UnitScope` from `@weasel-js/quantity`: set it on the spec passed to `scene.add`, or later with `scene.setUnits(id, scope)`, which is one undo step and clears the scope when passed `null`. It rides through `toJSON` and `sceneFromJSON`, undo of a removal, copy and paste, and `reconcileSpecs`, which writes a changed scope in place. `sceneUnitScopes(scene, id, root)` returns the scopes enclosing a node, outermost first, which is what `resolveScoped` and `formatScoped` take; before this a consumer kept each scope beside the scene and handed `scopesOf` its own lookup. This adds API. Nothing in the kit reads the scope yet: grids and property fields still resolve against the one unit system they are given. `LayoutMove` and `LayoutFrame` moved to their own module and are exported from the same places.
|
|
140
|
+
- 2ed751e: The package description on npm says what core is now: a scene-graph engine rendered on WebGL2, where it said hooks over a canvas.
|
|
141
|
+
- b3f1e4a: history: `swapOp` builds an op that swaps one whole value for another and carries both as `args`, so a serialized history can rebuild the step. `@weasel-js/core` re-exports it with `SwapArgs` and `SwapOpOptions`. `PrefSchemaEditor`'s own swap is now a call to it.
|
|
142
|
+
|
|
143
|
+
forge: the CSS Vars panel keeps an undo history of a trial's edits. Undo and Redo sit beside the filter, and Mod+Z / Shift+Mod+Z step from anywhere in the panel except the filter's text. Typing a value is one step, and so is a scale edit with every token it regenerates. The steps are kept with the trial, so they outlive a reload, held to the last 100. Saving scales into the theme forgets them. A trial's scale edits are kept with the trial now (`fg-css-vars-scales` was lab-wide), so a scale edited in one trial no longer shows in another.
|
|
144
|
+
- 329f658: Fixes a tool's cursor disappearing after a hover cursor: with a tool that declares a `cursor`, moving over something that shows a cursor of its own and off again left the canvas with no cursor until the tool changed. `SceneCanvas.toolCursor.test.tsx` shows it with a registered layer's hit claim. The tool's cursor and the hover cursor were written to the same inline `cursor` style by two writers, and clearing the second removed the first.
|
|
145
|
+
|
|
146
|
+
Adds API: `createCursorSink({ element, painted })` in `@weasel-js/cursor`, also exported from `@weasel-js/core`, is one writer for both. It holds a base cursor and an override, writes the element's `cursor` style and the painted-cursor state, and puts the base back when the override clears. A canvas makes one and exposes it as `CanvasExtensionApi.cursorSink`; `useGestureDispatcher` takes it as the `cursorSink` option, and without one behaves as before. A hand-built `CanvasExtensionApi` now needs the `cursorSink` field.
|
|
147
|
+
- 0449330: Fixes: the debug overlay drew the hitbox of a rect or ring affordance region as a turned rect on a target whose bounds carry a `transform`. Such a region is recorded as the quad it lands on; a target that is only turned still records the unturned box and its rotation.
|
|
148
|
+
- 4878967: A derived path or pose notices more of what changed in a dependency without being told. The memo behind `derivePath` and `derivePose` used to re-check only each dependency's pose, so a derivation reading a dependency's `data`, its `layer`, or its `path` went stale unless the scene pushed an invalidation. It now re-checks all three; a dependency's path is compared only where the derivation read it, so one that never asks still costs no route. What a derivation may read of a dependency without a push is its node, `pose`, `data`, `layer`, and `path`. Replacing `data` rather than mutating it in place is what the check relies on, as the rest of the kit already does. The dependencies a derivation is handed are now wrappers over the ones the lookup answered, with the same three fields.
|
|
149
|
+
- 2a141ac: Fixes: a `useDragHandle` drag that was aborted while the button was still down, as when the component holding the hook unmounts mid-drag, then released over its source element, delivered a click to that element. The click guard now stays until the pointer is released, canceled, or pressed again. A drag the browser cancels still drops the guard at once, since no release follows it.
|
|
150
|
+
- 7063584: Fixes: a canvas with no binding for a drop was still a drop target. An OS drag over a `<SceneCanvas>` without the `ingest` preset showed the copy cursor and the `weasel-dropover` class, and the drop was swallowed with nothing inserted. `useGestureDispatcher` now asks its bindings on each `dragover` whether one would take a drop of what the drag carries, and only then cancels the event and adds the class. A drag nothing would take is left to the page.
|
|
151
|
+
|
|
152
|
+
This is a behavior change, decided on an agent's judgment: the question is answered per drag, by the bindings, with no new channel flag. A consumer's own `drop` binding makes the canvas a drop target without the `ingest` preset, and a binding typed `drop(image/*)` refuses a drag of plain text. A file whose type the browser withholds until the drop (Firefox names it `application/x-moz-file`) is accepted while it hovers.
|
|
153
|
+
|
|
154
|
+
Adds API: `UNKNOWN_MIME` in `@weasel-js/gestures`, the MIME of an item whose type is not known yet, which `matchIngestTypes` lets through every glob; and `itemTypesFromDataTransfer` in `@weasel-js/routing`, what a drag in flight says it carries.
|
|
155
|
+
|
|
156
|
+
Changes API: `SceneCanvasApi.ingest()` returns a boolean, where it returned nothing. `false` means the canvas had no `ingest` action to run, which was a silent no-op before; it also warns under the `ingest` debug namespace.
|
|
157
|
+
- da0335e: A scene subscriber that throws no longer stops the subscribers after it, or throws into the mutation that caused the notify. The scene's change notice, its selection, and `createPathEditState` now notify through `createEmitter`, so the error goes to `console.error` as `weasel: a subscriber threw`. A subscriber added during a notify now waits for the next one; the scene used to call it in the same pass.
|
|
158
|
+
- fb715f4: A listener that throws no longer stops the listeners after it, or throws into whatever caused the notify, in these stores: `createRigEditState`, the bone, weight, and slice tools' overlays, the view registry, a canvas renderer lease's `subscribeRestored`, and the animator's `onTick`. Each now notifies through `createEmitter`, so the error goes to `console.error` as `weasel: a subscriber threw`; `onTick` already kept going, and its message changes to that one. A listener added during a notify now waits for the next one.
|
|
159
|
+
- 3777548: Fixes: a character the layout had no glyph for was drawn on top of the next one once text grew past the outline threshold. With the fallback policy set to `'none'`, a code point missing from the atlas gets an empty, zero-width slot; above `outlineMinSize` the painter still asked the outline face for it and drew what it found there. An empty slot now draws nothing at any size.
|
|
160
|
+
- de319ce: Types a public signature names are exported now, so a consumer can write them down and the API reference links to them. All additions; nothing is renamed or removed.
|
|
161
|
+
|
|
162
|
+
- core: `ViewLike`, `TargetTransform`, `WeightEnv`.
|
|
163
|
+
- diagram: `DiagramRouter`, `DiagramTextStyle`, `DiagramDerivePose`, `Forest`.
|
|
164
|
+
- font: `DynamicFace`.
|
|
165
|
+
- forge: `ArgCondition`, `ComponentHistory`, `StoryGlobals`, `StoryLayout`, `StoryViewport`, `TimelineSpan`; from `/frame`, `Channel`, `ToFrame`, `FromFrame`, `ConfigAnswers`, `FaultPhase`; from `/shell`, `StoryRegistryOptions`, `StoryChanges`, `IndexEntry`, `CssVarReport`, `TrialFrameCalls`, `Libraries`, `SchemaDescription`, `DescribedShape`, `DescribedEntry`, `SectionDescription`.
|
|
166
|
+
- guides: `SnapToGuidesInsertArgs`, `SnapToGuidesMoveArgs`, and `SnapToGuidesResizeArgs`, each from its own subpath.
|
|
167
|
+
- hud: `AttachHudOptions`, `SourceRect`, `LoupeBaseOptions`.
|
|
168
|
+
- labkit: `MarkPose`, `AnnotationStorage`, `PaintedMark`, `ControlPanelProps`, `ControlPack`, `LoupeBindings`; from `/state`, `InstrumentHooks`; from `/config`, `Branching`, `Fields`, `FieldValues`, `Variants`, `VariantValues`.
|
|
169
|
+
- paint: `InCommandUnits`, `WithPatternHandle`.
|
|
170
|
+
- quantity: `FractionOptions`.
|
|
171
|
+
- renderer: `ShaderStage`, `UniformArray`.
|
|
172
|
+
- routing: `ToolScopes`.
|
|
173
|
+
- svg: `SvgDraftPose`.
|
|
174
|
+
- text-dom: `OverlayRunBase`.
|
|
175
|
+
- theme: `DtcgDocument`; from `/engine`, `SemanticCommon`, `DtcgGroup`, `DtcgAxesExtension`, `DtcgLayer`.
|
|
176
|
+
- ui: `ButtonBase`, `ButtonRegular`, `ButtonIconOnly`, `ToggleBarCommonProps`, `ToastFn`, `Fold`, `DistributiveOmit`, `WalkCtx`, `OverlayPoint`, `DocumentCodec`, `OpenedDocument`, `SchemaRoot`, `AnyNode`, `CurveSamplePoint`.
|
|
177
|
+
|
|
178
|
+
The names for types that had none of their own to export under (`StoryGlobals`, `TimelineSpan`, `CurveSamplePoint`, the `Diagram*` three, `ShaderStage`, `DtcgGroup`, `ToggleBarCommonProps`) were chosen by an agent.
|
|
179
|
+
- 3a92afc: Breaking: the paint model's serialized shape changed in three ways, and its type names in two. Nothing reads the old shapes.
|
|
180
|
+
|
|
181
|
+
**A fill is a record holding a paint, as a stroke is.** Every `fill` slot now takes a `Fill`, `{ paint?: Paint }`, where it took a bare paint: node data, draw commands (`CommandFill`), text styles and runs, and the affordance and overlay paint options. `fill: { color: '#abc' }` becomes `fill: { paint: { color: '#abc' } }`, beside `stroke: { paint: { color: '#000' }, width: 2 }`. `fill: null` still means no fill, and a fill with no `paint` paints nothing. `commandFill(fill, box)` resolves a node's fill for a draw command the way `commandStroke` resolves its stroke; resolving a bare paint is `commandPaint`.
|
|
182
|
+
|
|
183
|
+
**A paint names its variant under `kind`, not `fill`.** `{ fill: 'linear-gradient', … }` becomes `{ kind: 'linear-gradient', … }`, the word the paint-kind registry already used. A solid still omits it. `asPaint` takes `{ kind: string }`.
|
|
184
|
+
|
|
185
|
+
**Each built-in tile is its own paint kind.** `{ fill: 'pattern', pattern: { tile: 'hatch', color, lineWidth }, units }` becomes `{ kind: 'hatch', color, lineWidth, units }`, and likewise `crosshatch`, `dots`, and `chunks`. A tile a consumer rasterized itself is `{ kind: 'texture', texture: handle }`. `TilePatternSpec` is now a union keyed on `kind`, so a tile's own fields are checked instead of being optional on every tile. An SVG exported before this change carries its tiles in the old shape and loses them on import, with a warning.
|
|
186
|
+
|
|
187
|
+
Follows from the fill record: `DEFAULT_SHAPE_FILL` is a `Fill`, `createPathLayer`'s `getFill` returns a `CommandFill`, `setFill` and `setFillOpacity` write the record, and the default node properties describe `data.fill` as an object with one `paint` field, as `data.stroke` is. A node whose `fill` is a string or a bare paint now paints no fill. `SelectionPanel` built from those default properties no longer offers "None" for a fill, since it offers none for a paint nested in a record; clearing one goes through the `setFill` action.
|
|
188
|
+
|
|
189
|
+
A tile paint has a `color`, so `'color' in paint` no longer means solid. `isSolidPaint(paint)` answers that.
|
|
190
|
+
|
|
191
|
+
Renames: `FillStyle` is `Paint`, and `GradientUnits` is `PaintUnits`. The paint types named as fills are named as paints: `GradientPaint`, `MeshGradientPaint`, `CommandPaint`, `PosedPaint`, and `SolidPaint`, with `isGradientPaint` and `isMeshGradientPaint`. `isPatternSpec` is gone; `isTilePaint` and `isPatternPaint` replace it.
|
|
192
|
+
|
|
193
|
+
Adds API: `Fill`, `CommandFill`, `commandFill`, `PatternPaint`, `TilePaint`, `TexturePaint`, `TileKind`, `PatternPlacement`, `TILE_KINDS`, `isTileKind`, `isTilePaint`, `isPatternPaint`, `isSolidPaint`, `tileSpecOf`, `patternPlacementOf`, and `seedTile`. A paint kind can name a `family` (`PaintKindFamily`); kinds sharing one are a single segment in `PaintInput`'s kind bar, and the built-in tiles and `texture` share `patternFamily`.
|
|
194
|
+
- 87dd1ad: Fixes: `renderDebugSnapshot` threw "sourceRect.height must be a positive finite number" for a y-up view (`view.scale.y < 0`), so a flipped canvas could not be rasterized headlessly. It now renders what that canvas showed.
|
|
195
|
+
|
|
196
|
+
Changes behavior: `renderSceneToPixels`, `planPixelRender`, and a raster session's `render` take a negative `scale` axis, where they used to throw. A negative axis is flipped: the output is sized from the scale's magnitude, and the source rect's far edge on that axis lands on the output's top or left. `sourceRect` is unchanged, a positive-size rect either way, and a zero or non-finite scale still throws.
|
|
197
|
+
- 3bacb3e: Adds API: `useFrameClock(options?)` in `@weasel-js/react`, re-exported from `@weasel-js/core`. It returns a stable `{ seconds(), subscribe }` driven by `useVisibleRaf`: each frame notifies the subscribers and sets no React state, so a shader uniform or a procedural layer animates without its owner re-rendering. It has `subscribe`, so a `RenderLayer` names it as its redraw source (`subscribe: clock.subscribe`) and reads `clock.seconds()` in `draw`. The clock runs only while it has a subscriber, and leaves out time spent hidden or `paused`; `start` sets what it reads before the first frame. Added on an agent's judgment, to take the hand-written elapsed-time loop out of the custom shader demo.
|
|
198
|
+
- 6b03b7e: A behavior can do frame math. `GestureContext.frames` (`GestureFrames<TPose>`, new) takes a pose between the frame a node stores it in and world: `toWorld(id, pose)`, `toLocal(id, worldPose)`, `world(id)` for the pose the scene shows now, and `planeOf(layer)` for the parallax plane a layer is stored in. Move, resize, rotate, and clone set it; an insert and a lasso, whose poses belong to no node, leave it absent.
|
|
199
|
+
|
|
200
|
+
A move's `ctx.current` is the pose each dragged node would store, so `frames.toWorld(id, ctx.current.get(id))` is where it is in world. It used to be the stored pose shifted by the world drag, which is a different value for a node inside a turned or scaled frame, and a node carried by a frame that is itself dragged now reads its unchanged stored pose. Under the default composition, where stored and world are one value, nothing changes.
|
|
201
|
+
- b260415: geom: `mat3`, the `GlMat3` type, and `viewToMat3` live here now, moved from core's renderer. `@weasel-js/core/renderer` still exports all three. `mat3` works on the nine-element column-major matrix a GL uniform takes; geom's `Mat3` type and its free functions (`identity`, `multiply`, `invert`) remain the six-number affine.
|
|
202
|
+
- 66d5455: A group can join what is under it by any Porter-Duff operator. `GroupDrawCommand.composite` and `LayerGroup.composite` are new API, taking a canvas 2D operator name (`xor`, `destination-out`, `source-in`, `lighter`, `copy`, and the rest of that family) or a `{ source, destination }` pair of blend factors for an operator with no name. The types `CompositeOp`, `BlendFactor`, and `BlendFactors` are exported from `@weasel-js/renderer` and from core's barrel. A group with an operator other than `source-over` is isolated: its children draw into a buffer of their own and the operator applies once, to the finished surface, across the whole target inside the enclosing clip. The culler keeps such a group even when every child is off screen, because an empty source still changes the destination. The operator set and the factor-pair form were chosen on an agent's judgment.
|
|
203
|
+
- eb7f534: A hold can cover some of a target's axes. `animator.hold({ target, value, weight, axes })` holds only the axes it names; the rest are left to the target's other holds and its committed value, and releasing it commits only those. `SampledTrack.axes` does the same for a timeline track, and `jointAxes(skeleton, names)` answers the axes of a rig's joints, so an arm solved by IK can be held at full strength beside clips holding the body.
|
|
204
|
+
|
|
205
|
+
Each axis is shared among the holds that cover it: weights are summed and capped per axis, where they were summed across the whole value.
|
|
206
|
+
- 7548e82: Fixes: `useHostAnchor` did not follow a host that moved without resizing. It recomputed on scroll, on window resize, and on a size change of the host or the panel, so a sibling collapsing beside the host shifted it with none of those firing, and the dev HUDs stayed where the host had been. It now also watches the host's box for a move, with an `IntersectionObserver` framed around it.
|
|
207
|
+
- eb3114f: Fixes: a panel held by `useHostAnchor` could be left behind for good when its host moved several times in quick succession, or moved while wholly outside the viewport. After each move the hook rebuilds the frame it watches the host through, and a move that landed before the rebuilt frame's first report was taken for a host partly off screen and never reported. That first report is now checked against the box the frame was built around.
|
|
208
|
+
- 0a37db1: Fixes: a panel held by `useHostAnchor` stopped following a host that had no width or height when the hook began watching it. The watch now starts once the host has a size.
|
|
209
|
+
- a275f78: Adds API: a `hover` gesture, the pointer moving with no button pressed. `{ kind: 'hover', target?, mods?, phase? }` (`HoverSpec`) binds an immediate action that runs on every such move with `worldX` / `worldY`, `clientX` / `clientY`, `affordance`, `bodyTarget`, and `mods` in its params; `hover` is a route-grammar gesture name, and `HoverEvent` joins `InputEvent`. A coordinate readout, an eyedropper preview, or a ruler can follow the pointer through the dispatcher, with its modifiers, targets, modes, and views, where each used to attach its own `pointermove` listener.
|
|
210
|
+
|
|
211
|
+
A hover binding claims nothing, a rule chosen on an agent's judgment: every live `hover` binding that matches a move runs, the move is never canceled, and it still reaches the hover-cursor pump. An ongoing action bound to `hover` is refused with a console error, since there is no press for it to own. A held pointer's moves are its drag's and fire no hover. The gesture reports motion only; it does not say when the pointer leaves.
|
|
212
|
+
|
|
213
|
+
Adding a member to `GestureSpec`, `InputEvent`, and `GestureName` breaks a consumer's exhaustive `switch` or `Record` over any of them.
|
|
214
|
+
- 605ace8: The image cache holds a byte budget and drops what it can once a load takes it past. It kept every decoded bitmap, keyed by `src`, until `releaseImage` was called, and the kit never called it. It now holds 256MB of decoded RGBA by default: when a bitmap lands and the total is over, the least recently read images are released along with their GL textures. An image a live renderer drew in its latest frame is never dropped, nor one read since the previous bitmap landed, so a scene showing more than the budget stays over it instead of reloading on every paint. A dropped image loads again on its next read, which shows as one frame of placeholder for an image that scrolls back into view. `setImageCacheBudget(bytes)` is new API, exported from `@weasel-js/renderer` and core's barrel; it returns the previous value, and `Infinity` restores the old behavior. The default and the two exemptions were chosen on an agent's judgment.
|
|
215
|
+
- 0db7e81: Fixes: a translucent image was multiplied by its alpha twice. A half-transparent white bitmap on a cleared canvas read back as `(64, 64, 64, 128)` where `(128, 128, 128, 128)` is right, so every PNG with soft edges drew a dark fringe. A pattern tile registered from an `ImageBitmap`, which every built-in tile is, had the same fault, and one registered from an `<img>` painted differently from the same picture registered as an `ImageBitmap`.
|
|
216
|
+
|
|
217
|
+
Every image texture now holds premultiplied texels: an image command's bitmap, and a texture from `registerTexture`, whatever it was made from. The kit's shaders divide the alpha back out before a color matrix runs. Measured in headless Chromium by reading the framebuffer (`packages/renderer/src/imageAlpha.browser.test.ts`).
|
|
218
|
+
|
|
219
|
+
Breaking, in two places:
|
|
220
|
+
|
|
221
|
+
- A custom shader sampling a texture registered from an `HTMLImageElement` used to read straight texels and now reads premultiplied ones, as it always did for an `ImageBitmap`. Write `outColor = texture(u_image, uv)` where it had `vec4(c.rgb * c.a, c.a)`.
|
|
222
|
+
- An `ImageBitmap` handed to an image command or to `registerTexture` must hold premultiplied pixels, which is what `createImageBitmap` makes by default. One made with `premultiplyAlpha: 'none'` used to be the only kind that drew right and now draws too bright wherever it is translucent: the browser uploads a bitmap as it stands, and nothing reports which kind it is.
|
|
223
|
+
|
|
224
|
+
Opaque images are unchanged.
|
|
225
|
+
- 6bb8035: A canvas refuses a drag no content handler would claim, and leaves a paste none claims to the page. The `ingest` action asks the handler registry before it takes a drop or a paste; `clipboard.pasteEvent` asks its one handler, so on a canvas that edits and does not ingest, pasted text that is no copied node is no longer swallowed.
|
|
226
|
+
|
|
227
|
+
New API. `Action.enabled` takes a third argument, `carried`: the items of the drop or paste being routed, which the dispatcher passes in prediction and in dispatch. `ContentHandlerEntry.types` lets a handler with a predicate `match` say which MIMEs it could claim; a drag still in flight shows its MIMEs and no contents, so a predicate cannot be asked about it.
|
|
228
|
+
|
|
229
|
+
Behavior change for a consumer handler: while a registered handler has a predicate `match` and no `types`, no drag with a known MIME is refused, since it might take anything. Declare `types` to let the canvas refuse the rest. The kit's handlers declare theirs.
|
|
230
|
+
- 5d82ef9: `InsertPaint` may name a fill rule. This adds API: the object an `insertPaint` callback returns takes an optional `fillRule`, and a pencil trail, a pen path, a polygon, or a star inserted through it is built with that rule where it was always nonzero. A rect or an ellipse carries no rule and is unchanged, and a callback that names none behaves as before. Added on an agent's judgment, so WeaselDraw's "Path fill rule" preference has something to set.
|
|
231
|
+
- bc15034: A group command can be isolated, and a `LayerGroup` with `alpha` now fades as one surface. `GroupDrawCommand.isolate` is new API: the children draw into a buffer of their own and are composited once, so the group's `alpha` and `colorMatrix` apply to the finished picture and overlapping children no longer show through each other. A `LayerGroup` with an `alpha` under 1 or a `colorMatrix` and no `effects` is drawn that way, which is what its documentation already said; before, each member was faded on its own. This changes the pixels of any such group whose members overlap, and costs it a device-resolution buffer and one full-screen composite.
|
|
232
|
+
- 1ce19c9: Fixes: a tool hotkey fired while a `<select>` had focus, under the select's own type-ahead. The dispatcher now leaves a select its printable characters and its arrow, Home, End, and Page keys, and still takes Delete, Escape, and every modifier chord typed on one, so Cmd+Z works with focus resting on a select.
|
|
233
|
+
|
|
234
|
+
Changes behavior: `BandEditor` and `Timeline` asked their own question about a key's target, which counted a `<select>` as a text field. They now ask the dispatcher's, so Delete on a select inside a band merges the band, and Delete on a select inside a `Timeline` deletes the selected key. `x` and `l` on a select in a band are still the select's. This rule for `<select>` was chosen on an agent's judgment.
|
|
235
|
+
|
|
236
|
+
Adds API: `focusedControlOwnsKey(e)`, exported from `@weasel-js/gestures`, `@weasel-js/routing`, and `@weasel-js/core`: whether a key belongs to the control it was typed on. `isEditableTarget` and `activatesFocusedControl` now live in `@weasel-js/gestures` and are re-exported where they were.
|
|
237
|
+
- 7d94bbb: Adds API: `kitTextHandler`, a content handler that turns pasted or dropped plain text into a text node. The node's box is the string's laid-out size at the default text style, placed where the image handler places an image: on the drop point, or centered in the viewport for a paste. It runs below every other kit handler, so SVG markup and a copied node payload arriving as plain text still go to the handlers that read them.
|
|
238
|
+
|
|
239
|
+
No canvas registers it by default. Opt in with `<SceneCanvas ingestion={{ handlers: [kitTextHandler] }}>`. Sizing the box by measuring the string, and leaving the handler off by default, were decided on an agent's judgment.
|
|
240
|
+
- 1c9bc4e: Every overlay takes its `z-index` from the theme's layer ladder. Adds tokens: `--wzl-z-hud` (900), `--wzl-z-toast` (1100), `--wzl-z-popover` (1200), and `--wzl-z-drag` (10000). `Dialog`, `Toast`, `Tooltip`, `Callout`, core's debug HUDs, and labkit's drag ghost read a rung where each held a literal of the same value, and core's rungs carry that value as a fallback for a page with no theme.
|
|
241
|
+
|
|
242
|
+
Breaking: `--wzl-z-modal` is 1000, where it was 30 and below every dialog. labkit's lightbox, its one reader, rises with it. `DragGhost` in `@weasel-js/ui` moves from `--wzl-z-overlay` (20) to `--wzl-z-drag`, so a row dragged out of a list inside a `Dialog` draws over the dialog; the ghost `useDragHandle` clones reads the same rung.
|
|
243
|
+
- 525800f: Fixes: a line drawn with the line tool was inserted with a fill beside its stroke, so the Pathfinder actions, which count an operand as its stroke only when it has no fill, read it as its bare path: Unite of a rect and a line across it gave back the rect alone.
|
|
244
|
+
|
|
245
|
+
Changes behavior: a line is inserted with `fill: null`, as an open pen path already was, whatever the `insertPaint` option gives it. `paletteInsertPaint` now answers a stroke alone for a line.
|
|
246
|
+
- dcf0554: Fixes: `scene.loadState` kept a selected node the loaded snapshot puts on a locked layer, so `getSelection()` answered with a node `isLocked` called locked. It drops such ids now, as every other selection write does.
|
|
247
|
+
- 5c7d50f: Fixes: a long-press on a canvas with several views fired on whichever view had last taken input, not the view the press went down in. A touch held in one view while a mouse moved over another ran its `longPress` or `contextMenu` binding against the wrong view's dispatcher and context. The hold now fires on its own view, from its timer and from the `contextmenu` a platform sends for a hold.
|
|
248
|
+
- bb3e633: minimap: a new package over core, holding the minimap in both its forms. `createMinimapContribution` and `createLinkedCursorContribution` are the ambient entries; `<MinimapCanvas>` is the detached canvas; `minimapCenterAction`, `minimapPanAction`, `centerRootOn`, `MINIMAP_CENTER`, and `MINIMAP_PAN` are the actions both run; `createIndicatorLayer`, `createLinkedCursorLayer`, `crosshairRects`, and `CROSSHAIR_HALO` are the chrome; `computeFitView`, `computeIndicatorCommand`, and `FALLBACK_FIT_VIEW` are the fit math. It depends on `@weasel-js/react` and `@weasel-js/routing`, with `@weasel-js/core` and `react` as peers.
|
|
249
|
+
|
|
250
|
+
**Breaking for `@weasel-js/core`:** `MinimapCanvas`, `createMinimapContribution`, `createLinkedCursorContribution`, `minimapCenterAction`, `minimapPanAction`, `centerRootOn`, `MINIMAP_CENTER`, `MINIMAP_PAN`, `crosshairRects`, `CROSSHAIR_HALO`, `computeFitView`, `computeIndicatorCommand`, and `FALLBACK_FIT_VIEW`, with their types (`MinimapCanvasProps`, `MinimapContributionOptions`, `LinkedCursorOptions`, `CrosshairRect`, `ComputeFitViewOptions`, `IndicatorStyle`, `MinimapFit`), are no longer exports of `@weasel-js/core`. Import them from `@weasel-js/minimap`. `@weasel-js/labkit/weasel-canvas` still re-exports the ones it did.
|
|
251
|
+
|
|
252
|
+
core: `accentColorOf` and `FALLBACK_ACCENT` are exported. `accentColorOf(el)` reads `--wzl-accent` off an element, where the theme cascade lands on a canvas.
|
|
253
|
+
- be611ae: Fixes: "is this tool allowed in this mode" had two answers. `ToolPalette` and a tool's activation key allowed a tool when any one of its capability tags was allowed and refused a tool with no tags, while the dispatcher required every tag and let an untagged tool through. A tool tagged `['navigation', 'creates-shapes']` in a mode without `creates-shapes` showed enabled, activated, and then had every binding dropped; an untagged tool was grayed out yet live once active.
|
|
254
|
+
|
|
255
|
+
Changes behavior, on the dispatcher's rule: a tool or contribution is allowed when the mode allows every one of its tags, and one with no tags is allowed in every mode. So `eligibleForMode`, `eligibleTool`, and `eligibleContribution` now return `true` for an empty tag list and `false` for a list with one disallowed tag, and `ToolPalette` and the activation keys follow. Which rule wins was chosen on an agent's judgment: a tag names something the tool does, so one refused tag refuses the tool.
|
|
256
|
+
|
|
257
|
+
Adds API: `capabilitiesAllowed(allowed, tags)` in `@weasel-js/modes`, the one predicate the palette, the activation keys, and the dispatcher all ask.
|
|
258
|
+
- ca09ae2: A `modifierHeld` rule now matches on a `<SceneCanvas>`. The canvas reported no modifier key as held, whatever the keyboard said, so a `chromeVisibility` rule or an action's eligibility written with `modifierHeld('shift')` never applied. It now reads the keys held anywhere in the window, a focused text field included, and repaints when one goes down or up.
|
|
259
|
+
- 33c90ed: A layout drop and reparent-on-drop are now move behaviors. The move action builds both for each drag and runs them after the binding's own: the layout drop when the `layout` dep is present, then reparent-on-drop. Neither is exported; a layout is still configured on its container and reparenting by the binding's `reparentOnDrop` param. `docs/extending.md` ("Move behaviors") lists the whole chain.
|
|
260
|
+
|
|
261
|
+
What a consumer can observe:
|
|
262
|
+
|
|
263
|
+
- `MoveEnd` gains `pointer`: where the pointer was let go, in world coordinates, or the last move's point when the release carries none. Code that calls a `MoveBehavior`'s `onEnd` directly, such as a consumer's own test, must now pass it: `{ answered, translateOps, pointer }`. `ctx.pointer` still holds the last move's point.
|
|
264
|
+
- A layout strategy that throws mid-drag drops that frame, the way a throwing binding behavior does. The release then commits the last frame that held, as a plain move. It used to commit the throwing frame's position.
|
|
265
|
+
- With a reflow transition, a binding behavior's `onSettled` now runs before the layout drop settles its glides, where it ran after.
|
|
266
|
+
- Every behavior's `onEnd` now runs even when an earlier one throws, for move, resize, rotate, insert, and lasso-select: the same guarantee `onSettled` and `onCancel` have. The ones after the throw are told `end.answered`, nothing commits, and the first error is rethrown once all have run. A behavior that releases something in `onEnd` used to be skipped.
|
|
267
|
+
|
|
268
|
+
`committed`, as `onGestureEnd` and `onSettled` report it, now says whether the ops landed, wherever a gesture commits ops: every commit of a move, resize, or rotate, and an insert whose behavior answered with ops. An insert no behavior claims still commits through the `insert` dep, and reports whether that minted a node.
|
|
269
|
+
|
|
270
|
+
- `scene.applyBatch` returns a boolean: `false` when a container's layout refused what the batch dropped into it, which reverts the batch and records nothing. That holds while a journal is taking the scene's batches. Inside `scene.batch` it returns `true`, since the enclosing batch owns the outcome and may still refuse.
|
|
271
|
+
- A layout drop the destination refuses reports `committed = false`. It reported `true`, and threw `SceneArrivalRefused` out of the gesture when the move was transient.
|
|
272
|
+
- A refused arrival on the transient route no longer throws `SceneArrivalRefused`: not out of a transient move, resize, or rotate, not out of an insert's behavior-answered commit, and not out of a move behavior's own later `ctx.adapter.applyOps`, such as `momentum` landing its coast. It lands nothing and returns.
|
|
273
|
+
- A consumer `applyOps` hook is still taken at its word: a commit handed to it reports `true`.
|
|
274
|
+
|
|
275
|
+
Fixed: a layout container inside the dragged subtree no longer takes the drop. A short drag of a group holding one could pick it, since it is tested where the document still holds it, and the commit then tried to reparent the group under its own descendant.
|
|
276
|
+
- 8d0498c: A move with `reparentOnDrop` now commits as ops (`reparent`, `setLayer`, `transform`) like every
|
|
277
|
+
other move commit, so it reaches a consumer's `applyOps` hook and history. It used to write to the
|
|
278
|
+
scene directly and bypass both. A consumer with its own history that relied on reparent drops
|
|
279
|
+
landing in the scene's history will now receive them instead.
|
|
280
|
+
- b3d4383: Additive: `InvocationCtx.multiTouch.rotation` is real. It was always 0; it is now the degrees the two primary fingers have turned since the gesture began, clockwise positive, and it keeps counting past a half turn. `MultiTouchEvent` carries the `angle` it is computed from, and `multiTouchGeometry` returns it beside the centroid and spread. An action that read `rotation` and relied on the 0 now sees the turn.
|
|
281
|
+
- a6dff38: Adds API, and breaks one read: a number leaf's `unit` may be data. `PrefLinearUnit` is `{ suffix?, scale, offset?, accepts?, precision? }`, where `stored = display * scale + offset`, the direction a `UnitEntry` runs toward its base, and `{ scale: 1 }` changes nothing. `PrefFunctionUnit` is the `toDisplay`/`fromDisplay` form, kept for a conversion that is not linear, and `PrefNumberUnit` is either. `resolvePrefUnit(unit)` gives `toDisplay`, `fromDisplay`, and `format` for both, and `isPrefLinearUnit` tells them apart.
|
|
282
|
+
|
|
283
|
+
Breaking: `prefUnit` now returns the data form, so `prefUnit(...).toDisplay` and `rotationDegreesUnit.toDisplay` are gone, and reading `leaf.unit.toDisplay` no longer typechecks. Call `resolvePrefUnit(leaf.unit).toDisplay` instead. `prefDisplayBounds`, `prefFieldProps`, and with them `PrefsForm`, `SelectionPanel`, and labkit's `ControlPanel` already do.
|
|
284
|
+
|
|
285
|
+
A data unit prints in `printSchema`'s literal in full, where a unit of functions prints as `KEEP_FROM_SOURCE`, and a draft keeps one set on a leaf the source schema does not hold. `PrefSchemaEditor` offers it on a number, and on a list's number entry, as a Unit attribute: suffix, scale, offset, places, and the suffixes it also takes. A unit of functions is still listed there as code.
|
|
286
|
+
- 27c1c86: Canceling a tween, spring, or coast on a target that has a hold no longer moves the value on screen. What the canceled animation had left to travel was added to the committed value, which a hold stands in front of, so at full weight it vanished. It now stays on screen beside the hold. It is committed when the target's last hold is released, taken up by the next tween or spring given a destination, and dropped by `target.stop({ commit: false })`.
|
|
287
|
+
|
|
288
|
+
**This changes when `set` is called**: for an animation canceled under a hold, the target's `set` runs as the last hold leaves, not at the cancel.
|
|
289
|
+
- 54b013c: Removes what was left of tools running their own gestures. A tool declares bindings to actions, and nothing called these any more.
|
|
290
|
+
|
|
291
|
+
Breaking, for code that used them:
|
|
292
|
+
|
|
293
|
+
- `ToolCtx` is gone from `@weasel-js/routing` and `@weasel-js/core`. An action reads its `InvocationCtx`.
|
|
294
|
+
- A function passed as `Tool.cursor` or `ToolDef.cursor` takes no argument: the type is `CursorSpec | (() => CursorSpec)`. A cursor that depends on the tool's state closes over that state. Before, the function was handed a context whose pointer position was always `0, 0` and whose modifiers were always up.
|
|
295
|
+
- `Tool.previewPose`, `Tool.previewBounds`, and `Tool.previewIds` are gone, and a canvas no longer asks its tools for a preview. An in-flight preview comes from the action's `OngoingHandle` (`previewIds`, `previewPose`, `previewData`), which is where the kit's actions publish theirs. `CanvasHelpers.getPreviewSources()` returns those handles alone.
|
|
296
|
+
- `Tool.initScratch` and `ToolDef.initScratch` are gone, and so is `ToolLifecycleCtx`. `onActivate` and `onDeactivate` take no argument; before, they were handed `{ scratch }`, the value `initScratch()` returned. A tool that keeps state between gestures holds it itself and closes over it, as the pen does.
|
|
297
|
+
- `Tool`, `ToolDef`, and `defineTool` lose their scratch type parameter. In `@weasel-js/core` none of them takes a type argument: `Tool<null>` becomes `Tool`, and `defineTool<null>({ … })` becomes `defineTool({ … })`. In `@weasel-js/routing` the one parameter left is the overlay type: `Tool<TOverlay>`, `ToolDef<TOverlay>`, `defineTool<TOverlay>`.
|
|
298
|
+
- `AnyToolOf<TOverlay>` is gone from `@weasel-js/routing`; `Tool<TOverlay>` is the same type.
|
|
299
|
+
- `ToolPresentation` takes no type parameter, and a function passed as `presentation.icon` takes no argument. The palette only ever called it with `undefined`.
|
|
300
|
+
|
|
301
|
+
Adds API: `CanvasExtensionApi.clientToWorld(clientX, clientY)` converts a client point to the canvas's world the way the canvas itself does, through the `clientToWorld` prop when one was given. Fixes a `<Canvas>` given that prop disagreeing with itself: hover used the override, and the test for whether a registered layer covers a point inside a `<CanvasView>` did not.
|
|
302
|
+
- a8ef308: The three drag ghosts mount in one place. `fixedSeat(from)` in `@weasel-js/gestures` answers where a `position: fixed` element following the pointer mounts (the nearest themed or `data-wzl-portal-host` ancestor of `from`, else the body) and the client point its corner lands on when that host contains its fixed descendants. `nearestPortalHost` moved there from ui, which still exports it.
|
|
303
|
+
|
|
304
|
+
- core: the default `useDragHandle` ghost mounts in the source's host, where it mounted on the body, so it resolves the source's theme and draws in its font.
|
|
305
|
+
- ui: `<DragGhost>`'s `at.width` is optional; with none the ghost is as wide as what it holds.
|
|
306
|
+
- labkit: a palette drag's ghost is ui's `<DragGhost>`, so it takes the lab's theme. **Breaking:** `DragState` and `DragGhostProps` gain a required `from`, the element the drag began on, and the ghost loses its own border.
|
|
307
|
+
- 5996856: core: an undo entry now holds the scene's own ops whichever way the edit was made. `scene.applyBatch`, `scene.history.apply`, and a scene journal record the `kit:*` ops their ops caused, and beside them any op that wrote no scene state, such as a selection change. Undo and redo of such an entry restore what was written and no longer call the adapter the batch was applied with.
|
|
308
|
+
|
|
309
|
+
Breaking:
|
|
310
|
+
|
|
311
|
+
- `scene.carry` is removed. A pose an adapter writes beside the one it was asked for is an ordinary `scene.setPose`, and the entry holds it.
|
|
312
|
+
- `scene.applyBatch` inside `scene.batch` joins that batch's entry. It used to push an entry of its own ahead of the batch's.
|
|
313
|
+
- A journal opened on a history other than the scene's reverts in place. Its undo, redo, and cancel used to replay through the adapter and leave `setPose` and `update` entries on the scene's undo stack.
|
|
314
|
+
- `scene.serializeHistory()` returns a `SerializedSceneHistory`, which carries `form: 2`, and `scene.restoreHistory` drops a snapshot without it. A history persisted by an earlier version is not restored.
|
|
315
|
+
|
|
316
|
+
history: an `Op` may define `caused()`, which names the ops its entry records in its place once it has applied. An entry's `touchedIds` now also reads `args.nodes[].id`.
|
|
317
|
+
- 0d1c052: The scene's adapter is the only adapter the kit builds. A flat list of items is a scene (`useScene({ items })`), read and written through `useSceneAdapter(scene)` like any other, so the separate array adapter is gone.
|
|
318
|
+
|
|
319
|
+
**Breaking:**
|
|
320
|
+
|
|
321
|
+
- `arrayAdapter`, `useArrayAdapter`, and the types `ArrayAdapter`, `ArrayAdapterConfig`, `ArrayPoseTargets`, and `UseArrayAdapterOptions` are removed. Replace `useArrayAdapter({ items, setItems, toPose })` with `useScene({ items })` and `useSceneAdapter(scene, { selection })`. The scene owns the list from then on: read it from `scene`, and what is written through the adapter is undoable. For a store the kit cannot own, write the adapter by hand against the slices its readers take (`docs/adapters.md`), with `createWrittenPoseTarget` for its `poseTarget`.
|
|
322
|
+
- The `SceneAdapter` interface is removed. Nothing implemented it: it required a `hitTest` no adapter had. Name the slice a reader takes (`MoveAdapter`, `PoseAnimationAdapter`, …), or `SceneCanvasAdapter` for the whole of what `sceneToAdapter` returns.
|
|
323
|
+
- The scene slot always paints the adapter's tree, one canvas layer per scene layer. It no longer falls back to painting `getNodes()` flat for an adapter without `getLayers`, `getNode`, and `getChildren`, and `CanvasProps['adapter']` requires all three. `SceneSlotConfig.objects` still paints a list of your own in place of the tree.
|
|
324
|
+
- 71512af: Changes behavior: a controlled `<SceneCanvas view viewBounds>` now hands `onViewChange` a view clamped to `viewBounds`, as an uncontrolled one already did. It used to report the raw view for a pan, zoom, or animation frame, leaving the consumer to clamp. The canvas now holds its view in one place; it kept a second copy with a hand-written controlled fork that skipped the clamp.
|
|
325
|
+
|
|
326
|
+
Also changes: a controlled view repaints when its numbers change, not when the `view` object's identity does, and a write to an uncontrolled view made before the canvas mounts is applied.
|
|
327
|
+
|
|
328
|
+
Breaking: `SceneCanvasProps` loses `previewIdsExtra` and `pickBest`, which were never `<SceneCanvas>`'s own and were reachable only through the internal canvas's prop type. `CanvasProps`, the prop type of that unexported component, takes a required `viewState` and already-built `layers`, and drops `view`, `defaultView`, `onViewChange`, `viewBounds`, `pickEvery`, `pickBest`, `previewIdsExtra`, and the three dev HUD flags. The HUD flags on `<SceneCanvas>` work as before.
|
|
329
|
+
- 54174b6: Fixes: SVG import and export, the booleans, and the renderer's mesh cache disagreed with a path whose open subpaths no fill closes (`openFill: 'none'`, or `setDefaultOpenFill('none')`).
|
|
330
|
+
|
|
331
|
+
- `parseSvg` stamps `openFill: 'close'` on a `<polyline>` or `<path>` with an open subpath, since SVG always closes one to fill it. Such a path now carries a field it did not, and keeps painting under a `'none'` default.
|
|
332
|
+
- `serializeSvg` writes open subpaths no fill closes with `fill="none"`. A path mixing closed and open subpaths is written as a `<g>` of two `<path>`s, the group carrying the node's opacity, rotation, and metadata, so it reads back as a group of two.
|
|
333
|
+
- `pathUnion`, `pathIntersect`, `pathSubtract`, `pathExclude`, `pathDivide`, and the slice cuts leave such an open subpath out of the region. This changes their result for a path that says `'none'`.
|
|
334
|
+
- A mesh the renderer cached under one default rule is rebuilt after `setDefaultOpenFill` changes it, so the default no longer has to be set before the first paint.
|
|
335
|
+
|
|
336
|
+
Adds API: `splitByClosure(path)` and `hasOpenSubpath(path)` in `@weasel-js/geom`, re-exported from `@weasel-js/core`.
|
|
337
|
+
- 4edad85: Fixes: a filled path with an open subpath painted and could not be clicked. `tessellate` and `pathSignedArea` closed the subpath, and `pointInPath`, `pathContainsRect`, `pathIntersectsRect`, and the polygon tests ignored it. All of them now ask the path.
|
|
338
|
+
|
|
339
|
+
Adds API: `PolygonPath.openFill`, `'close'` (a fill closes an open subpath with a straight edge back to its start, as SVG and canvas do) or `'none'` (an open subpath never fills), and `setDefaultOpenFill(rule)` / `defaultOpenFill()` in `@weasel-js/geom` for a path that names neither; the default starts at `'close'`. `fillsOpenSubpaths(path)` is the one answer. Set the default before anything is painted: a mesh already built keeps the rule it was built under.
|
|
340
|
+
|
|
341
|
+
Changes behavior: the filled-region hit tests now count an open subpath of three or more points as closed, so such a path is picked across the area its ends enclose. A node whose painter reports unfilled ink is still picked on its outline only. A marquee or lasso reads that ink too: it meets the open subpaths of a node painted with no fill only where it touches the stroke.
|
|
342
|
+
|
|
343
|
+
Fixes: `editAnchorSet` returned a path with `fillRule: 'nonzero'` whatever the path it was given said. It, `reversePath`, `splitSubpaths`, the path transforms, the pen's continue and join, and the rig's skinned path now hand back a path with the fields of the one they were given. `anchorsToPath` takes that path as an optional third argument.
|
|
344
|
+
- bb53d86: Outline Stroke, and Boolean operations that can count an operand's stroke.
|
|
345
|
+
|
|
346
|
+
Adds API: the `outlineStroke` action (`outlineStrokeAction`, in the `pathfinder` group, part of the `paths` feature) and `applyOutlineStroke` replace each selected stroked path with the region its stroke covers, filled in the stroke's paint; a node that is also filled keeps its fill as a path of its own underneath, grouped with the outline when the adapter mints containers. It runs through the `createOutlinesAdapter` dep, which gains optional `getWorldPath` and `getPaint`; an adapter without them leaves the action disabled.
|
|
347
|
+
|
|
348
|
+
Adds API: `applyBooleanOp` and `useBooleans` take `strokes`: `'ignore'` (the default, and what every operation did before), `'unfilled'` (an operand with a stroke and no fill is the region its stroke covers), or `'include'` (every operand is what it paints, fill and stroke together). `BooleansAdapter` gains optional `getPaint`, which either mode needs, and `createPathNode` is passed a fourth argument, `paint`, when the topmost source's stroke went into the result's shape: the result must wear that paint and not the source's stroke again. Changes behavior: the built-in Pathfinder actions pass `'unfilled'`, so a line or an open pencil stroke with no fill is now an operand by the ink it draws, where it used to be the unseen region its path encloses; an adapter without `getPaint` behaves as before.
|
|
349
|
+
|
|
350
|
+
Adds API: `PathPaint` and `pathPaintOf`, the resolved fill and stroke of a node that keeps them in `data.fill` and `data.stroke`, as the built-in path painter reads them.
|
|
351
|
+
|
|
352
|
+
Changes API: `CreateOutlinesAdapter.createPathNode` is passed a `Path` where it was passed a `PolygonPath`, since a filled node's own path can be a rect.
|
|
353
|
+
- 18920a4: Outline Stroke works on stroked text. A selected text node that wears a stroke, its own or one of its runs', is replaced by its glyph outlines by paint, with each stroke as a path of its own over the glyphs it outlined, where it used to be passed over until Create Outlines had run. Text with no stroke stays text. The action is enabled on stroked text, and waits for a face's outlines to load as Create Outlines does.
|
|
354
|
+
|
|
355
|
+
New in the API: `applyOutlineStroke` can answer `{ kind: 'failed', reason: 'text-outlines', error }` when a stroked text's face has no outlines, changing nothing, so a `switch` over `OutlineStrokeResult` has one more case.
|
|
356
|
+
- 9b8bd89: Fixes: `useNodeOverlayFrame` applied a pose's rotation and left out its `transform`, so DOM chrome over a skewed or stretched node, the gradient handles among them, sat on the unstretched box. `toScreen` and `toLocal` now go through the pose's whole frame, and the hook answers `null` for a pose whose `transform` is singular, which draws nothing.
|
|
357
|
+
- efc1205: Adds API: a pose override can carry a `path`. `scene.overrides.set(id, { pose, path })` makes the node paint and be picked by that path in place of the one in its data, with no document write, as an override's `pose` and `alpha` already work. `kit:path` and `kit:derived` nodes honor it, and an override path wins over a derived one. The path is in the frame a painter draws in, so give `pose` beside it as the path's bounds with no rotation. A view painting through its own `toPose` does not see it.
|
|
358
|
+
- b4227bc: core: a paint kind's draw slots are their own type now. `PaintDrawKind` holds `id`, `bind`, `inPoseFrame`, `toBoundsFrame`, and `programs`, and `PaintKindEntry` extends it with the slots an editor and a serializer read. `registerPaintKind` takes the same single object as before, and every other paint-kind export keeps its name and shape.
|
|
359
|
+
- 6139898: parallax: a new package over core, holding the paint-side parallax and tiling layers. `createParallaxLayer` draws render layers through a derived view, `createParallaxPlane` is the live plane a camera or an animator drives, and `createTiledLayer` with `tiledProject` repeats its sources across a period. It depends on `@weasel-js/registry`, with `@weasel-js/core` as a peer, and has no React.
|
|
360
|
+
|
|
361
|
+
**Breaking for `@weasel-js/core`:** `createParallaxLayer`, `createParallaxPlane`, `createTiledLayer`, and `tiledProject`, with their types (`CreateParallaxLayerOpts`, `ParallaxSource`, `ParallaxPlane`, `CreateTiledLayerOpts`, `TileBleed`, `TilePeriod`, `TileRange`), are no longer exports of `@weasel-js/core`. Import them from `@weasel-js/parallax`.
|
|
362
|
+
|
|
363
|
+
The parallax math stays in core, which a scene layer's own `parallax` uses: `deriveParallaxView`, `planeMap`, `toPlane`, `fromPlane`, `rectToPlane`, `rectFromPlane`, `planeToPlane`, `planeMatrix`, and the types `ParallaxOpts`, `ScalarOrXY`, and `PlaneMap`.
|
|
364
|
+
- 335f192: geom: the path anchor model and the small shape builders live here now. That is `pathToAnchors`, `anchorsToPath`, `countPathAnchors`, `isAnchorSmooth`, `nearestSegmentT`, and the `PenAnchor` type, plus `circlePath`, `squarePath`, `rectMarkerPath`, and `roundRectPath`. `@weasel-js/core` still exports every one of them. New from geom: `segmentEnds` and `isStraightSegment`.
|
|
365
|
+
- f3b977a: `<SceneCanvas pathEdit>` hands which path is being anchor-edited to the host. This adds API: the `pathEdit` prop and its `PathEditHost` type, `{ editingId(), setEditingId(id) }`. Given one, the canvas keeps no editing id of its own. It reads `editingId()` wherever it needs the open path, and the `enterPathEdit` and `exitPathEdit` actions call `setEditingId`. A host whose own state already names the open path, such as a mode machine holding a path-edit mode's target, passes it so the two cannot disagree. Without the prop the canvas owns the id as before. Added on an agent's judgment.
|
|
366
|
+
- df159bc: Fixes: deselecting or deleting a node while its anchors were being edited left the anchors drawn but ungrabbable, kept shift-click from extending the selection, and made a drag on an anchor move the whole node. Whether a node is in anchor editing is now decided in one place: it exists, it is selected, and the mode allows it. The overlay, the selection outline, the chrome rules' `editingAnchors`, hit-testing, and the shift-click lock all read that answer. Selecting the node again resumes editing.
|
|
367
|
+
|
|
368
|
+
Changes behavior: an editing id supplied through `pathEdit` is held to the same rule, including the mode check, which the canvas used to skip for a host's id.
|
|
369
|
+
- 485bb80: Trim and Merge are Boolean operations. Trim cuts each selected shape back to the part of it left showing under the shapes in front; Merge does the same, then unites the pieces whose sources wear the same fill. New API: `'trim'` and `'merge'` in `BooleanOp`, `trim()` and `merge()` on `useBooleans`, the `pathfinder.trim` and `pathfinder.merge` actions (`pathfinderTrimAction`, `pathfinderMergeAction`, registered with the `paths` feature and shown in the `pathfinder` action group), and `TrimIcon` and `MergeIcon`.
|
|
370
|
+
|
|
371
|
+
Each result is minted from its own source, as a Divide's pieces are. Merge compares fills as `BooleansAdapter.getPaint` reports them, or the stroke's paint for an operand whose stroke was counted in; an operand the adapter reports no paint for is united with nothing, so Merge on an adapter without `getPaint` is a Trim. Strokes are otherwise left as the adapter paints them: unlike Illustrator's, this Trim does not strip them.
|
|
372
|
+
|
|
373
|
+
A `Record<BooleanOp, …>` in consumer code needs the two new keys. The two glyphs were drawn on an agent's judgment.
|
|
374
|
+
- 21b6db7: Adds API: a plane's axes can carry different units. `resolveAxes(value, units)` in `@weasel-js/quantity` resolves one value for both axes, or `{ x, y }`, against one `UnitSystem` or one per axis (`PlaneUnits`), and `formatAxes` writes a base-unit point back out with each axis in its own display unit. `axisUnits`, `PerAxis`, `PlaneUnits`, and `PlaneValue` are exported beside them, and all are re-exported from `@weasel-js/core`.
|
|
375
|
+
|
|
376
|
+
`gridSnapStrategy`, `pointToGridCell`, `createGridLayer`, `createCellHighlightLayer`, and `useGridCellHover` take a per-axis `spacing` and `unitSystem`, so a grid can be 1s wide and 5mV tall. A single value still means a square grid.
|
|
377
|
+
- 970f489: Fixes: picking a node whose pose carries a `transform` measured the grab tolerance in the node's own frame, so a node stretched four times as wide could be picked four times as far from its edge, and a screen slop was stretched the same way. A world tolerance, the default path slop, and a screen slop are now all measured where they are stated, through the node's whole frame. A `PoseSlop`'s `reach` stays in the node's frame, where the stroke it stands for is drawn.
|
|
378
|
+
- af48ee3: A behavior's `ctx.pointer.clientX` / `clientY` are the client point of the event, where every default action used to fill them with `0`. Move, resize, rotate, insert, and lasso-select read them from `InvocationCtx.screen`.
|
|
379
|
+
|
|
380
|
+
Breaking for a behavior that read them as numbers: `PointerState.clientX` and `clientY` are optional now, absent when the event carried no client point (a keystroke, a UI-driven trigger, a synthetic probe). Chosen on an agent's judgment over removing the fields.
|
|
381
|
+
- 1c8c3fc: Pointer gesture recognition moved out of `useGestureDispatcher`'s effect into `createPointerRecognizer` in `@weasel-js/gestures`. It takes pointer samples and a clock, and emits `InputEvent`s to a sink: the press and the drag it becomes past `DRAG_THRESHOLD_PX`, click, double click, long-press with its contextmenu fallback, and multitouch start, move, end, and tap. It has no DOM, so its timings can be tested with a fake clock.
|
|
382
|
+
|
|
383
|
+
Additive in `@weasel-js/gestures`: `createPointerRecognizer` and its types, `clickEvents`, `longPressEvents`, `multiTouchGeometry`, `stylusOf`, and the thresholds `LONG_PRESS_MS`, `DOUBLE_CLICK_MAX_MS`, `DOUBLE_CLICK_MAX_PX`, and `TAP_THRESHOLD_PX`. `@weasel-js/routing` still exports `LONG_PRESS_MS`, and adds `multiTouchGestureId` beside `pointerGestureId`.
|
|
384
|
+
|
|
385
|
+
What a consumer of `useGestureDispatcher` can observe:
|
|
386
|
+
|
|
387
|
+
- `requestRedraw` follows the dispatcher's own notifications. It now also fires when a gesture in flight is ended or stepped by something other than an input event through the hook: the cancel a tool switch makes, `Dispatcher.cancelAll`, a UI-driven ongoing action. A canceled marquee no longer stays painted until the next redraw.
|
|
388
|
+
- A double click is timed on `performance.now()`, as long-press and multitouch tap already were, where it used `Date.now()`.
|
|
389
|
+
- The platform that decides whether `mod` means Command is read when the hook mounts, not when the module loads.
|
|
390
|
+
- The hover cursor's `keydown`/`keyup` listeners on `window` attach only when the pointer channel is on.
|
|
391
|
+
- A click is decided by whether the press crossed the drag threshold. The hook used to also ask whether a `pointer-<id>` handle was in flight; nothing the hook does opens one before the threshold, so only code calling `handleInput` on the hook's dispatcher with its own pointerdown could have seen the difference.
|
|
392
|
+
|
|
393
|
+
Tool `onActivate` / `onDeactivate` run from their own hook beside the tool registry, in the same order as before: the outgoing tool's `onDeactivate`, the cancel of in-flight gestures, then the incoming tool's `onActivate`.
|
|
394
|
+
- 4d4d81c: Adds axis names to the kit's own targets, so a hold or a track on one can say `axes: ['y']` where it had to say `axes: [1]`. A rect pose's axes are `x`, `y`, `width`, `height`, and `rotation`; a rect path pose's are the first four; the view's are `x`, `y`, `scale.x`, and `scale.y`, so `'scale'` names both. A polygon path pose's axes are its coordinates and stay indexes.
|
|
395
|
+
- ea54a64: geom: the box-pose frame math lives here now: `poseFrameOf`, `poseFrameInverseOf`, `poseLinearOf`, `pathThroughPoseFrame`, `poseRotationOf`, and `rotatePathAround`, with the `PoseLinear` and `PoseRotation` types. They read a pose as plain numbers and need no scene. `@weasel-js/core` still exports every one of them.
|
|
396
|
+
- 8524e05: core: `scene.overrides.hold()` hands out a `PoseHold`, a writer's claim on some nodes' pose overrides. `hold.set(poses)` publishes a whole frame with one notification and releases any id the frame leaves out, `hold.others()` answers the poses other writers are publishing, and `hold.drop()` releases what the hold still owns, leaving alone an entry another writer has since replaced. Move, rotate, resize, and `usePoseRun` publish their previews through it. `PoseHold` is exported, and `PoseOverrides` gains the `hold` method, so a hand-written `PoseOverrides` has to supply one; `createPoseOverrides` builds a complete table.
|
|
397
|
+
- 8ac6236: Two moves on one node now combine. `tweenPose`, `springPose`, `animateOnSetPose`, `animateLifecycle`, the reflow glide, and `momentum` move the node's pose target, where they used to each write a pose every frame and the last writer won.
|
|
398
|
+
|
|
399
|
+
**This changes behavior on a scene-backed adapter** (`sceneToAdapter`, `useSceneAdapter`, the one `<SceneCanvas>` builds):
|
|
400
|
+
|
|
401
|
+
- `tweenPose` and `springPose` write the destination to the scene as the move starts. The scene's pose is the destination for the whole move, and the node on screen travels there through `scene.overrides`. `setPose` is no longer called each frame, so the scene's version and history do not change per frame. Read the pose on screen with `effectivePose(scene, node)`.
|
|
402
|
+
- A second `tweenPose` on a node no longer cancels the first. Both run under `pose:<id>` and add. `springPose` interrupts every move on its node and starts at their combined velocity.
|
|
403
|
+
- Canceling a move leaves the scene at the pose the node was shown at, not at the destination.
|
|
404
|
+
- A move undone mid-flight ends there: at the next frame the node shows the undone pose and nothing is left running. The same goes for anything else that writes a node's pose while it is moving.
|
|
405
|
+
- `target.stop({ commit? })` stops every animation on a target. By default each commits where it was; `commit: false` leaves the committed value as it stands.
|
|
406
|
+
- `animateOnSetPose`: the scene takes each written pose at once. A second write to a node mid-glide bends the glide (or, with `spring`, carries its velocity) where it used to end the glide and snap.
|
|
407
|
+
- `animateLifecycle`: the enter pose is shown and never written, and a node shrunk out is removed at the pose it had, so undoing the removal restores it whole.
|
|
408
|
+
- Reflow glides: a timed retarget adds to the glide still running, and no longer restarts from the pose on screen. A `spring` retarget keeps the node's velocity.
|
|
409
|
+
- `momentum` coasts on the node's pose target. The document still takes the flick as one transform when it comes to rest.
|
|
410
|
+
|
|
411
|
+
An adapter without `poseTarget`, and a pose its descriptor gives no axes for, behave as before: `setPose` each frame, and a new move cancels the one running. `pathPoseDescriptor` and `AUTO_POSE_DESCRIPTOR` give a `Path` pose axes, a polygon's being its coordinates, so a path moves on its target between two shapes with as many points.
|
|
412
|
+
|
|
413
|
+
A container under `cascadeContainerPose` moves on its target too. Its descendants' poses are written with it as the move starts, and each is shown traveling beside it through an override of its own; `scenePoseTarget` takes a `cascade` (`PoseCascade`) that says how.
|
|
414
|
+
|
|
415
|
+
New API:
|
|
416
|
+
|
|
417
|
+
- `createPoseTarget({ id, get, set, overrides, descriptor? })` makes the target for one node's pose, and `scenePoseTarget(scene, id, descriptor?)` returns the one a scene keeps per node. Animations given it as `target` add to everything else moving that node.
|
|
418
|
+
- `MoveAdapter.poseTarget?(id, descriptor?)` is how an adapter hands that target to the helpers.
|
|
419
|
+
- `PoseDescriptor.axes?(like)` says how a pose maps to numbers and which are angles. `RECT_POSE_DESCRIPTOR` maps `x`, `y`, `width`, `height`, and `rotation` as an angle, so a rotation tweens the short way round.
|
|
420
|
+
- `interrupt: false` on a targeted `tween`, `spring`, `physics`, or `decay` takes a `cancelKey` without canceling the animations holding it.
|
|
421
|
+
- `publish` on `createTarget`: called once a frame for all the targets sharing it. A target's `show` is now also called as an animation starts on it.
|
|
422
|
+
- `tweenPose` takes `from`, where the move appears to start. `tweenPose` and `springPose` accept any adapter with `getPose` and `setPose` (`PoseAnimationAdapter`), so the adapter from `useSceneAdapter` needs no cast.
|
|
423
|
+
- eafd001: Fixes: a pre-built layer (`{ layer }`) in `<SceneCanvas layers>`'s `selectionOverlay` slot typechecked and was never painted; the kit's own overlay was built from the defaults instead. It now paints in the overlay's place, with no rotate badge of the kit's.
|
|
424
|
+
|
|
425
|
+
Adds API: the `scene` slot takes a pre-built layer too, which paints the scene in place of the per-layer canvas layers the kit builds, under the `scene` anchor. A gesture in flight draws no ghost over it, since the ghost is painted with the slot's `drawOne`. `mergeLayersWithDefaults` leaves a pre-built layer in either slot as it was given.
|
|
426
|
+
- 1956417: `previewBooleanOp(adapter, op, opts)` answers what `applyBooleanOp` would make of the selection, each piece with the source it stands in for and the paint a counted stroke leaves it, without minting a node or committing anything. It is what a live preview of a Pathfinder operation draws from. New API: `previewBooleanOp`, `BooleanOpPreview`, and `BooleanPreviewPiece`. The two functions share one resolution, so a preview and the commit that follows cannot disagree.
|
|
427
|
+
- 955defa: geom: the screen-pixel helpers live here now: `pxExtent`, `scaleDelta`, `screenAngleOf`, `standoff`, `withinPxBox`, `withinPxRadius`, and `meanScale`, with the `Scale2` type. They take a view's scale as two numbers and need nothing else from core. `@weasel-js/core` still exports every one of them.
|
|
428
|
+
- 27b827e: text: the run algebra lives here now: `styleAtRange`, `applyStyleToRange`, `patchRangeStyle`, `effectiveRangeStyle`, `rangeWeight`, `setFlagOverRange`, `nodeHasFlag`, and `unboldPatch`, with the `RangeStyle`, `RunStylePatch`, `StyleKey`, `FlagKey`, and `SetFlagResult` types. `runsCarryStyling` and `supersededKey` are exported beside them. None of them needed a scene. The `MIXED` sentinel and its `Mixed` type moved to `@weasel-js/registry`, and text exports them too. `@weasel-js/core` still exports every name it did before.
|
|
429
|
+
- 74f364f: Removing a node takes it out of the scene's selection. `scene.getSelection()` used to keep the id of a node `scene.remove` had taken, so every reader guarded `scene.get(id)`. Undo puts the node and its selection back. `reconcileSpecs` carries the selection across a node it replaces by removing and re-adding the id, and deselects one it drops. `setSelection` still accepts an id no node has. This is a behavior change, made on an agent's judgment: a consumer that read a removed id back out of the selection no longer finds it.
|
|
430
|
+
- 01d6e4e: renderer: a new package holding the WebGL2 renderer, moved out of core. `WeaselRenderer` draws a `DrawCommand[]`; `cullDrawCommands` drops what cannot reach a rectangle; `registerProgram`, `registerTexture`, and `registerEffect` add shaders, textures, and full-screen passes. It depends on `@weasel-js/geom`, `@weasel-js/paint`, `@weasel-js/registry`, `@weasel-js/stroke`, and `@weasel-js/text`, with `@weasel-js/font` as a peer, and has no scene and no React.
|
|
431
|
+
|
|
432
|
+
Everything `@weasel-js/core/renderer` exported is exported from `@weasel-js/renderer`. So are `isPaintKindKnown` and `warmPaintKinds`, `fillInPoseFrame` and `fillToBoundsFrame`, `commandFill` and `commandStroke`, `createTilePattern`, `resolvePatternSpec`, `resolveFillPattern`, `isPatternSpec`, the image cache (`getImageBitmap`, `imageStatus`, `releaseImage`, `retryImage`, `subscribeImageReady`, `isVectorImageSrc`), and `textCommand`, `textCommandFromRuns`, and `textCommandFromPose`.
|
|
433
|
+
|
|
434
|
+
These were not exports of `@weasel-js/core` before and are additions: `getProgramSource`, `strokeReachAt`, `boundsMissRect`, and the draw-kind registry a paint kind's draw slots live in (`registerPaintDrawKind`, `registerPaintDrawKindLoader`, `getPaintDrawKind`, `paintDrawKindRegistry`).
|
|
435
|
+
|
|
436
|
+
The mesh gradient is at `@weasel-js/renderer/mesh`, the named pattern tiles at `@weasel-js/renderer/patterns-builtin`, the recording WebGL2 stand-in at `@weasel-js/renderer/testing/glRecorder`, and the reset seams at `@weasel-js/renderer/test-seams`.
|
|
437
|
+
|
|
438
|
+
`@weasel-js/core`, `@weasel-js/core/renderer`, `@weasel-js/core/mesh`, and `@weasel-js/core/patterns-builtin` still export every name they did before.
|
|
439
|
+
- 32b3cc9: core: a node grabbed while a reflow transition was still gliding it, then dropped onto another node with `reparentOnDrop` on, landed where its document pose plus the drag put it, off from where the drag showed it by however far the glide had left to go. It now lands where it was shown. Not breaking.
|
|
440
|
+
- 70413dd: Fixes: resizing a node whose pose carries a `transform` took the drag in the unskewed box's axes, so the dragged corner left the pointer and the opposite corner slid. The drag is taken in the frame the node is drawn in: the dragged corner follows the pointer and the opposite one stays where it is drawn. A resize still writes the box and keeps the `transform`. A point snap is told where the corners are drawn, and lands the drawn corner on the point it names.
|
|
441
|
+
- fcf44fa: A pose move can rewind when it is undone. `tweenPose`, `springPose`, and `staggerSpringPose` take `rewind: true`: undone mid-flight, a tween travels back to where it began along the positions it passed, at the pace it passed them, and a spring springs back from where it is at the speed it has; redone on the way back, either turns forward again. `onDone` is called only when the move arrives at its destination. Without `rewind` a move undone mid-flight comes to rest on the undone pose at once, as before, and any write that is not the move's own undo or redo still wins at once either way. It needs an adapter with `poseTarget`, which every scene adapter has.
|
|
442
|
+
|
|
443
|
+
This adds API, and its shape was chosen on an agent's judgment: an option per move, off by default, and a rewind that turns on the frame after the undo.
|
|
444
|
+
- a91e5cd: Adds API: a rig can live in the scene. `rigFromNode(scene, id)` reads a skeleton from a node's `data.skeleton`, with its joints relative to that node's box and turned as the node is, and gathers from every node under it a `data.skin` (a path that bends) or a `data.joint` (a node that rides that joint whole). It answers the `skeleton`, `bindings`, and `skins` `bindRig` takes. `useRigNode({ scene, node })` binds that rig for a component's lifetime and binds it again when the rig node or anything under it changes its pose or data; an edit elsewhere in the scene leaves the rig, and its `target`, alone.
|
|
445
|
+
- 91a479a: `useRigNode` keeps its rig's `target` when it binds again. A change to the rig node or anything under it, a painted weight included, used to make a new rig with a new target, which dropped every animation running on the old one and left the nodes at rest. The rig returned is still a new object, but its `target`, its committed pose, and its placement carry over, and it shows the pose that was on screen as it binds. This is a behavior change: a rig posed with `rig.pose` used to go back to the bind pose when it bound again, and now stays posed. Adding, removing, renaming, or reordering a joint still makes a new target at the bind pose. `bindRig` and `useRig` are unchanged.
|
|
446
|
+
- 7afbc13: A rig is an animation target, and `blendPoses` is removed. Breaking for anything that called `blendPoses`.
|
|
447
|
+
|
|
448
|
+
`Rig.target` is a `Target<Pose>`: its committed value starts as `{}`, the bind pose, and each frame the rig is posed with what the target shows. A clip is a `SampledTrack<Pose>` with `target: rig.target`. Two clips on one rig crossfade by their `weight`s, weights that sum to less than 1 leave the rest to the committed pose, and a `spring` or `tween` on the target adds on top. `rig.pose(pose, root)` still writes at once, and now commits `pose` as well. `rig.place(root)` sets the root transform without a pose; a `pose` called with no `root` keeps the last one given, where it used to drop it.
|
|
449
|
+
|
|
450
|
+
`skeletonAxes(skeleton)` is the axes a pose target uses: five per joint in skeleton order, every rotation an angle. Pass it to `createTarget` for a pose target that is not bound to scene nodes.
|
|
451
|
+
|
|
452
|
+
A `SampledTrack` with a `target` no longer needs `interpolate` for a value that is not plain numbers. It is sampled in the target's axes, the short way round between neighboring keys on an angle axis, and every sample, a key's own included, is a value the axes built. An `interpolate` or `interpolator` on the track still wins.
|
|
453
|
+
|
|
454
|
+
What replaces each use of `blendPoses`:
|
|
455
|
+
|
|
456
|
+
- **A track's `interpolate`** (`blendPoses([a, b], [1 - u, u])`): give the track `target: rig.target` and drop `interpolate`.
|
|
457
|
+
- **Blending poses by weight**: `animator.hold({ target: rig.target, value: pose, weight })`, one per pose.
|
|
458
|
+
- **Weighting IK against animation** (`blendPoses([anim, solved], [1 - w, w])`): hold the solved pose at `w` beside the clip at `1 - w`.
|
|
459
|
+
- **A blended pose as a value**: `sampleTrack` on a targeted track whose two keys are the poses.
|
|
460
|
+
|
|
461
|
+
Where the result differs from `blendPoses`:
|
|
462
|
+
|
|
463
|
+
- Weights are not normalized. `[0.3, 0.3]` is an even mix at 60% strength over the committed pose; weights summing past 1 share full strength, so `[1, 1]` is still an even mix.
|
|
464
|
+
- Rotations meet at their average direction by weight, where `blendPoses` turned each pose in order from the first. Two poses give the same answer; three or more spread around the circle can differ. At weights short of 1 the joint turns the short way from the committed pose toward that meeting point.
|
|
465
|
+
- A pose read back names every joint of the skeleton in full.
|
|
466
|
+
|
|
467
|
+
Also fixed: a frame the animator requested from inside its own ticks ran ahead of the paint a canvas requests from `onTick`, which cost one painted frame each time a track took hold of its target or an `onDone` started another animation. The request now waits until after `onTick`.
|
|
468
|
+
- 8f38287: Adds API: a rig skins paths. `bindRig` and `useRig` take `skins`, a map from node id to a `Skin`, beside `bindings`, which is now optional. A bound node moves whole with one joint; a skinned node's path bends, each point following its own joints by weight, so one outline flexes at a joint. The rig shows the bent path through the node's pose override, posed at the path's bounds with no rotation, so paint, picking, and the selection box all follow it. `bake` writes the bent path into the node's `data.path` and its bounds into the pose, in the same undo entry as the bound nodes. A node cannot be both bound and skinned.
|
|
469
|
+
|
|
470
|
+
The rest path is read once, when the rig is bound, from the node's `data.path` carried through its pose. `restPath` reads it from elsewhere, and `dataRestPath` is the default.
|
|
471
|
+
|
|
472
|
+
Breaking for a hand-written `RigScene`: it now needs `update(id, { data })`, which `bake` uses for a skinned node, and its `get` may answer `data`. A `Scene` already has both.
|
|
473
|
+
- 936679d: Additive, with one behavior change: rotating with Shift held snaps the angle to 15 degree steps. `snapRotationWithModifier({ key, step })` is the behavior, and a rotate binding that names no `behaviors` gets it through `DEFAULT_ROTATE_BEHAVIORS`, the way a resize gets the Shift aspect lock. What snaps is the angle the first rotated node ends at; the rest of a multi-selection turns by the same amount. Pass `rotate: { behaviors: [] }` to `selectionRotateContribution` or `selectionTransformContribution` to turn it off; an empty list used to be dropped there and now reaches the binding.
|
|
474
|
+
|
|
475
|
+
A `RotateBehavior.onMove` may return `{ rotation }` in radians where it only changes the angle, in place of a whole pose.
|
|
476
|
+
|
|
477
|
+
Making Shift snap by default was a judgment call, taken from how resize already treats Shift.
|
|
478
|
+
- 813aea2: Fixes: the route-conflict check never compared `mod` with the key it resolves to, so `mods: { mod: true }` on one binding and `mods: { ctrl: true }` on another went unreported though both match Ctrl off a Mac, and likewise `mod` against `meta` on one. The check now buckets bindings once per platform, reading `mod` as `meta` on a Mac and `ctrl` elsewhere.
|
|
479
|
+
|
|
480
|
+
Changes behavior: a consumer whose bindings tie this way will see a new `[weasel] route conflict` warning in development. Two bindings of one action with equal `params` that tie on one platform only are not reported, since whichever fires does the same thing; `viewport.zoom` binds its wheel to both `mod` and `ctrl` that way. The same pair tying on both platforms is still reported as a duplicate. That exemption was chosen on an agent's judgment.
|
|
481
|
+
|
|
482
|
+
Adds API: `RegistryEntry.params`, the binding's `opts.params` as declared.
|
|
483
|
+
- 42f24c8: core: the canvas adapter (`sceneToAdapter`), `defaultCommitAdapter`, and the adapter the move action hands its behaviors now share one set of scene mutators, so an op applies the same way through all three. Not breaking. What that changes:
|
|
484
|
+
|
|
485
|
+
- `sceneToAdapter` has `setLayer`. A `setLayer` op applied through it, such as the one a cross-layer reparent-on-drop sends to a consumer's `applyOps`, used to throw.
|
|
486
|
+
- `defaultCommitAdapter().setChildOrder` called outside a batch records one undo step instead of one per sibling it moved.
|
|
487
|
+
- A move behavior that answers with a delete op now gets the node's dependents back on undo, as rotate's already did. A `setLayout` or `setSelection` op from a move behavior applies instead of throwing.
|
|
488
|
+
- 499af9b: `SceneCanvasApi.camera` hands out the canvas's camera as an animation target, with the animator that moves it: `{ target, animator }`. An animation started on that animator with that target adds to an `animateView` glide in flight, so a shake or a nudge no longer needs a camera of its own.
|
|
489
|
+
- 8cc746f: Breaking: `<SceneCanvas>` no longer takes `insertTool`. It set `commitInsert` on the adapter, which nothing in the kit calls: the insert action mints nodes through the `insert` dep, so override that dep (`useDepSource('insert', …)` or `insertNodeFactories`) instead.
|
|
490
|
+
- a21947b: `<SceneCanvas>` reads what each `features` preset turns on (its actions, tools, ambient bindings, and chrome) from one table, and `features/chrome-caps` builds the rule context the canvas used to assemble inline.
|
|
491
|
+
|
|
492
|
+
Changes behavior: `FEATURE_ACTION_IDS` and `COMPOSITE_FEATURES.draw` list `move` after `rotate`; the order is the order ambient bindings are matched in. The rule context `<SceneCanvas>` hands to chrome rules no longer carries an untyped `view` property; read `zoom`.
|
|
493
|
+
- de07db0: Breaking: `<SceneCanvas>` no longer takes `actionDefaults`. Nothing had read it since the legacy action bridge was removed.
|
|
494
|
+
|
|
495
|
+
Fixes: a bare `<SceneCanvas>` registered three sets of pointer and hover media-query listeners. `useDeviceProfile` watched the device even when a `<DeviceProfileProvider>` above it already answered, so every reader under a provider added a set; it now watches nothing under a provider.
|
|
496
|
+
- 4d3ff3f: Fixes: a shape kind added to `KIT_SHAPE_KINDS` did not get a built-in tool on `<SceneCanvas>`, because the canvas spelled the kinds out by hand. It now resolves its built-in tools from `BUILTIN_TOOL_IDS` in one place.
|
|
497
|
+
|
|
498
|
+
Breaking: `createPenPreviewLayer` takes the pen's `state` (a `PenScratch`) where it took `penTool`. The pen tool now declares the preview as its own overlay, so `<SceneCanvas>` no longer builds it and the layers map has no `penPreview` key. A pen passed through a `tools` takeover, or a consumer's own `usePenTool`, draws its preview without being wired to one.
|
|
499
|
+
|
|
500
|
+
Changes behavior: the pen's preview sits directly beneath the selection overlay, and it is hidden while a mode forbids the pen's capabilities, as the tool's other chrome is. The path in progress is kept and shows again when the mode allows it. Holding a hotkey tool mid-draw still shows it.
|
|
501
|
+
|
|
502
|
+
Breaking: `useKeybindings` takes `modes` where it took `isToolEligible`, and asks the mode registry about each tool's own capability tags.
|
|
503
|
+
|
|
504
|
+
Adds API: `inertia: true` on `useHandTool` and on the `viewport.dragPan` action's params means the kit's default inertia, as it already does on `<SceneCanvas viewport>`.
|
|
505
|
+
- 85cb886: Adds API: `Bivariant` and `ScopedScene` are exported from `@weasel-js/core`. `DerivePathFn`, `DerivePoseFn`, and `ClipFromPoseFn` are written in terms of the first, and `sceneUnitScopes` takes the second, so a consumer can now name both.
|
|
506
|
+
- aed6320: Breaking: a scene's pose composition is the scene's own. Pass it once, as `useScene({ composition: RIGID_POSE_COMPOSITION })` (or `createScene`, `sceneFromJSON`), and read it as `scene.composition`; a scene given none answers `IDENTITY_POSE_COMPOSITION`. The canvas, the adapter, the layout pass, picking, the headless renders, and every built-in action read it from the scene.
|
|
507
|
+
|
|
508
|
+
Removed, each replaced by the scene option: the `<SceneCanvas poseComposition>` prop; `sceneToAdapter`'s `poseComposition` and `cascadeContainerPose` options; `LayoutFrame.composition`; the `poseComposition` option of `scenePickSource` and `useLayoutArrivals` / `layoutArrivalHandler`; the `poseComposition` routing dep and `usePoseCompositionDepSource`; and the composition parameter of `buildSceneViewCommands`.
|
|
509
|
+
|
|
510
|
+
Changes behavior: `sceneToAdapter(scene)` on an absolute-pose scene now always carries a container's descendants when the container is posed, where it did so only under `cascadeContainerPose: true`. `renderSceneToPixels`, `renderSceneToCanvas`, and `<SceneViewCanvas>` now compose poses for a scene that has a composition, where they painted every node at its stored pose.
|
|
511
|
+
|
|
512
|
+
Adds API: `composesFrames(composition)`, whether a composition makes a container's pose a frame.
|
|
513
|
+
- 9d11828: `TimelineHandle.seek` samples the timeline's sampled tracks at once. A target a track holds reads the seeked value straight away, where it used to read the old one until the animator's next frame, so a simulation that seeks a clip and draws in the same frame no longer draws a frame behind. A track's `onTick` is called from the seek as well as from the next frame. Events still wait for playback to advance. `TimelineHandle.edit` samples at once in the same way.
|
|
514
|
+
- 37463b5: Fixes: an always-live `pointerDown` binding never fired on empty canvas while the select tool was active. `select.pick` matched every press off chrome, found nothing to pick there, and still took the press at the active tier. Its binding, and `select.collapseDeferred`'s, now match a press on a node only, so a press on empty canvas reaches the binding a tier below.
|
|
515
|
+
|
|
516
|
+
Behavior change, made on an agent's judgment: a consumer whose own always-live `pointerDown` binding has no target now sees presses on empty canvas under the select tool, where it saw none. A press on a node still goes to the tool. A bare `useSelectTool` with no `classifyTarget` wired has no body class to read and behaves as before.
|
|
517
|
+
- 3558fbb: Adds API: a timeline can be saved and loaded. A `Clip` is a timeline as data: `{ version: 1, tracks, duration? }` with keys, easings by built-in name or bezier points, and names wherever a live timeline holds a function or a target. `bindClip(clip, binder)` answers the `{ tracks, duration }` `animator.timeline` takes, resolving each sampled track's `target` and `interpolate` and each event's `name` through the binder, and throws on a name the binder does not know. `toClip({ tracks, duration })` reads a live timeline back into a clip, `handle.tracks()` included, so an animation changed in `<AnimatedTimeline>` can be saved.
|
|
518
|
+
|
|
519
|
+
A live track now says what it is as well as what it does: `SampledTrack` has `targetName` and `interpolateName`, and `TimelineEvent` has `name` and `data`. `bindClip` sets them and a track written by hand can set them too. `toClip` throws, naming the track, on what a clip cannot hold: a target or `interpolate` with no name, an `onTick`, an `interpolator`, a function for `weight`, a function easing that is not a built-in, or a value JSON would not read back, such as a typed array.
|
|
520
|
+
|
|
521
|
+
In `@weasel-js/core`, `sceneClipTargets(scene, { rigs })` is a binder's `target` for a scene: `pose:<node id>` is that node's pose target and `rig:<name>` the target of the rig given under that name.
|
|
522
|
+
- bffba0a: `ShaderDrawCommand`, the module-level `registerProgram`, and `WeaselRenderer.registerProgram` are no longer marked `@experimental`, and a shader command's program compiles on the first frame that draws it. Before, a renderer drew a shader command only if the program had been compiled on it first, through `<Canvas shaders>` or `renderer.registerProgram(handle)`, so a custom `RenderLayer` had no way to draw one without reaching the renderer. Now a layer emits the command with the handle `registerProgram()` returned and nothing else: the renderer compiles it through the path effects and paint kinds already use. `shaders` and `renderer.registerProgram` remain, for compiling ahead of the first frame and for catching `ShaderCompileError`. A command whose id was never registered, or whose source does not compile, draws nothing and warns once, where it warned on every frame. Dropping the tag was done on an agent's judgment; `registerEffect` keeps its own.
|
|
523
|
+
- efc5cea: simulation: a new package holding the N-body integrator that lived in core. `createSimulation`, its types, and the `DEFAULT_ALPHA_DECAY`, `DEFAULT_ALPHA_MIN`, and `DEFAULT_VELOCITY_DECAY` constants are the root entry, which needs no React and no DOM. `useSimulation` is in `@weasel-js/simulation/react`. `@weasel-js/core` and `@weasel-js/core/math` still export what they did.
|
|
524
|
+
- 32e243f: Adds API, in `@weasel-js/animator`: pure edits to a `Skeleton`, each answering a new one. `moveJoint(skeleton, name, x, y)` rests a joint at a point, worked back through its parent's frame, and the joints under it move along. `addJoint(skeleton, parent, x, y, name?)` adds a joint at a point under a parent or as a root. `removeJoint(skeleton, name)` removes a joint and everything under it and says which names went, and `dropSkinJoints(skin, names)` takes those joints' weights out of a skin. `jointPositions(skeleton)` answers where each joint rests and `jointAt(skeleton, x, y, reach)` the joint nearest a point.
|
|
525
|
+
- 233f856: Adds API, in `@weasel-js/animator`: the first piece of skinning, where one path bends with a skeleton. `skinPath(path, skin, motions)` moves each point of a path to where its joints' motions since the bind pose would carry it, averaged by weight, and answers a new path. A `Skin` is one weight array per joint name, indexed by point: every coordinate pair of a polygon path's `coords`, curve handles included, or a rect's four corners. `motionsFromRest(skeleton, world)` turns the joint world transforms `resolveSkeleton` or `Rig.world()` answers into those motions. `autoSkin(path, skeleton, { power, max })` makes a skin from each point's distance to the bones at the bind pose; a joint with no child gets no weight, so a limb needs an end joint.
|
|
526
|
+
|
|
527
|
+
Nothing draws a skinned path yet: these are the pure functions the rig will call.
|
|
528
|
+
- c9b9598: labkit's stylesheets, core's debug HUDs, and forge's shell and story frame take every `gap`, `padding`, and `margin` that has a rung from the `--wzl-space-*` ladder, where each held the same px as a literal. Core, which draws on a page that may load no theme, keeps that px as the `var()` fallback, so nothing moves there.
|
|
529
|
+
- 2705878: `animator.stagger(items, delay).springPose(adapter, poseFn, opts)` is gone, and `staggerSpringPose(animator, adapter, { items, delay, to, ...opts })` replaces it, beside `springPose` and `tweenPose`. Breaking: a caller of the builder method moves to the function, and `poseFn` becomes the `to` option. The stagger builder keeps `.each` and `.tween`. This takes the animator's last reference to a scene adapter out of it.
|
|
530
|
+
- f59e769: Fixes: undo got stuck on an entry naming a node an untracked edit had removed. `scene.add(n)`, `scene.setPose(n, p)`, then `scene.untracked(() => scene.remove(n))`, which is what `reconcileSpecs` does when outside data drops a node, left `scene.undo()` throwing `unknown node id "n"` with the entry still on top, so nothing beneath it could be undone. A replayed op whose node is gone is now skipped, and the rest of its entry applies; so is one that would restore a node an untracked edit already added back under that id, which used to overwrite the live node. The inverse of a skipped op is skipped too, so undo then redo leaves the scene as it was. This covers the scene's own edits and ops applied through `scene.applyBatch` or `scene.history`. A first apply still throws on an unknown id. The skip rule was chosen on an agent's judgment over dropping the entries or clearing history.
|
|
531
|
+
- e69e97f: Outline Stroke and a Boolean operation that counts strokes outline each stroke in the frame the canvas draws it in. A `{ px }` width is measured on screen, so under a view that scales its axes apart a line across the page and a line down it get different world widths, where both took the mean scale. A world width is skewed and stretched with its node when the adapter says how the node is drawn.
|
|
532
|
+
|
|
533
|
+
New API: `getStrokeFrame(id)` on `BooleansAdapter` and `CreateOutlinesAdapter`, optional, answering the node's `poseFrameOf` to world. `BooleanOpOptions.scale` and `applyOutlineStroke`'s `scale` take the view's per-axis scale as well as a number (`StrokeRegionOptions`). The built-in Pathfinder and Outline Stroke actions pass the view's scale per axis.
|
|
534
|
+
|
|
535
|
+
`applyOutlineStroke` no longer takes `StrokeToPathOptions`: a `frame` passed there is ignored, and `getStrokeFrame` is how a node's frame is given.
|
|
536
|
+
- 9c19d5e: stroke: a new package holding a stroke as geometry, moved out of core. `tessellateStroke` and `resolveStrokeWidth` build the ribbon mesh; `registerMarker`, `getMarker`, `listMarkers`, `markerRegistry`, `markerGeneration`, and `BUILTIN_MARKERS` are the marker registry; `markerSites`, `markerHeads`, `markerInset`, `markerKeyOf`, `resolveMarkerSize`, `strokeInsets`, and `markerReach` place and measure marker heads; `strokeToPath` outlines the whole stroke as a path. It depends on `@weasel-js/geom`, `@weasel-js/paint`, and `@weasel-js/registry`, and has no scene and no React.
|
|
537
|
+
|
|
538
|
+
The stroke metric functions the renderer uses are exported here too (`strokeSpaceOf`, `polylineIntoMetric`, `coordsOutOfMetric`, and the rest, with `StrokeMetric`, `ScreenSpace`, and `StrokeSpaces`), as are `splitForDash`, `populatePolylineWidths`, `trimInSpace`, `markerHeads`, `markerReadsKey`, and `markerReach`. These were not exports of `@weasel-js/core` before; they are additions. `_resetMarkersForTests` is at `@weasel-js/stroke/test-seams`.
|
|
539
|
+
|
|
540
|
+
`@weasel-js/core` still exports every name it did before.
|
|
541
|
+
- 0e1f269: A canvas hears of a scene-layer change from its adapter instead of polling for one at paint. `LayerEnumerableAdapter` gains an optional `subscribeLayers(listener)`, which the adapter `<SceneCanvas>` builds implements, and a layer added, removed, or reordered now paints on the next frame; the poll skipped one. This adds API. A hand-written adapter that implements `getLayers` and changes the list after mount has to implement `subscribeLayers` too, or the canvas keeps the list it mounted with. That trade was made on an agent's judgment.
|
|
542
|
+
- 5b1a788: A `Target` answers its committed value with `committed()`, writes it with `commit(value)`, and carries its `axes`. Additive. Core's pose helpers, coast, and lifecycle wrapper read the committed pose through these, where they reached the animator's private state for it.
|
|
543
|
+
- d3b9057: A target can be read as numbers. `target.readInto(out, at?)` writes the value on screen as its axes into a `Float64Array`, `Float32Array`, or array the caller owns, `target.axisCount` numbers from `at`, with no value built: for a painter reading thousands of targets a frame.
|
|
544
|
+
|
|
545
|
+
`TargetAxes` takes two optional functions that make reads cheaper. `add(value, delta)` answers the value with a delta applied axis by axis, and `read()` uses it to skip the array of axes it used to build. `write(value, out, at)` puts a value's axes straight into a buffer, for `readInto`. Every axes mapping the kit supplies defines both: the default for a number, an array, or an object of numbers, `RECT_POSE_DESCRIPTOR`, `pathPoseDescriptor`, `viewAxes`, and `skeletonAxes`. Axes without them work as before.
|
|
546
|
+
- 4fe6756: `createTargetTable({ axes })` keeps many like values as rows of numbers an animator can move: particles, dots, vertex colors. `table.add(value)` answers a row, `table.target(row)` is that row as a `Target`, so it tweens, springs, coasts, and holds like any other, and `table.shown` is every row's value on screen in one `Float64Array`, filled by the animator once a frame. `table.committed` holds the values the rows rest at, `table.set(row, value)` writes one, and `table.remove(row)` frees a row for the next `add`.
|
|
547
|
+
|
|
548
|
+
Reading 10,000 moving values through a target apiece costs about 140 ns each; the table's pass over them costs 3 to 4 ns a row, and the same at 100,000. A row with a hold on it is part of that pass too, unless a tween or spring with a destination is running under the hold.
|
|
549
|
+
- 9fa373d: text-dom: a new package holding in-place text editing, moved out of core. `useTextEdit` mounts a contenteditable overlay over a box on screen and commits styled runs; `runsToDom`, `domToRuns`, `charOffsetToDomPosition`, and `domPositionToCharOffset` convert between runs and the overlay's DOM. The types `TextEditScreenPose`, `TextEditClipRect`, `TextEditCommit`, `TextEditSelection`, `StartEditOptions`, `UseTextEditOptions`, `UseTextEditReturn`, and `StyleToggle` come with it, as does `TEXT_EDIT_FONT_HOLD`. It depends on `@weasel-js/text`, `@weasel-js/font`, `@weasel-js/paint`, and `@weasel-js/react`, needs React, and has no scene.
|
|
550
|
+
|
|
551
|
+
The `text-dom@1.9.4` seeded on npm exports `overlayTop` and `baselineDrop`, which are internal; this release takes them off the entry. `@weasel-js/core` still exports every name it did before, and `useSceneTextEdit` stays in core.
|
|
552
|
+
- b76089a: text: `pointInTextPose`, `caretIndexAt`, `fitTextPose`, `renderLabel`, `defaultLabelTextRenderer`, and `isTextData` live here now, with the `PointInTextPoseOpts`, `FitTextPoseOptions`, and `LabelOptions` types. None of them needed a scene. `@weasel-js/core` still exports every one of them.
|
|
553
|
+
- 54242f0: Breaking: `layoutRuns` no longer returns `groups` or `decorations`, and no longer takes `outlineMinSize`. It places glyphs and reads no paint; `paintRuns(laid, runs, { outlineMinSize })` derives what to draw for a layout and returns `{ groups, decorations }`.
|
|
554
|
+
|
|
555
|
+
```ts
|
|
556
|
+
const laid = layoutRuns(runs, opts);
|
|
557
|
+
const { groups, decorations } = paintRuns(laid, runs, { outlineMinSize });
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
`cachedPaintRuns` is the memoized form, beside `cachedLayoutRuns`. A layout's lines each carry `glyphs`, one `PlacedGlyph` per code point in visual order, which is what `paintRuns` and `textToPath` read. The `LaidOutGroup`, `LaidOutQuad`, `LaidOutOutlineGlyph`, and `LaidOutDecoration` shapes are unchanged, and groups still come in the order their first glyph appears.
|
|
561
|
+
|
|
562
|
+
The layout cache no longer keys on a run's fill, stroke, or decorations, or on the outline threshold, so two runs arrays that differ only there share one layout. It also survives a dynamic glyph bake landing: `faceGeneration()` in `@weasel-js/font` advances when faces change and holds still for a bake, where `glyphGeneration()` advances for both.
|
|
563
|
+
|
|
564
|
+
Paint identity is structural, and has one definition. `paintKey`, `strokeKey`, `fillHasInk`, and `strokeHasInk` are new in `@weasel-js/paint`. Two equal gradients built separately are one paint, so text runs filled with them share a group where each used to get its own. `textToPathsByPaint` now groups a zero-width or unpainted stroke with no stroke.
|
|
565
|
+
|
|
566
|
+
`@weasel-js/font` gains `metricsOf(resolved)`, the advances, kerning, and baseline of whichever tier a face resolved to, and `glyphIn` / `resolveGlyph`, which find one code point's glyph in that tier and then in the dynamic tier. Layout's missing-glyph and no-metrics warnings moved there and read `weasel:` where they read `weasel layoutRuns:`; `_resetFontRegistryForTests` and `_resetFallbackForTests` clear them. `@weasel-js/text/test-seams` gains `_resetBidiWarningForTests`.
|
|
567
|
+
|
|
568
|
+
Fixes:
|
|
569
|
+
|
|
570
|
+
- A run whose fill holds no paint (`fill: {}`) drew black from an atlas or the canvas tier. It now draws nothing, as `fill: null` does.
|
|
571
|
+
- A run set in a canvas-tier family reported `drawsInk: true`, with no warning, for a code point its face could not rasterize. It now reports `false` and warns once, as an atlas run that escalates to the canvas tier does.
|
|
572
|
+
- A default-ignorable code point (a joiner, a variation selector, a zero-width space) that the canvas tier serves as no advance and no ink is a glyph, not a miss. An atlas run that escalated one warned that it had no glyph and dropped the letter spacing of the cluster it closed; it now does neither.
|
|
573
|
+
- A zero-advance glyph that escalated to the canvas tier was reported as missing until its bake landed.
|
|
574
|
+
- A family the registry had already warned "will not render at all" about got a second, no-metrics warning from layout.
|
|
575
|
+
- Text made only of Arabic-Indic digits or Arabic number signs triggered the "right-to-left characters but no `bidi` engine" warning, though it lays out the same with an engine. So did left-to-right text holding a byte order mark, an Arabic comma, or an ornate parenthesis.
|
|
576
|
+
|
|
577
|
+
Adds to the `@weasel-js/core` barrel: `paintRuns`, `cachedPaintRuns`, and the types `LaidOutCell`, `PlacedGlyph`, `PaintRunsOpts`, and `PaintedRuns`.
|
|
578
|
+
- ad10f82: Fixes: editing a text node whose pose is turned or carries a `transform` put the edit overlay on the node's unturned, unskewed box, and a double-click opened the editor from that box where no text is drawn. `useSceneTextEdit` hands the overlay the frame the node is drawn in, and takes a double-click back through it before testing it against the text.
|
|
579
|
+
|
|
580
|
+
Adds API: `TextEditScreenPose.frame`, the linear part `[a, b, c, d]` of the frame a text box is drawn in, applied about the box's center. `useTextEdit` writes it into the overlay's CSS transform with the `zoom`.
|
|
581
|
+
- 4042637: A timeline track can move a target, a value can be held on one, and an animation's clock now starts with its frame.
|
|
582
|
+
|
|
583
|
+
- `animator.hold({ target, value, weight? })` shows `value` on a target in place of its committed value until canceled or released: a drag preview, a value driven from outside. `value` and `weight` are plain or functions read each frame; the handle's `touch()` says a function's answer changed between frames. Animations on the target add on top of a hold. Several holds on one target show their weighted average, and whatever their weights leave short of 1 goes to the committed value. Canceling or `release()` commits what the hold was showing, so the target stays put; `release({ commit: false })` lets it fall back. A hold of plain values does not keep the frame loop running. `'hold'` is a new `AnimationKind`.
|
|
584
|
+
- `SampledTrack` takes `target` and `weight`, and `onTick` is now optional. While the playhead is within the track's keys the target shows the sampled value, the same frame the playhead moves, including after a seek and across a loop seam. Past its last key, or when the timeline finishes or is canceled, the target keeps the value it was showing. Before its first key the track leaves the target alone.
|
|
585
|
+
- **Behavior change:** an animation started while the animator is already running counts its time from the last frame, not from the moment of the call. Its first frame then advances by the whole frame, as the value it shows always did, so a tween's end, a timeline's playhead, and its events line up frame for frame. An animation started between frames reaches a given time up to one frame sooner than before. Starting on an idle animator is unchanged.
|
|
586
|
+
- 90f8ec4: Adds API: types that documented exports already named, and that a consumer could not import, are now exported. `@weasel-js/core`: `CameraProps`, `CanvasViewState`, `CanvasLayers`, `SceneSlotLayers`, and `OpsApplier`. `@weasel-js/animator`: `Naming`. `@weasel-js/gestures`: `Point`. `@weasel-js/ui`: `LiveControl`, `OnTokenChange`, and `OptionKey`, the `string | number` a `Select`, a `ComboBox`, and `useAsyncOptions` each declared privately as `Key`.
|
|
587
|
+
|
|
588
|
+
Adds API: `strokeRegion` in `@weasel-js/core`, the region a stroke covers along a path, which `applyOutlineStroke`'s documentation pointed at and `StrokeRegionOptions` already described.
|
|
589
|
+
- a297730: Fixes: a marquee or lasso in `intersect` mode drawn wholly inside a closed shape with no fill selected it, though a click there did not. A region now takes an unfilled shape only where it meets the outline or encloses it. This changes what a marquee selects: one drawn inside a stroke-only rect to reach the nodes within it no longer takes the rect too.
|
|
590
|
+
|
|
591
|
+
Adds API: `polygonIntersectsPath(polygon, path, { filled: false })` in `@weasel-js/geom` reads a closed subpath as a line, and `regionTakes` takes a sixth argument, `filled`, a thunk asked only when the bounds cannot decide. Both default to filled.
|
|
592
|
+
- 38fd203: Adds API: arithmetic across units. `resolveUnitExpr('50% + 2ft', { unitSystem, percentOf })` returns base units, and `parseUnitExpr` returns the expression as plain data (`UnitExpr`), so a stored one resolves again when the length its percentage is measured against changes. It reads `+ - * /`, parentheses, and adjacent terms as one compound value (`5ft 3in`). Both are re-exported from `@weasel-js/core`.
|
|
593
|
+
|
|
594
|
+
Decided on an agent's judgment: a bare number beside `+` or `-` is base units and beside `*` or `/` a scalar; a measure over a measure is a scalar; a product of two measures, a scalar over a measure, and a unit with an offset (degC) anywhere inside arithmetic all throw; `%` resolves against `percentOf` unless the unit system defines a `%` unit of its own.
|
|
595
|
+
- 9ad34e0: Adds API: a unit system nested in another. A `UnitScope` is a `UnitSystem` plus the `scale` one of its base units is worth in the scope around it, so a sub-assembly drawn in millimeters can sit in a scene measured in inches. `resolveScoped(value, scopes)` reads a value against the innermost scope and returns the outermost scope's base units, converting at each boundary; `toRoot` and `fromRoot` convert a bare measure each way; `formatScoped` writes a root measure in an inner unit; and `scopesOf(id, root, tree)` collects the chain for a node from a `parentOf` and a `scopeOf`. All are re-exported from `@weasel-js/core`.
|
|
596
|
+
|
|
597
|
+
Decided on an agent's judgment: a value is resolved only against the innermost scope's units, so `ft` inside a metric scope throws; and a node's own scope covers its children, not the node, unless `scopesOf` is asked to be `inclusive`.
|
|
598
|
+
- 1d34f51: react: `useCanvasFocus` lives here now, with `UseCanvasFocusOptions` and `CanvasFocusReturn`. `@weasel-js/core` still exports all three.
|
|
599
|
+
- 80b29f6: react: `useVisibleRaf` lives here now, with its `VisibleRaf`, `VisibleRafOptions`, and `VisibleRafTarget` types, so a package below core can run a frame loop behind the visibility gate. `@weasel-js/core` still exports all four.
|
|
600
|
+
- 6941e0c: A stroke of the weight tool can bend the path as it is painted. This is additive, with one breaking edge for anyone who wrote a `RigEditState` by hand.
|
|
601
|
+
|
|
602
|
+
- `RigEditState` now also holds the weights a stroke has painted and not yet written: `painted()` and `paint(next)`, with `listen` told of both. `createRigEditState()` makes one as before; an object written by hand to that interface needs the two new members.
|
|
603
|
+
- `useRigNode` takes `painting`, anything with `painted()` and `listen()` (the new `PaintedSkins` type). Give it the `RigEditState` the weight tool has and the rig binds the painted weights in place of each node's `data.skin` while the stroke runs, so a bent arm moves under the brush. Without `painting` a stroke shows on the path when it ends, as before.
|
|
604
|
+
- The document is still written once, as the stroke ends, and a canceled stroke leaves the rig on the document's weights.
|
|
605
|
+
- 98ec291: Adds API: `useWeightTool({ scene, rig })`, a tool that paints bone weights on the canvas. It works on every path under the rig node and writes each one's `data.skin`. A click on a joint makes it the active one. A drag is a round brush: points under it follow the active joint more, the nearer the brush's center, and their other joints give way so each point still sums to 1. With Alt held they follow it less. A click away from any joint is one dab. Every point, curve handles included, shows as a dot colored by the active joint's share of it, with the skeleton drawn over them. A stroke is one undo entry. Its key is W; mount it with `tools={{ weight }}`, and hand it the same `createRigEditState()` as the bone tool so both act on one joint.
|
|
606
|
+
|
|
607
|
+
`setWeights(skin, count, joint, weights)` and `brushWeights(coords, x, y, radius, current, mode)` are the pure edits behind it, in `@weasel-js/animator`.
|
|
608
|
+
|
|
609
|
+
The rig in view is bound from the document, so a stroke bends the path when it ends, not while it is painted.
|
|
610
|
+
- 0d1c052: `createWrittenPoseTarget({ read, write, descriptor?, onRest? })` makes a pose target over a store that holds one pose per node and has no overrides table, such as a hand-written adapter's. It keeps the committed pose while the node moves and writes the store the pose on screen each frame. Hand it back from the adapter's `poseTarget(id)` and moves on one node add: a second `tweenPose` no longer cancels the first, and `springPose` starts at their combined velocity. Canceling a move leaves the store at the pose on screen. A write to a moving node's pose from somewhere else is overwritten at the next frame.
|
|
611
|
+
- Updated dependencies [a695295]
|
|
612
|
+
- Updated dependencies [122a09c]
|
|
613
|
+
- Updated dependencies [bc7cd74]
|
|
614
|
+
- Updated dependencies [cd8cbbd]
|
|
615
|
+
- Updated dependencies [1f7548d]
|
|
616
|
+
- Updated dependencies [a86d79f]
|
|
617
|
+
- Updated dependencies [96a63de]
|
|
618
|
+
- Updated dependencies [7140b5a]
|
|
619
|
+
- Updated dependencies [89a2c50]
|
|
620
|
+
- Updated dependencies [9f5cdb2]
|
|
621
|
+
- Updated dependencies [1837952]
|
|
622
|
+
- Updated dependencies [99553f7]
|
|
623
|
+
- Updated dependencies [5149cce]
|
|
624
|
+
- Updated dependencies [de60e10]
|
|
625
|
+
- Updated dependencies [2892438]
|
|
626
|
+
- Updated dependencies [b3dec78]
|
|
627
|
+
- Updated dependencies [e80de55]
|
|
628
|
+
- Updated dependencies [126116b]
|
|
629
|
+
- Updated dependencies [9296fb4]
|
|
630
|
+
- Updated dependencies [6ba0496]
|
|
631
|
+
- Updated dependencies [b1f7521]
|
|
632
|
+
- Updated dependencies [d675fed]
|
|
633
|
+
- Updated dependencies [67b7639]
|
|
634
|
+
- Updated dependencies [18547a3]
|
|
635
|
+
- Updated dependencies [d635e84]
|
|
636
|
+
- Updated dependencies [d9620a2]
|
|
637
|
+
- Updated dependencies [bc9f367]
|
|
638
|
+
- Updated dependencies [a15b3f8]
|
|
639
|
+
- Updated dependencies [95c01e4]
|
|
640
|
+
- Updated dependencies [b3f1e4a]
|
|
641
|
+
- Updated dependencies [329f658]
|
|
642
|
+
- Updated dependencies [7063584]
|
|
643
|
+
- Updated dependencies [229ee1c]
|
|
644
|
+
- Updated dependencies [06003a5]
|
|
645
|
+
- Updated dependencies [c5a7bd3]
|
|
646
|
+
- Updated dependencies [7bac60f]
|
|
647
|
+
- Updated dependencies [fb715f4]
|
|
648
|
+
- Updated dependencies [3777548]
|
|
649
|
+
- Updated dependencies [de319ce]
|
|
650
|
+
- Updated dependencies [3a92afc]
|
|
651
|
+
- Updated dependencies [1bd7fdc]
|
|
652
|
+
- Updated dependencies [3bacb3e]
|
|
653
|
+
- Updated dependencies [b260415]
|
|
654
|
+
- Updated dependencies [66d5455]
|
|
655
|
+
- Updated dependencies [d58d2e8]
|
|
656
|
+
- Updated dependencies [3adb0d9]
|
|
657
|
+
- Updated dependencies [a275f78]
|
|
658
|
+
- Updated dependencies [605ace8]
|
|
659
|
+
- Updated dependencies [82cc3fa]
|
|
660
|
+
- Updated dependencies [0db7e81]
|
|
661
|
+
- Updated dependencies [2425281]
|
|
662
|
+
- Updated dependencies [6bb8035]
|
|
663
|
+
- Updated dependencies [bc15034]
|
|
664
|
+
- Updated dependencies [6273d6c]
|
|
665
|
+
- Updated dependencies [38866bc]
|
|
666
|
+
- Updated dependencies [1ce19c9]
|
|
667
|
+
- Updated dependencies [5c7d50f]
|
|
668
|
+
- Updated dependencies [7f8ab55]
|
|
669
|
+
- Updated dependencies [be611ae]
|
|
670
|
+
- Updated dependencies [c0f1190]
|
|
671
|
+
- Updated dependencies [b3d4383]
|
|
672
|
+
- Updated dependencies [6b11cac]
|
|
673
|
+
- Updated dependencies [a6dff38]
|
|
674
|
+
- Updated dependencies [54b013c]
|
|
675
|
+
- Updated dependencies [a8ef308]
|
|
676
|
+
- Updated dependencies [5996856]
|
|
677
|
+
- Updated dependencies [54174b6]
|
|
678
|
+
- Updated dependencies [4edad85]
|
|
679
|
+
- Updated dependencies [a428b54]
|
|
680
|
+
- Updated dependencies [94f353d]
|
|
681
|
+
- Updated dependencies [56da358]
|
|
682
|
+
- Updated dependencies [335f192]
|
|
683
|
+
- Updated dependencies [7b9de2d]
|
|
684
|
+
- Updated dependencies [21b6db7]
|
|
685
|
+
- Updated dependencies [1c8c3fc]
|
|
686
|
+
- Updated dependencies [ea54a64]
|
|
687
|
+
- Updated dependencies [c4209cb]
|
|
688
|
+
- Updated dependencies [6ea5171]
|
|
689
|
+
- Updated dependencies [a071085]
|
|
690
|
+
- Updated dependencies [505a75f]
|
|
691
|
+
- Updated dependencies [143613a]
|
|
692
|
+
- Updated dependencies [d7af897]
|
|
693
|
+
- Updated dependencies [955defa]
|
|
694
|
+
- Updated dependencies [1ee5335]
|
|
695
|
+
- Updated dependencies [27b827e]
|
|
696
|
+
- Updated dependencies [d02d059]
|
|
697
|
+
- Updated dependencies [ee08fa5]
|
|
698
|
+
- Updated dependencies [01d6e4e]
|
|
699
|
+
- Updated dependencies [813aea2]
|
|
700
|
+
- Updated dependencies [3558fbb]
|
|
701
|
+
- Updated dependencies [fa0ecbe]
|
|
702
|
+
- Updated dependencies [bffba0a]
|
|
703
|
+
- Updated dependencies [efc5cea]
|
|
704
|
+
- Updated dependencies [32e243f]
|
|
705
|
+
- Updated dependencies [233f856]
|
|
706
|
+
- Updated dependencies [4b0a7d7]
|
|
707
|
+
- Updated dependencies [5c9d69f]
|
|
708
|
+
- Updated dependencies [bbb538e]
|
|
709
|
+
- Updated dependencies [9c19d5e]
|
|
710
|
+
- Updated dependencies [bf9a262]
|
|
711
|
+
- Updated dependencies [b8eba2f]
|
|
712
|
+
- Updated dependencies [9fa373d]
|
|
713
|
+
- Updated dependencies [ded9e52]
|
|
714
|
+
- Updated dependencies [28f1f55]
|
|
715
|
+
- Updated dependencies [b2a1c61]
|
|
716
|
+
- Updated dependencies [b76089a]
|
|
717
|
+
- Updated dependencies [54242f0]
|
|
718
|
+
- Updated dependencies [ad10f82]
|
|
719
|
+
- Updated dependencies [222fd80]
|
|
720
|
+
- Updated dependencies [70cf20d]
|
|
721
|
+
- Updated dependencies [b75cc8e]
|
|
722
|
+
- Updated dependencies [6073365]
|
|
723
|
+
- Updated dependencies [46fcc7e]
|
|
724
|
+
- Updated dependencies [90f8ec4]
|
|
725
|
+
- Updated dependencies [a297730]
|
|
726
|
+
- Updated dependencies [38fd203]
|
|
727
|
+
- Updated dependencies [9ad34e0]
|
|
728
|
+
- Updated dependencies [1d34f51]
|
|
729
|
+
- Updated dependencies [534c866]
|
|
730
|
+
- Updated dependencies [80b29f6]
|
|
731
|
+
- Updated dependencies [0cef6a3]
|
|
732
|
+
- Updated dependencies [98ec291]
|
|
733
|
+
- @weasel-js/prefs@1.10.0
|
|
734
|
+
- @weasel-js/routing@1.10.0
|
|
735
|
+
- @weasel-js/geom@1.10.0
|
|
736
|
+
- @weasel-js/text@1.10.0
|
|
737
|
+
- @weasel-js/animator@1.10.0
|
|
738
|
+
- @weasel-js/font@1.10.0
|
|
739
|
+
- @weasel-js/renderer@1.10.0
|
|
740
|
+
- @weasel-js/text-dom@1.10.0
|
|
741
|
+
- @weasel-js/paint@1.10.0
|
|
742
|
+
- @weasel-js/history@1.10.0
|
|
743
|
+
- @weasel-js/cursor@1.10.0
|
|
744
|
+
- @weasel-js/gestures@1.10.0
|
|
745
|
+
- @weasel-js/quantity@1.10.0
|
|
746
|
+
- @weasel-js/react@1.10.0
|
|
747
|
+
- @weasel-js/modes@1.10.0
|
|
748
|
+
- @weasel-js/registry@1.10.0
|
|
749
|
+
- @weasel-js/simulation@1.10.0
|
|
750
|
+
- @weasel-js/stroke@1.10.0
|
|
751
|
+
- @weasel-js/select@1.10.0
|
|
752
|
+
|
|
3
753
|
## 1.9.4
|
|
4
754
|
|
|
5
755
|
### Patch Changes
|