@number10/jsx-core 5.0.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/LICENSE +667 -0
- package/README.md +38 -0
- package/dist/animation/animated-signal.cjs +19 -0
- package/dist/animation/animated-signal.cjs.map +1 -0
- package/dist/animation/animated-signal.d.ts +35 -0
- package/dist/animation/animated-signal.d.ts.map +1 -0
- package/dist/animation/animated-signal.js +19 -0
- package/dist/animation/animated-signal.js.map +1 -0
- package/dist/animation/create-spring.cjs +80 -0
- package/dist/animation/create-spring.cjs.map +1 -0
- package/dist/animation/create-spring.d.ts +56 -0
- package/dist/animation/create-spring.d.ts.map +1 -0
- package/dist/animation/create-spring.js +80 -0
- package/dist/animation/create-spring.js.map +1 -0
- package/dist/animation/easing.cjs +76 -0
- package/dist/animation/easing.cjs.map +1 -0
- package/dist/animation/easing.d.ts +45 -0
- package/dist/animation/easing.d.ts.map +1 -0
- package/dist/animation/easing.js +76 -0
- package/dist/animation/easing.js.map +1 -0
- package/dist/animation/effect-definitions.cjs +441 -0
- package/dist/animation/effect-definitions.cjs.map +1 -0
- package/dist/animation/effect-definitions.d.ts +60 -0
- package/dist/animation/effect-definitions.d.ts.map +1 -0
- package/dist/animation/effect-definitions.js +441 -0
- package/dist/animation/effect-definitions.js.map +1 -0
- package/dist/animation/effect-engine.cjs +189 -0
- package/dist/animation/effect-engine.cjs.map +1 -0
- package/dist/animation/effect-engine.d.ts +70 -0
- package/dist/animation/effect-engine.d.ts.map +1 -0
- package/dist/animation/effect-engine.js +189 -0
- package/dist/animation/effect-engine.js.map +1 -0
- package/dist/animation/index.d.ts +24 -0
- package/dist/animation/index.d.ts.map +1 -0
- package/dist/animation/spring-physics.cjs +94 -0
- package/dist/animation/spring-physics.cjs.map +1 -0
- package/dist/animation/spring-physics.d.ts +145 -0
- package/dist/animation/spring-physics.d.ts.map +1 -0
- package/dist/animation/spring-physics.js +94 -0
- package/dist/animation/spring-physics.js.map +1 -0
- package/dist/animation/tween.cjs +67 -0
- package/dist/animation/tween.cjs.map +1 -0
- package/dist/animation/tween.d.ts +60 -0
- package/dist/animation/tween.d.ts.map +1 -0
- package/dist/animation/tween.js +67 -0
- package/dist/animation/tween.js.map +1 -0
- package/dist/animation/types.d.ts +31 -0
- package/dist/animation/types.d.ts.map +1 -0
- package/dist/animation/useSpring.cjs +152 -0
- package/dist/animation/useSpring.cjs.map +1 -0
- package/dist/animation/useSpring.d.ts +55 -0
- package/dist/animation/useSpring.d.ts.map +1 -0
- package/dist/animation/useSpring.js +149 -0
- package/dist/animation/useSpring.js.map +1 -0
- package/dist/animation/useTween.cjs +208 -0
- package/dist/animation/useTween.cjs.map +1 -0
- package/dist/animation/useTween.d.ts +116 -0
- package/dist/animation/useTween.d.ts.map +1 -0
- package/dist/animation/useTween.js +208 -0
- package/dist/animation/useTween.js.map +1 -0
- package/dist/border-geometry.cjs +447 -0
- package/dist/border-geometry.cjs.map +1 -0
- package/dist/border-geometry.d.ts +114 -0
- package/dist/border-geometry.d.ts.map +1 -0
- package/dist/border-geometry.js +447 -0
- package/dist/border-geometry.js.map +1 -0
- package/dist/colors/color-presets.cjs +236 -0
- package/dist/colors/color-presets.cjs.map +1 -0
- package/dist/colors/color-presets.d.ts +89 -0
- package/dist/colors/color-presets.d.ts.map +1 -0
- package/dist/colors/color-presets.js +236 -0
- package/dist/colors/color-presets.js.map +1 -0
- package/dist/colors/color-theme-helpers.cjs +32 -0
- package/dist/colors/color-theme-helpers.cjs.map +1 -0
- package/dist/colors/color-theme-helpers.d.ts +65 -0
- package/dist/colors/color-theme-helpers.d.ts.map +1 -0
- package/dist/colors/color-theme-helpers.js +32 -0
- package/dist/colors/color-theme-helpers.js.map +1 -0
- package/dist/colors/color-types.cjs +38 -0
- package/dist/colors/color-types.cjs.map +1 -0
- package/dist/colors/color-types.d.ts +112 -0
- package/dist/colors/color-types.d.ts.map +1 -0
- package/dist/colors/color-types.js +38 -0
- package/dist/colors/color-types.js.map +1 -0
- package/dist/colors/color-utils.cjs +197 -0
- package/dist/colors/color-utils.cjs.map +1 -0
- package/dist/colors/color-utils.d.ts +216 -0
- package/dist/colors/color-utils.d.ts.map +1 -0
- package/dist/colors/color-utils.js +197 -0
- package/dist/colors/color-utils.js.map +1 -0
- package/dist/colors/contrast-contracts.cjs +265 -0
- package/dist/colors/contrast-contracts.cjs.map +1 -0
- package/dist/colors/contrast-contracts.d.ts +289 -0
- package/dist/colors/contrast-contracts.d.ts.map +1 -0
- package/dist/colors/contrast-contracts.js +265 -0
- package/dist/colors/contrast-contracts.js.map +1 -0
- package/dist/colors/index.cjs +55 -0
- package/dist/colors/index.cjs.map +1 -0
- package/dist/colors/index.d.ts +16 -0
- package/dist/colors/index.d.ts.map +1 -0
- package/dist/colors/index.js +55 -0
- package/dist/colors/index.js.map +1 -0
- package/dist/core-props.cjs +66 -0
- package/dist/core-props.cjs.map +1 -0
- package/dist/core-props.d.ts +395 -0
- package/dist/core-props.d.ts.map +1 -0
- package/dist/core-props.js +66 -0
- package/dist/core-props.js.map +1 -0
- package/dist/design-tokens/design-token-presets.cjs +91 -0
- package/dist/design-tokens/design-token-presets.cjs.map +1 -0
- package/dist/design-tokens/design-token-presets.d.ts +34 -0
- package/dist/design-tokens/design-token-presets.d.ts.map +1 -0
- package/dist/design-tokens/design-token-presets.js +91 -0
- package/dist/design-tokens/design-token-presets.js.map +1 -0
- package/dist/design-tokens/design-token-types.d.ts +97 -0
- package/dist/design-tokens/design-token-types.d.ts.map +1 -0
- package/dist/design-tokens/index.cjs +10 -0
- package/dist/design-tokens/index.cjs.map +1 -0
- package/dist/design-tokens/index.d.ts +9 -0
- package/dist/design-tokens/index.d.ts.map +1 -0
- package/dist/design-tokens/index.js +10 -0
- package/dist/design-tokens/index.js.map +1 -0
- package/dist/dev-config.cjs +296 -0
- package/dist/dev-config.cjs.map +1 -0
- package/dist/dev-config.d.ts +238 -0
- package/dist/dev-config.d.ts.map +1 -0
- package/dist/dev-config.js +296 -0
- package/dist/dev-config.js.map +1 -0
- package/dist/effects.cjs +69 -0
- package/dist/effects.cjs.map +1 -0
- package/dist/effects.d.ts +152 -0
- package/dist/effects.d.ts.map +1 -0
- package/dist/effects.js +69 -0
- package/dist/effects.js.map +1 -0
- package/dist/global-registry.cjs +25 -0
- package/dist/global-registry.cjs.map +1 -0
- package/dist/global-registry.d.ts +19 -0
- package/dist/global-registry.d.ts.map +1 -0
- package/dist/global-registry.js +25 -0
- package/dist/global-registry.js.map +1 -0
- package/dist/hooks.cjs +378 -0
- package/dist/hooks.cjs.map +1 -0
- package/dist/hooks.d.ts +322 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +378 -0
- package/dist/hooks.js.map +1 -0
- package/dist/host-adapter.d.ts +414 -0
- package/dist/host-adapter.d.ts.map +1 -0
- package/dist/index.cjs +229 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +226 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx-dev-runtime.cjs +10 -0
- package/dist/jsx-dev-runtime.cjs.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +5 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-dev-runtime.js +11 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime.cjs +44 -0
- package/dist/jsx-runtime.cjs.map +1 -0
- package/dist/jsx-runtime.d.ts +24 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +44 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/jsx-types.d.ts +25 -0
- package/dist/jsx-types.d.ts.map +1 -0
- package/dist/layout/appliers/container-applier.cjs +20 -0
- package/dist/layout/appliers/container-applier.cjs.map +1 -0
- package/dist/layout/appliers/container-applier.d.ts +9 -0
- package/dist/layout/appliers/container-applier.d.ts.map +1 -0
- package/dist/layout/appliers/container-applier.js +20 -0
- package/dist/layout/appliers/container-applier.js.map +1 -0
- package/dist/layout/appliers/position-applier.cjs +31 -0
- package/dist/layout/appliers/position-applier.cjs.map +1 -0
- package/dist/layout/appliers/position-applier.d.ts +8 -0
- package/dist/layout/appliers/position-applier.d.ts.map +1 -0
- package/dist/layout/appliers/position-applier.js +31 -0
- package/dist/layout/appliers/position-applier.js.map +1 -0
- package/dist/layout/layout-engine-test-utils.d.ts +26 -0
- package/dist/layout/layout-engine-test-utils.d.ts.map +1 -0
- package/dist/layout/layout-engine.cjs +628 -0
- package/dist/layout/layout-engine.cjs.map +1 -0
- package/dist/layout/layout-engine.d.ts +140 -0
- package/dist/layout/layout-engine.d.ts.map +1 -0
- package/dist/layout/layout-engine.js +628 -0
- package/dist/layout/layout-engine.js.map +1 -0
- package/dist/layout/strategies/base-strategy.cjs +31 -0
- package/dist/layout/strategies/base-strategy.cjs.map +1 -0
- package/dist/layout/strategies/base-strategy.d.ts +59 -0
- package/dist/layout/strategies/base-strategy.d.ts.map +1 -0
- package/dist/layout/strategies/base-strategy.js +31 -0
- package/dist/layout/strategies/base-strategy.js.map +1 -0
- package/dist/layout/strategies/column-layout.cjs +145 -0
- package/dist/layout/strategies/column-layout.cjs.map +1 -0
- package/dist/layout/strategies/column-layout.d.ts +38 -0
- package/dist/layout/strategies/column-layout.d.ts.map +1 -0
- package/dist/layout/strategies/column-layout.js +145 -0
- package/dist/layout/strategies/column-layout.js.map +1 -0
- package/dist/layout/strategies/row-layout.cjs +145 -0
- package/dist/layout/strategies/row-layout.cjs.map +1 -0
- package/dist/layout/strategies/row-layout.d.ts +38 -0
- package/dist/layout/strategies/row-layout.d.ts.map +1 -0
- package/dist/layout/strategies/row-layout.js +145 -0
- package/dist/layout/strategies/row-layout.js.map +1 -0
- package/dist/layout/strategies/stack-layout.cjs +94 -0
- package/dist/layout/strategies/stack-layout.cjs.map +1 -0
- package/dist/layout/strategies/stack-layout.d.ts +30 -0
- package/dist/layout/strategies/stack-layout.d.ts.map +1 -0
- package/dist/layout/strategies/stack-layout.js +94 -0
- package/dist/layout/strategies/stack-layout.js.map +1 -0
- package/dist/layout/types.d.ts +134 -0
- package/dist/layout/types.d.ts.map +1 -0
- package/dist/layout/utils/child-utils.cjs +129 -0
- package/dist/layout/utils/child-utils.cjs.map +1 -0
- package/dist/layout/utils/child-utils.d.ts +54 -0
- package/dist/layout/utils/child-utils.d.ts.map +1 -0
- package/dist/layout/utils/child-utils.js +129 -0
- package/dist/layout/utils/child-utils.js.map +1 -0
- package/dist/layout/utils/dimension-calculator.cjs +109 -0
- package/dist/layout/utils/dimension-calculator.cjs.map +1 -0
- package/dist/layout/utils/dimension-calculator.d.ts +59 -0
- package/dist/layout/utils/dimension-calculator.d.ts.map +1 -0
- package/dist/layout/utils/dimension-calculator.js +109 -0
- package/dist/layout/utils/dimension-calculator.js.map +1 -0
- package/dist/layout/utils/flex-distributor.cjs +173 -0
- package/dist/layout/utils/flex-distributor.cjs.map +1 -0
- package/dist/layout/utils/flex-distributor.d.ts +18 -0
- package/dist/layout/utils/flex-distributor.d.ts.map +1 -0
- package/dist/layout/utils/flex-distributor.js +173 -0
- package/dist/layout/utils/flex-distributor.js.map +1 -0
- package/dist/layout/utils/size-resolver.cjs +280 -0
- package/dist/layout/utils/size-resolver.cjs.map +1 -0
- package/dist/layout/utils/size-resolver.d.ts +84 -0
- package/dist/layout/utils/size-resolver.d.ts.map +1 -0
- package/dist/layout/utils/size-resolver.js +280 -0
- package/dist/layout/utils/size-resolver.js.map +1 -0
- package/dist/layout/utils/spacing-calculator.cjs +50 -0
- package/dist/layout/utils/spacing-calculator.cjs.map +1 -0
- package/dist/layout/utils/spacing-calculator.d.ts +27 -0
- package/dist/layout/utils/spacing-calculator.d.ts.map +1 -0
- package/dist/layout/utils/spacing-calculator.js +50 -0
- package/dist/layout/utils/spacing-calculator.js.map +1 -0
- package/dist/memo.cjs +18 -0
- package/dist/memo.cjs.map +1 -0
- package/dist/memo.d.ts +29 -0
- package/dist/memo.d.ts.map +1 -0
- package/dist/memo.js +18 -0
- package/dist/memo.js.map +1 -0
- package/dist/nineslice-contract.cjs +60 -0
- package/dist/nineslice-contract.cjs.map +1 -0
- package/dist/nineslice-contract.d.ts +107 -0
- package/dist/nineslice-contract.d.ts.map +1 -0
- package/dist/nineslice-contract.js +60 -0
- package/dist/nineslice-contract.js.map +1 -0
- package/dist/placeholder.cjs +12 -0
- package/dist/placeholder.cjs.map +1 -0
- package/dist/placeholder.d.ts +44 -0
- package/dist/placeholder.d.ts.map +1 -0
- package/dist/placeholder.js +12 -0
- package/dist/placeholder.js.map +1 -0
- package/dist/portal.cjs +89 -0
- package/dist/portal.cjs.map +1 -0
- package/dist/portal.d.ts +62 -0
- package/dist/portal.d.ts.map +1 -0
- package/dist/portal.js +89 -0
- package/dist/portal.js.map +1 -0
- package/dist/primitive-contracts.cjs +12 -0
- package/dist/primitive-contracts.cjs.map +1 -0
- package/dist/primitive-contracts.d.ts +186 -0
- package/dist/primitive-contracts.d.ts.map +1 -0
- package/dist/primitive-contracts.js +12 -0
- package/dist/primitive-contracts.js.map +1 -0
- package/dist/theme.cjs +332 -0
- package/dist/theme.cjs.map +1 -0
- package/dist/theme.d.ts +204 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +332 -0
- package/dist/theme.js.map +1 -0
- package/dist/types.d.ts +86 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/vdom/create-runtime.cjs +79 -0
- package/dist/vdom/create-runtime.cjs.map +1 -0
- package/dist/vdom/create-runtime.d.ts +7 -0
- package/dist/vdom/create-runtime.d.ts.map +1 -0
- package/dist/vdom/create-runtime.js +79 -0
- package/dist/vdom/create-runtime.js.map +1 -0
- package/dist/vdom/index.cjs +8 -0
- package/dist/vdom/index.cjs.map +1 -0
- package/dist/vdom/index.d.ts +4 -0
- package/dist/vdom/index.d.ts.map +1 -0
- package/dist/vdom/index.js +8 -0
- package/dist/vdom/index.js.map +1 -0
- package/dist/vdom/mount.cjs +161 -0
- package/dist/vdom/mount.cjs.map +1 -0
- package/dist/vdom/mount.d.ts +6 -0
- package/dist/vdom/mount.d.ts.map +1 -0
- package/dist/vdom/mount.js +161 -0
- package/dist/vdom/mount.js.map +1 -0
- package/dist/vdom/patch.cjs +163 -0
- package/dist/vdom/patch.cjs.map +1 -0
- package/dist/vdom/patch.d.ts +3 -0
- package/dist/vdom/patch.d.ts.map +1 -0
- package/dist/vdom/patch.js +163 -0
- package/dist/vdom/patch.js.map +1 -0
- package/dist/vdom/registry.cjs +85 -0
- package/dist/vdom/registry.cjs.map +1 -0
- package/dist/vdom/registry.d.ts +28 -0
- package/dist/vdom/registry.d.ts.map +1 -0
- package/dist/vdom/registry.js +85 -0
- package/dist/vdom/registry.js.map +1 -0
- package/dist/vdom/runtime-helpers.cjs +23 -0
- package/dist/vdom/runtime-helpers.cjs.map +1 -0
- package/dist/vdom/runtime-helpers.d.ts +8 -0
- package/dist/vdom/runtime-helpers.d.ts.map +1 -0
- package/dist/vdom/runtime-helpers.js +23 -0
- package/dist/vdom/runtime-helpers.js.map +1 -0
- package/dist/vdom/surface.cjs +107 -0
- package/dist/vdom/surface.cjs.map +1 -0
- package/dist/vdom/surface.d.ts +9 -0
- package/dist/vdom/surface.d.ts.map +1 -0
- package/dist/vdom/surface.js +107 -0
- package/dist/vdom/surface.js.map +1 -0
- package/dist/vdom/types.d.ts +104 -0
- package/dist/vdom/types.d.ts.map +1 -0
- package/dist/vdom/utils.cjs +146 -0
- package/dist/vdom/utils.cjs.map +1 -0
- package/dist/vdom/utils.d.ts +24 -0
- package/dist/vdom/utils.d.ts.map +1 -0
- package/dist/vdom/utils.js +146 -0
- package/dist/vdom/utils.js.map +1 -0
- package/dist/vdom.d.ts +4 -0
- package/dist/vdom.d.ts.map +1 -0
- package/dist/vector-draw-context.d.ts +63 -0
- package/dist/vector-draw-context.d.ts.map +1 -0
- package/package.json +161 -0
- package/vdom/index.cjs +1 -0
- package/vdom/index.d.ts +1 -0
- package/vdom/index.js +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# @number10/jsx-core
|
|
2
|
+
|
|
3
|
+
Renderer-neutral UI framework core — JSX runtime, Virtual DOM, hooks, theme engine, effects, and layout system for the PhaserJSX framework.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
/** @jsxImportSource @number10/jsx-core */
|
|
9
|
+
import { View, Text } from '@number10/jsx-components'
|
|
10
|
+
import { useState, useTheme } from '@number10/jsx-core'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This package provides the **foundation** for all PhaserJSX renderers. It has **no engine dependencies** — pair it with a renderer adapter to target a specific engine.
|
|
14
|
+
|
|
15
|
+
## What's included
|
|
16
|
+
|
|
17
|
+
- **JSX Runtime** — `jsx-runtime` and `jsx-dev-runtime` for TypeScript JSX support
|
|
18
|
+
- **Virtual DOM** — Renderer-neutral VDOM with per-context isolation and smart diffing
|
|
19
|
+
- **Hooks** — `useState`, `useEffect`, `useLayoutEffect`, `useRef`, `useMemo`, `useCallback`, `useReducer`, `useViewportSize`, `usePortalSurface`, `useTexture`, `useAtlas`
|
|
20
|
+
- **Theme Engine** — Global theme registry, nested theme propagation, design tokens, runtime switching
|
|
21
|
+
- **Effect Engine** — Penner easing, `Animatable<T>`, `useSpring`, `useTween`, `useTweens`, `AnimatedSignal`, custom effects
|
|
22
|
+
- **Layout Engine** — Flexbox-inspired with px, %, vw/vh, calc(), fill, auto, deferred layout queue
|
|
23
|
+
- **Portal System** — `Portal` component, `usePortalSurface` hook, per-context VDOM isolation
|
|
24
|
+
- **Vector Draw** — `VectorDrawContext` for renderer-agnostic canvas drawing
|
|
25
|
+
- **Texture System** — `TextureResolver`, portable `useTexture`/`useAtlas`
|
|
26
|
+
- **Border System** — `BorderPropsV2` with renderer capability detection
|
|
27
|
+
|
|
28
|
+
## Renderer integration
|
|
29
|
+
|
|
30
|
+
| Renderer | Package | Status |
|
|
31
|
+
| -------- | ---------------------- | ------- |
|
|
32
|
+
| Phaser 4 | `@number10/jsx-phaser` | ✅ Full |
|
|
33
|
+
| PixiJS 8 | `@number10/jsx-pixi` | ✅ Full |
|
|
34
|
+
| Konva | `@number10/jsx-konva` | ✅ Full |
|
|
35
|
+
|
|
36
|
+
## License
|
|
37
|
+
|
|
38
|
+
GPL-3.0-only
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const signalsCore = require("@preact/signals-core");
|
|
4
|
+
function animatedSignal(initialValue) {
|
|
5
|
+
const sig = signalsCore.signal(initialValue);
|
|
6
|
+
sig.__isAnimated = true;
|
|
7
|
+
return sig;
|
|
8
|
+
}
|
|
9
|
+
function isAnimatedSignal(value) {
|
|
10
|
+
return typeof value === "object" && value !== null && "__isAnimated" in value && value.__isAnimated === true;
|
|
11
|
+
}
|
|
12
|
+
function unwrapSignal(value) {
|
|
13
|
+
if (value === void 0) return void 0;
|
|
14
|
+
return isAnimatedSignal(value) ? value.value : value;
|
|
15
|
+
}
|
|
16
|
+
exports.animatedSignal = animatedSignal;
|
|
17
|
+
exports.isAnimatedSignal = isAnimatedSignal;
|
|
18
|
+
exports.unwrapSignal = unwrapSignal;
|
|
19
|
+
//# sourceMappingURL=animated-signal.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animated-signal.cjs","sources":["../../src/animation/animated-signal.ts"],"sourcesContent":["/**\n * Signal-based animation utilities\n * Provides reactive signals that trigger direct DOM updates without VDOM traversal\n *\n * @migration(audit:surface-access) Phase 7 — moved to @number10/jsx-core ✅\n */\nimport { signal, type Signal } from '@preact/signals-core'\n\n/**\n * Animated signal that holds a numeric value\n * Can be used in JSX props for direct updates without VDOM\n */\nexport interface AnimatedSignal extends Signal<number> {\n /** Mark as animated signal for VDOM detection */\n __isAnimated: true\n}\n\n/**\n * Creates an animated signal\n * @param initialValue - Initial numeric value\n * @returns Animated signal\n */\nexport function animatedSignal(initialValue: number): AnimatedSignal {\n const sig = signal(initialValue) as AnimatedSignal\n sig.__isAnimated = true\n return sig\n}\n\n/**\n * Type guard to check if value is an animated signal\n * @param value - Value to check\n * @returns True if value is an animated signal\n */\nexport function isAnimatedSignal(value: unknown): value is AnimatedSignal {\n return (\n typeof value === 'object' &&\n value !== null &&\n '__isAnimated' in value &&\n (value as AnimatedSignal).__isAnimated === true\n )\n}\n\n/**\n * Unwraps signal value or returns raw value\n * Type-safe overloads ensure correct return types\n * @param value - Signal or raw value\n * @returns Unwrapped value\n */\nfunction unwrapSignal(value: AnimatedSignal): number\nfunction unwrapSignal(value: number): number\nfunction unwrapSignal(value: string): string\nfunction unwrapSignal(value: number | AnimatedSignal): number\nfunction unwrapSignal(value: string | AnimatedSignal): string | number\nfunction unwrapSignal(value: number | string | AnimatedSignal): number | string\nfunction unwrapSignal(\n value: number | string | AnimatedSignal | undefined\n): number | string | undefined {\n if (value === undefined) return undefined\n return isAnimatedSignal(value) ? value.value : value\n}\n\nexport { unwrapSignal }\n"],"names":["signal"],"mappings":";;;AAsBO,SAAS,eAAe,cAAsC;AACnE,QAAM,MAAMA,YAAAA,OAAO,YAAY;AAC/B,MAAI,eAAe;AACnB,SAAO;AACT;AAOO,SAAS,iBAAiB,OAAyC;AACxE,SACE,OAAO,UAAU,YACjB,UAAU,QACV,kBAAkB,SACjB,MAAyB,iBAAiB;AAE/C;AAcA,SAAS,aACP,OAC6B;AAC7B,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO,iBAAiB,KAAK,IAAI,MAAM,QAAQ;AACjD;;;;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Signal } from '@preact/signals-core';
|
|
2
|
+
/**
|
|
3
|
+
* Animated signal that holds a numeric value
|
|
4
|
+
* Can be used in JSX props for direct updates without VDOM
|
|
5
|
+
*/
|
|
6
|
+
export interface AnimatedSignal extends Signal<number> {
|
|
7
|
+
/** Mark as animated signal for VDOM detection */
|
|
8
|
+
__isAnimated: true;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Creates an animated signal
|
|
12
|
+
* @param initialValue - Initial numeric value
|
|
13
|
+
* @returns Animated signal
|
|
14
|
+
*/
|
|
15
|
+
export declare function animatedSignal(initialValue: number): AnimatedSignal;
|
|
16
|
+
/**
|
|
17
|
+
* Type guard to check if value is an animated signal
|
|
18
|
+
* @param value - Value to check
|
|
19
|
+
* @returns True if value is an animated signal
|
|
20
|
+
*/
|
|
21
|
+
export declare function isAnimatedSignal(value: unknown): value is AnimatedSignal;
|
|
22
|
+
/**
|
|
23
|
+
* Unwraps signal value or returns raw value
|
|
24
|
+
* Type-safe overloads ensure correct return types
|
|
25
|
+
* @param value - Signal or raw value
|
|
26
|
+
* @returns Unwrapped value
|
|
27
|
+
*/
|
|
28
|
+
declare function unwrapSignal(value: AnimatedSignal): number;
|
|
29
|
+
declare function unwrapSignal(value: number): number;
|
|
30
|
+
declare function unwrapSignal(value: string): string;
|
|
31
|
+
declare function unwrapSignal(value: number | AnimatedSignal): number;
|
|
32
|
+
declare function unwrapSignal(value: string | AnimatedSignal): string | number;
|
|
33
|
+
declare function unwrapSignal(value: number | string | AnimatedSignal): number | string;
|
|
34
|
+
export { unwrapSignal };
|
|
35
|
+
//# sourceMappingURL=animated-signal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animated-signal.d.ts","sourceRoot":"","sources":["../../src/animation/animated-signal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAE1D;;;GAGG;AACH,MAAM,WAAW,cAAe,SAAQ,MAAM,CAAC,MAAM,CAAC;IACpD,iDAAiD;IACjD,YAAY,EAAE,IAAI,CAAA;CACnB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,CAInE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAOxE;AAED;;;;;GAKG;AACH,iBAAS,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAAA;AACpD,iBAAS,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;AAC5C,iBAAS,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;AAC5C,iBAAS,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,MAAM,CAAA;AAC7D,iBAAS,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,CAAA;AACtE,iBAAS,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,CAAA;AAQ/E,OAAO,EAAE,YAAY,EAAE,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { signal } from "@preact/signals-core";
|
|
2
|
+
function animatedSignal(initialValue) {
|
|
3
|
+
const sig = signal(initialValue);
|
|
4
|
+
sig.__isAnimated = true;
|
|
5
|
+
return sig;
|
|
6
|
+
}
|
|
7
|
+
function isAnimatedSignal(value) {
|
|
8
|
+
return typeof value === "object" && value !== null && "__isAnimated" in value && value.__isAnimated === true;
|
|
9
|
+
}
|
|
10
|
+
function unwrapSignal(value) {
|
|
11
|
+
if (value === void 0) return void 0;
|
|
12
|
+
return isAnimatedSignal(value) ? value.value : value;
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
animatedSignal,
|
|
16
|
+
isAnimatedSignal,
|
|
17
|
+
unwrapSignal
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=animated-signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animated-signal.js","sources":["../../src/animation/animated-signal.ts"],"sourcesContent":["/**\n * Signal-based animation utilities\n * Provides reactive signals that trigger direct DOM updates without VDOM traversal\n *\n * @migration(audit:surface-access) Phase 7 — moved to @number10/jsx-core ✅\n */\nimport { signal, type Signal } from '@preact/signals-core'\n\n/**\n * Animated signal that holds a numeric value\n * Can be used in JSX props for direct updates without VDOM\n */\nexport interface AnimatedSignal extends Signal<number> {\n /** Mark as animated signal for VDOM detection */\n __isAnimated: true\n}\n\n/**\n * Creates an animated signal\n * @param initialValue - Initial numeric value\n * @returns Animated signal\n */\nexport function animatedSignal(initialValue: number): AnimatedSignal {\n const sig = signal(initialValue) as AnimatedSignal\n sig.__isAnimated = true\n return sig\n}\n\n/**\n * Type guard to check if value is an animated signal\n * @param value - Value to check\n * @returns True if value is an animated signal\n */\nexport function isAnimatedSignal(value: unknown): value is AnimatedSignal {\n return (\n typeof value === 'object' &&\n value !== null &&\n '__isAnimated' in value &&\n (value as AnimatedSignal).__isAnimated === true\n )\n}\n\n/**\n * Unwraps signal value or returns raw value\n * Type-safe overloads ensure correct return types\n * @param value - Signal or raw value\n * @returns Unwrapped value\n */\nfunction unwrapSignal(value: AnimatedSignal): number\nfunction unwrapSignal(value: number): number\nfunction unwrapSignal(value: string): string\nfunction unwrapSignal(value: number | AnimatedSignal): number\nfunction unwrapSignal(value: string | AnimatedSignal): string | number\nfunction unwrapSignal(value: number | string | AnimatedSignal): number | string\nfunction unwrapSignal(\n value: number | string | AnimatedSignal | undefined\n): number | string | undefined {\n if (value === undefined) return undefined\n return isAnimatedSignal(value) ? value.value : value\n}\n\nexport { unwrapSignal }\n"],"names":[],"mappings":";AAsBO,SAAS,eAAe,cAAsC;AACnE,QAAM,MAAM,OAAO,YAAY;AAC/B,MAAI,eAAe;AACnB,SAAO;AACT;AAOO,SAAS,iBAAiB,OAAyC;AACxE,SACE,OAAO,UAAU,YACjB,UAAU,QACV,kBAAkB,SACjB,MAAyB,iBAAiB;AAE/C;AAcA,SAAS,aACP,OAC6B;AAC7B,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO,iBAAiB,KAAK,IAAI,MAAM,QAAQ;AACjD;"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const springPhysics = require("./spring-physics.cjs");
|
|
4
|
+
function createSpring(initial, config, scheduler) {
|
|
5
|
+
const target = { ...initial };
|
|
6
|
+
const keys = Object.keys(config.to);
|
|
7
|
+
const springConfig = typeof config.config === "string" ? { ...springPhysics.SPRING_PRESETS[config.config] ?? springPhysics.SPRING_PRESETS.default } : config.config ?? {};
|
|
8
|
+
const properties = /* @__PURE__ */ new Map();
|
|
9
|
+
for (const key of keys) {
|
|
10
|
+
const initialVal = initial[key];
|
|
11
|
+
properties.set(key, {
|
|
12
|
+
physics: new springPhysics.SpringPhysics(springConfig),
|
|
13
|
+
state: { value: initialVal, velocity: 0 },
|
|
14
|
+
target: config.to[key]
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
let frameHandle = null;
|
|
18
|
+
let completed = false;
|
|
19
|
+
if (keys.length === 0) {
|
|
20
|
+
config.onUpdate?.(target);
|
|
21
|
+
config.onComplete?.();
|
|
22
|
+
return {
|
|
23
|
+
target,
|
|
24
|
+
stop: () => {
|
|
25
|
+
},
|
|
26
|
+
isActive: false
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
frameHandle = scheduler.onFrame((delta) => {
|
|
30
|
+
if (completed) return;
|
|
31
|
+
const deltaSeconds = delta / 1e3;
|
|
32
|
+
let allAtRest = true;
|
|
33
|
+
for (const key of keys) {
|
|
34
|
+
const prop = properties.get(key);
|
|
35
|
+
if (!prop) continue;
|
|
36
|
+
const newState = prop.physics.step(prop.state, prop.target, deltaSeconds);
|
|
37
|
+
prop.state = newState;
|
|
38
|
+
target[key] = newState.value;
|
|
39
|
+
if (!prop.physics.isAtRest(newState, prop.target)) {
|
|
40
|
+
allAtRest = false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (allAtRest) {
|
|
44
|
+
for (const key of keys) {
|
|
45
|
+
const prop = properties.get(key);
|
|
46
|
+
if (!prop) continue;
|
|
47
|
+
const snapped = prop.physics.snapIfAtRest(prop.state, prop.target);
|
|
48
|
+
if (snapped.value !== prop.state.value) {
|
|
49
|
+
prop.state = snapped;
|
|
50
|
+
target[key] = snapped.value;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
config.onUpdate?.(target);
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
if (allAtRest) {
|
|
59
|
+
completed = true;
|
|
60
|
+
frameHandle?.cancel();
|
|
61
|
+
try {
|
|
62
|
+
config.onComplete?.();
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
target,
|
|
69
|
+
stop: () => {
|
|
70
|
+
if (completed) return;
|
|
71
|
+
completed = true;
|
|
72
|
+
frameHandle?.cancel();
|
|
73
|
+
},
|
|
74
|
+
get isActive() {
|
|
75
|
+
return !completed;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
exports.createSpring = createSpring;
|
|
80
|
+
//# sourceMappingURL=create-spring.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-spring.cjs","sources":["../../src/animation/create-spring.ts"],"sourcesContent":["/**\n * Imperative spring animation — renderer-neutral, cancellable multi-value spring.\n *\n * Counterpart to createTween. Uses SpringPhysics internally, driven by\n * HostScheduler.onFrame(). Returns a handle with stop() and isActive.\n *\n * This is the imperative primitive that enables spring-based effect steps\n * in the effect engine (Phase G).\n */\n\nimport type { HostCancelHandle, HostScheduler } from '../host-adapter'\nimport {\n SPRING_PRESETS,\n SpringPhysics,\n type AnimationPreset,\n type SpringConfig,\n type SpringState,\n} from './spring-physics'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Configuration for a spring animation.\n * @typeParam T - Record of numeric properties to animate\n */\nexport interface SpringAnimationConfig<T extends Record<string, number>> {\n /** Target values (partial — only specified keys are animated) */\n to: Partial<T>\n /** Spring configuration (preset name or custom config). Default: 'default' */\n config?: SpringConfig | AnimationPreset | undefined\n /** Called every frame with the current interpolated target */\n onUpdate?: ((target: T) => void) | undefined\n /** Called when all properties reach rest (not called on stop()) */\n onComplete?: (() => void) | undefined\n}\n\n/**\n * Handle to an active spring animation.\n */\nexport interface SpringHandle<T extends Record<string, number> = Record<string, number>> {\n /** Current animated state (mutated each frame) */\n readonly target: Readonly<T>\n /** Stop the animation immediately. onComplete is NOT called. */\n stop(): void\n /** Whether the animation is still running */\n readonly isActive: boolean\n}\n\n// ---------------------------------------------------------------------------\n// Internal state per property\n// ---------------------------------------------------------------------------\n\ninterface SpringPropertyState {\n physics: SpringPhysics\n state: SpringState\n target: number\n}\n\n// ---------------------------------------------------------------------------\n// createSpring\n// ---------------------------------------------------------------------------\n\n/**\n * Start a spring physics animation.\n *\n * Animates numeric properties of a plain object from their current values\n * to the specified target values using spring-damper physics.\n * Each property has its own spring but shares the same configuration.\n *\n * @param initial - Starting values for all animated properties\n * @param config - Animation configuration (target, spring config, callbacks)\n * @param scheduler - HostScheduler for frame updates (from SurfaceContext)\n * @returns SpringHandle for tracking and cancellation\n *\n * @example\n * ```typescript\n * const spring = createSpring(\n * { x: 0, y: 0 },\n * {\n * to: { x: 100, y: 50 },\n * config: 'wobbly',\n * onUpdate: (t) => updatePosition(t.x, t.y),\n * onComplete: () => console.log('done'),\n * },\n * scheduler,\n * )\n * // later: spring.stop()\n * ```\n */\nexport function createSpring<T extends Record<string, number>>(\n initial: T,\n config: SpringAnimationConfig<T>,\n scheduler: HostScheduler\n): SpringHandle<T> {\n const target = { ...initial } as T\n const keys = Object.keys(config.to) as (keyof T)[]\n\n // Resolve spring config\n const springConfig: SpringConfig =\n typeof config.config === 'string'\n ? { ...(SPRING_PRESETS[config.config as AnimationPreset] ?? SPRING_PRESETS.default) }\n : (config.config ?? {})\n\n // Create per-property spring states\n const properties = new Map<keyof T, SpringPropertyState>()\n for (const key of keys) {\n const initialVal = initial[key] as number\n properties.set(key, {\n physics: new SpringPhysics(springConfig),\n state: { value: initialVal, velocity: 0 },\n target: config.to[key] as number,\n })\n }\n\n let frameHandle: HostCancelHandle | null = null\n let completed = false\n\n // Handle empty/zero-key case\n if (keys.length === 0) {\n config.onUpdate?.(target)\n config.onComplete?.()\n return {\n target,\n stop: () => {},\n isActive: false,\n }\n }\n\n frameHandle = scheduler.onFrame((delta: number) => {\n if (completed) return\n\n const deltaSeconds = delta / 1000\n let allAtRest = true\n\n // Step each property\n for (const key of keys) {\n const prop = properties.get(key)\n if (!prop) continue\n\n const newState = prop.physics.step(prop.state, prop.target, deltaSeconds)\n prop.state = newState\n\n // Update the target object\n ;(target as Record<string, number>)[key as string] = newState.value\n\n // Check if at rest\n if (!prop.physics.isAtRest(newState, prop.target)) {\n allAtRest = false\n }\n }\n\n // Snap to exact target values if all at rest\n if (allAtRest) {\n for (const key of keys) {\n const prop = properties.get(key)\n if (!prop) continue\n const snapped = prop.physics.snapIfAtRest(prop.state, prop.target)\n if (snapped.value !== prop.state.value) {\n prop.state = snapped\n ;(target as Record<string, number>)[key as string] = snapped.value\n }\n }\n }\n\n // Fire onUpdate\n try {\n config.onUpdate?.(target)\n } catch {\n // Swallow onUpdate errors — don't break the animation loop\n }\n\n // If all at rest, complete\n if (allAtRest) {\n completed = true\n frameHandle?.cancel()\n try {\n config.onComplete?.()\n } catch {\n // Swallow onComplete errors\n }\n }\n })\n\n return {\n target,\n stop: () => {\n if (completed) return\n completed = true\n frameHandle?.cancel()\n },\n get isActive(): boolean {\n return !completed\n },\n }\n}\n"],"names":["SPRING_PRESETS","SpringPhysics"],"mappings":";;;AA2FO,SAAS,aACd,SACA,QACA,WACiB;AACjB,QAAM,SAAS,EAAE,GAAG,QAAA;AACpB,QAAM,OAAO,OAAO,KAAK,OAAO,EAAE;AAGlC,QAAM,eACJ,OAAO,OAAO,WAAW,WACrB,EAAE,GAAIA,cAAAA,eAAe,OAAO,MAAyB,KAAKA,cAAAA,eAAe,QAAA,IACxE,OAAO,UAAU,CAAA;AAGxB,QAAM,iCAAiB,IAAA;AACvB,aAAW,OAAO,MAAM;AACtB,UAAM,aAAa,QAAQ,GAAG;AAC9B,eAAW,IAAI,KAAK;AAAA,MAClB,SAAS,IAAIC,cAAAA,cAAc,YAAY;AAAA,MACvC,OAAO,EAAE,OAAO,YAAY,UAAU,EAAA;AAAA,MACtC,QAAQ,OAAO,GAAG,GAAG;AAAA,IAAA,CACtB;AAAA,EACH;AAEA,MAAI,cAAuC;AAC3C,MAAI,YAAY;AAGhB,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO,WAAW,MAAM;AACxB,WAAO,aAAA;AACP,WAAO;AAAA,MACL;AAAA,MACA,MAAM,MAAM;AAAA,MAAC;AAAA,MACb,UAAU;AAAA,IAAA;AAAA,EAEd;AAEA,gBAAc,UAAU,QAAQ,CAAC,UAAkB;AACjD,QAAI,UAAW;AAEf,UAAM,eAAe,QAAQ;AAC7B,QAAI,YAAY;AAGhB,eAAW,OAAO,MAAM;AACtB,YAAM,OAAO,WAAW,IAAI,GAAG;AAC/B,UAAI,CAAC,KAAM;AAEX,YAAM,WAAW,KAAK,QAAQ,KAAK,KAAK,OAAO,KAAK,QAAQ,YAAY;AACxE,WAAK,QAAQ;AAGX,aAAkC,GAAa,IAAI,SAAS;AAG9D,UAAI,CAAC,KAAK,QAAQ,SAAS,UAAU,KAAK,MAAM,GAAG;AACjD,oBAAY;AAAA,MACd;AAAA,IACF;AAGA,QAAI,WAAW;AACb,iBAAW,OAAO,MAAM;AACtB,cAAM,OAAO,WAAW,IAAI,GAAG;AAC/B,YAAI,CAAC,KAAM;AACX,cAAM,UAAU,KAAK,QAAQ,aAAa,KAAK,OAAO,KAAK,MAAM;AACjE,YAAI,QAAQ,UAAU,KAAK,MAAM,OAAO;AACtC,eAAK,QAAQ;AACX,iBAAkC,GAAa,IAAI,QAAQ;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAGA,QAAI;AACF,aAAO,WAAW,MAAM;AAAA,IAC1B,QAAQ;AAAA,IAER;AAGA,QAAI,WAAW;AACb,kBAAY;AACZ,mBAAa,OAAA;AACb,UAAI;AACF,eAAO,aAAA;AAAA,MACT,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,MAAM,MAAM;AACV,UAAI,UAAW;AACf,kBAAY;AACZ,mBAAa,OAAA;AAAA,IACf;AAAA,IACA,IAAI,WAAoB;AACtB,aAAO,CAAC;AAAA,IACV;AAAA,EAAA;AAEJ;;"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { HostScheduler } from '../host-adapter';
|
|
2
|
+
import { AnimationPreset, SpringConfig } from './spring-physics';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for a spring animation.
|
|
5
|
+
* @typeParam T - Record of numeric properties to animate
|
|
6
|
+
*/
|
|
7
|
+
export interface SpringAnimationConfig<T extends Record<string, number>> {
|
|
8
|
+
/** Target values (partial — only specified keys are animated) */
|
|
9
|
+
to: Partial<T>;
|
|
10
|
+
/** Spring configuration (preset name or custom config). Default: 'default' */
|
|
11
|
+
config?: SpringConfig | AnimationPreset | undefined;
|
|
12
|
+
/** Called every frame with the current interpolated target */
|
|
13
|
+
onUpdate?: ((target: T) => void) | undefined;
|
|
14
|
+
/** Called when all properties reach rest (not called on stop()) */
|
|
15
|
+
onComplete?: (() => void) | undefined;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Handle to an active spring animation.
|
|
19
|
+
*/
|
|
20
|
+
export interface SpringHandle<T extends Record<string, number> = Record<string, number>> {
|
|
21
|
+
/** Current animated state (mutated each frame) */
|
|
22
|
+
readonly target: Readonly<T>;
|
|
23
|
+
/** Stop the animation immediately. onComplete is NOT called. */
|
|
24
|
+
stop(): void;
|
|
25
|
+
/** Whether the animation is still running */
|
|
26
|
+
readonly isActive: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Start a spring physics animation.
|
|
30
|
+
*
|
|
31
|
+
* Animates numeric properties of a plain object from their current values
|
|
32
|
+
* to the specified target values using spring-damper physics.
|
|
33
|
+
* Each property has its own spring but shares the same configuration.
|
|
34
|
+
*
|
|
35
|
+
* @param initial - Starting values for all animated properties
|
|
36
|
+
* @param config - Animation configuration (target, spring config, callbacks)
|
|
37
|
+
* @param scheduler - HostScheduler for frame updates (from SurfaceContext)
|
|
38
|
+
* @returns SpringHandle for tracking and cancellation
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const spring = createSpring(
|
|
43
|
+
* { x: 0, y: 0 },
|
|
44
|
+
* {
|
|
45
|
+
* to: { x: 100, y: 50 },
|
|
46
|
+
* config: 'wobbly',
|
|
47
|
+
* onUpdate: (t) => updatePosition(t.x, t.y),
|
|
48
|
+
* onComplete: () => console.log('done'),
|
|
49
|
+
* },
|
|
50
|
+
* scheduler,
|
|
51
|
+
* )
|
|
52
|
+
* // later: spring.stop()
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function createSpring<T extends Record<string, number>>(initial: T, config: SpringAnimationConfig<T>, scheduler: HostScheduler): SpringHandle<T>;
|
|
56
|
+
//# sourceMappingURL=create-spring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-spring.d.ts","sourceRoot":"","sources":["../../src/animation/create-spring.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAoB,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,YAAY,EAElB,MAAM,kBAAkB,CAAA;AAMzB;;;GAGG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IACrE,iEAAiE;IACjE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;IACd,8EAA8E;IAC9E,MAAM,CAAC,EAAE,YAAY,GAAG,eAAe,GAAG,SAAS,CAAA;IACnD,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC5C,mEAAmE;IACnE,UAAU,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAA;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IACrF,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC5B,gEAAgE;IAChE,IAAI,IAAI,IAAI,CAAA;IACZ,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC3B;AAgBD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3D,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAChC,SAAS,EAAE,aAAa,GACvB,YAAY,CAAC,CAAC,CAAC,CAqGjB"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { SPRING_PRESETS, SpringPhysics } from "./spring-physics.js";
|
|
2
|
+
function createSpring(initial, config, scheduler) {
|
|
3
|
+
const target = { ...initial };
|
|
4
|
+
const keys = Object.keys(config.to);
|
|
5
|
+
const springConfig = typeof config.config === "string" ? { ...SPRING_PRESETS[config.config] ?? SPRING_PRESETS.default } : config.config ?? {};
|
|
6
|
+
const properties = /* @__PURE__ */ new Map();
|
|
7
|
+
for (const key of keys) {
|
|
8
|
+
const initialVal = initial[key];
|
|
9
|
+
properties.set(key, {
|
|
10
|
+
physics: new SpringPhysics(springConfig),
|
|
11
|
+
state: { value: initialVal, velocity: 0 },
|
|
12
|
+
target: config.to[key]
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
let frameHandle = null;
|
|
16
|
+
let completed = false;
|
|
17
|
+
if (keys.length === 0) {
|
|
18
|
+
config.onUpdate?.(target);
|
|
19
|
+
config.onComplete?.();
|
|
20
|
+
return {
|
|
21
|
+
target,
|
|
22
|
+
stop: () => {
|
|
23
|
+
},
|
|
24
|
+
isActive: false
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
frameHandle = scheduler.onFrame((delta) => {
|
|
28
|
+
if (completed) return;
|
|
29
|
+
const deltaSeconds = delta / 1e3;
|
|
30
|
+
let allAtRest = true;
|
|
31
|
+
for (const key of keys) {
|
|
32
|
+
const prop = properties.get(key);
|
|
33
|
+
if (!prop) continue;
|
|
34
|
+
const newState = prop.physics.step(prop.state, prop.target, deltaSeconds);
|
|
35
|
+
prop.state = newState;
|
|
36
|
+
target[key] = newState.value;
|
|
37
|
+
if (!prop.physics.isAtRest(newState, prop.target)) {
|
|
38
|
+
allAtRest = false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (allAtRest) {
|
|
42
|
+
for (const key of keys) {
|
|
43
|
+
const prop = properties.get(key);
|
|
44
|
+
if (!prop) continue;
|
|
45
|
+
const snapped = prop.physics.snapIfAtRest(prop.state, prop.target);
|
|
46
|
+
if (snapped.value !== prop.state.value) {
|
|
47
|
+
prop.state = snapped;
|
|
48
|
+
target[key] = snapped.value;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
config.onUpdate?.(target);
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
if (allAtRest) {
|
|
57
|
+
completed = true;
|
|
58
|
+
frameHandle?.cancel();
|
|
59
|
+
try {
|
|
60
|
+
config.onComplete?.();
|
|
61
|
+
} catch {
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
66
|
+
target,
|
|
67
|
+
stop: () => {
|
|
68
|
+
if (completed) return;
|
|
69
|
+
completed = true;
|
|
70
|
+
frameHandle?.cancel();
|
|
71
|
+
},
|
|
72
|
+
get isActive() {
|
|
73
|
+
return !completed;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
createSpring
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=create-spring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-spring.js","sources":["../../src/animation/create-spring.ts"],"sourcesContent":["/**\n * Imperative spring animation — renderer-neutral, cancellable multi-value spring.\n *\n * Counterpart to createTween. Uses SpringPhysics internally, driven by\n * HostScheduler.onFrame(). Returns a handle with stop() and isActive.\n *\n * This is the imperative primitive that enables spring-based effect steps\n * in the effect engine (Phase G).\n */\n\nimport type { HostCancelHandle, HostScheduler } from '../host-adapter'\nimport {\n SPRING_PRESETS,\n SpringPhysics,\n type AnimationPreset,\n type SpringConfig,\n type SpringState,\n} from './spring-physics'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Configuration for a spring animation.\n * @typeParam T - Record of numeric properties to animate\n */\nexport interface SpringAnimationConfig<T extends Record<string, number>> {\n /** Target values (partial — only specified keys are animated) */\n to: Partial<T>\n /** Spring configuration (preset name or custom config). Default: 'default' */\n config?: SpringConfig | AnimationPreset | undefined\n /** Called every frame with the current interpolated target */\n onUpdate?: ((target: T) => void) | undefined\n /** Called when all properties reach rest (not called on stop()) */\n onComplete?: (() => void) | undefined\n}\n\n/**\n * Handle to an active spring animation.\n */\nexport interface SpringHandle<T extends Record<string, number> = Record<string, number>> {\n /** Current animated state (mutated each frame) */\n readonly target: Readonly<T>\n /** Stop the animation immediately. onComplete is NOT called. */\n stop(): void\n /** Whether the animation is still running */\n readonly isActive: boolean\n}\n\n// ---------------------------------------------------------------------------\n// Internal state per property\n// ---------------------------------------------------------------------------\n\ninterface SpringPropertyState {\n physics: SpringPhysics\n state: SpringState\n target: number\n}\n\n// ---------------------------------------------------------------------------\n// createSpring\n// ---------------------------------------------------------------------------\n\n/**\n * Start a spring physics animation.\n *\n * Animates numeric properties of a plain object from their current values\n * to the specified target values using spring-damper physics.\n * Each property has its own spring but shares the same configuration.\n *\n * @param initial - Starting values for all animated properties\n * @param config - Animation configuration (target, spring config, callbacks)\n * @param scheduler - HostScheduler for frame updates (from SurfaceContext)\n * @returns SpringHandle for tracking and cancellation\n *\n * @example\n * ```typescript\n * const spring = createSpring(\n * { x: 0, y: 0 },\n * {\n * to: { x: 100, y: 50 },\n * config: 'wobbly',\n * onUpdate: (t) => updatePosition(t.x, t.y),\n * onComplete: () => console.log('done'),\n * },\n * scheduler,\n * )\n * // later: spring.stop()\n * ```\n */\nexport function createSpring<T extends Record<string, number>>(\n initial: T,\n config: SpringAnimationConfig<T>,\n scheduler: HostScheduler\n): SpringHandle<T> {\n const target = { ...initial } as T\n const keys = Object.keys(config.to) as (keyof T)[]\n\n // Resolve spring config\n const springConfig: SpringConfig =\n typeof config.config === 'string'\n ? { ...(SPRING_PRESETS[config.config as AnimationPreset] ?? SPRING_PRESETS.default) }\n : (config.config ?? {})\n\n // Create per-property spring states\n const properties = new Map<keyof T, SpringPropertyState>()\n for (const key of keys) {\n const initialVal = initial[key] as number\n properties.set(key, {\n physics: new SpringPhysics(springConfig),\n state: { value: initialVal, velocity: 0 },\n target: config.to[key] as number,\n })\n }\n\n let frameHandle: HostCancelHandle | null = null\n let completed = false\n\n // Handle empty/zero-key case\n if (keys.length === 0) {\n config.onUpdate?.(target)\n config.onComplete?.()\n return {\n target,\n stop: () => {},\n isActive: false,\n }\n }\n\n frameHandle = scheduler.onFrame((delta: number) => {\n if (completed) return\n\n const deltaSeconds = delta / 1000\n let allAtRest = true\n\n // Step each property\n for (const key of keys) {\n const prop = properties.get(key)\n if (!prop) continue\n\n const newState = prop.physics.step(prop.state, prop.target, deltaSeconds)\n prop.state = newState\n\n // Update the target object\n ;(target as Record<string, number>)[key as string] = newState.value\n\n // Check if at rest\n if (!prop.physics.isAtRest(newState, prop.target)) {\n allAtRest = false\n }\n }\n\n // Snap to exact target values if all at rest\n if (allAtRest) {\n for (const key of keys) {\n const prop = properties.get(key)\n if (!prop) continue\n const snapped = prop.physics.snapIfAtRest(prop.state, prop.target)\n if (snapped.value !== prop.state.value) {\n prop.state = snapped\n ;(target as Record<string, number>)[key as string] = snapped.value\n }\n }\n }\n\n // Fire onUpdate\n try {\n config.onUpdate?.(target)\n } catch {\n // Swallow onUpdate errors — don't break the animation loop\n }\n\n // If all at rest, complete\n if (allAtRest) {\n completed = true\n frameHandle?.cancel()\n try {\n config.onComplete?.()\n } catch {\n // Swallow onComplete errors\n }\n }\n })\n\n return {\n target,\n stop: () => {\n if (completed) return\n completed = true\n frameHandle?.cancel()\n },\n get isActive(): boolean {\n return !completed\n },\n }\n}\n"],"names":[],"mappings":";AA2FO,SAAS,aACd,SACA,QACA,WACiB;AACjB,QAAM,SAAS,EAAE,GAAG,QAAA;AACpB,QAAM,OAAO,OAAO,KAAK,OAAO,EAAE;AAGlC,QAAM,eACJ,OAAO,OAAO,WAAW,WACrB,EAAE,GAAI,eAAe,OAAO,MAAyB,KAAK,eAAe,QAAA,IACxE,OAAO,UAAU,CAAA;AAGxB,QAAM,iCAAiB,IAAA;AACvB,aAAW,OAAO,MAAM;AACtB,UAAM,aAAa,QAAQ,GAAG;AAC9B,eAAW,IAAI,KAAK;AAAA,MAClB,SAAS,IAAI,cAAc,YAAY;AAAA,MACvC,OAAO,EAAE,OAAO,YAAY,UAAU,EAAA;AAAA,MACtC,QAAQ,OAAO,GAAG,GAAG;AAAA,IAAA,CACtB;AAAA,EACH;AAEA,MAAI,cAAuC;AAC3C,MAAI,YAAY;AAGhB,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO,WAAW,MAAM;AACxB,WAAO,aAAA;AACP,WAAO;AAAA,MACL;AAAA,MACA,MAAM,MAAM;AAAA,MAAC;AAAA,MACb,UAAU;AAAA,IAAA;AAAA,EAEd;AAEA,gBAAc,UAAU,QAAQ,CAAC,UAAkB;AACjD,QAAI,UAAW;AAEf,UAAM,eAAe,QAAQ;AAC7B,QAAI,YAAY;AAGhB,eAAW,OAAO,MAAM;AACtB,YAAM,OAAO,WAAW,IAAI,GAAG;AAC/B,UAAI,CAAC,KAAM;AAEX,YAAM,WAAW,KAAK,QAAQ,KAAK,KAAK,OAAO,KAAK,QAAQ,YAAY;AACxE,WAAK,QAAQ;AAGX,aAAkC,GAAa,IAAI,SAAS;AAG9D,UAAI,CAAC,KAAK,QAAQ,SAAS,UAAU,KAAK,MAAM,GAAG;AACjD,oBAAY;AAAA,MACd;AAAA,IACF;AAGA,QAAI,WAAW;AACb,iBAAW,OAAO,MAAM;AACtB,cAAM,OAAO,WAAW,IAAI,GAAG;AAC/B,YAAI,CAAC,KAAM;AACX,cAAM,UAAU,KAAK,QAAQ,aAAa,KAAK,OAAO,KAAK,MAAM;AACjE,YAAI,QAAQ,UAAU,KAAK,MAAM,OAAO;AACtC,eAAK,QAAQ;AACX,iBAAkC,GAAa,IAAI,QAAQ;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAGA,QAAI;AACF,aAAO,WAAW,MAAM;AAAA,IAC1B,QAAQ;AAAA,IAER;AAGA,QAAI,WAAW;AACb,kBAAY;AACZ,mBAAa,OAAA;AACb,UAAI;AACF,eAAO,aAAA;AAAA,MACT,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,MAAM,MAAM;AACV,UAAI,UAAW;AACf,kBAAY;AACZ,mBAAa,OAAA;AAAA,IACf;AAAA,IACA,IAAI,WAAoB;AACtB,aAAO,CAAC;AAAA,IACV;AAAA,EAAA;AAEJ;"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const c1 = 1.70158;
|
|
4
|
+
const c2 = c1 * 1.525;
|
|
5
|
+
const c3 = c1 + 1;
|
|
6
|
+
const c4 = 2 * Math.PI / 3;
|
|
7
|
+
const c5 = 2 * Math.PI / 4.5;
|
|
8
|
+
const n1 = 7.5625;
|
|
9
|
+
const d1 = 2.75;
|
|
10
|
+
const Easing = {
|
|
11
|
+
// --- Linear ---
|
|
12
|
+
linear: (t) => t,
|
|
13
|
+
// --- Quad ---
|
|
14
|
+
quadIn: (t) => t * t,
|
|
15
|
+
quadOut: (t) => 1 - (1 - t) * (1 - t),
|
|
16
|
+
quadInOut: (t) => t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2,
|
|
17
|
+
// --- Cubic ---
|
|
18
|
+
cubicIn: (t) => t * t * t,
|
|
19
|
+
cubicOut: (t) => 1 - Math.pow(1 - t, 3),
|
|
20
|
+
cubicInOut: (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2,
|
|
21
|
+
// --- Quart ---
|
|
22
|
+
quartIn: (t) => t * t * t * t,
|
|
23
|
+
quartOut: (t) => 1 - Math.pow(1 - t, 4),
|
|
24
|
+
quartInOut: (t) => t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2,
|
|
25
|
+
// --- Quint ---
|
|
26
|
+
quintIn: (t) => t * t * t * t * t,
|
|
27
|
+
quintOut: (t) => 1 - Math.pow(1 - t, 5),
|
|
28
|
+
quintInOut: (t) => t < 0.5 ? 16 * t * t * t * t * t : 1 - Math.pow(-2 * t + 2, 5) / 2,
|
|
29
|
+
// --- Sine ---
|
|
30
|
+
sineIn: (t) => 1 - Math.cos(t * Math.PI / 2),
|
|
31
|
+
sineOut: (t) => Math.sin(t * Math.PI / 2),
|
|
32
|
+
sineInOut: (t) => -(Math.cos(Math.PI * t) - 1) / 2,
|
|
33
|
+
// --- Expo ---
|
|
34
|
+
expoIn: (t) => t === 0 ? 0 : Math.pow(2, 10 * t - 10),
|
|
35
|
+
expoOut: (t) => t === 1 ? 1 : 1 - Math.pow(2, -10 * t),
|
|
36
|
+
expoInOut: (t) => {
|
|
37
|
+
if (t === 0) return 0;
|
|
38
|
+
if (t === 1) return 1;
|
|
39
|
+
return t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2;
|
|
40
|
+
},
|
|
41
|
+
// --- Circ ---
|
|
42
|
+
circIn: (t) => 1 - Math.sqrt(1 - Math.pow(t, 2)),
|
|
43
|
+
circOut: (t) => Math.sqrt(1 - Math.pow(t - 1, 2)),
|
|
44
|
+
circInOut: (t) => t < 0.5 ? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2 : (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2,
|
|
45
|
+
// --- Back ---
|
|
46
|
+
backIn: (t) => c3 * t * t * t - c1 * t * t,
|
|
47
|
+
backOut: (t) => 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2),
|
|
48
|
+
backInOut: (t) => t < 0.5 ? Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2) / 2 : (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2,
|
|
49
|
+
// --- Elastic ---
|
|
50
|
+
elasticIn: (t) => {
|
|
51
|
+
if (t === 0) return 0;
|
|
52
|
+
if (t === 1) return 1;
|
|
53
|
+
return -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * c4);
|
|
54
|
+
},
|
|
55
|
+
elasticOut: (t) => {
|
|
56
|
+
if (t === 0) return 0;
|
|
57
|
+
if (t === 1) return 1;
|
|
58
|
+
return Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
|
|
59
|
+
},
|
|
60
|
+
elasticInOut: (t) => {
|
|
61
|
+
if (t === 0) return 0;
|
|
62
|
+
if (t === 1) return 1;
|
|
63
|
+
return t < 0.5 ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * c5)) / 2 : Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * c5) / 2 + 1;
|
|
64
|
+
},
|
|
65
|
+
// --- Bounce ---
|
|
66
|
+
bounceOut: (t) => {
|
|
67
|
+
if (t < 1 / d1) return n1 * t * t;
|
|
68
|
+
if (t < 2 / d1) return n1 * (t -= 1.5 / d1) * t + 0.75;
|
|
69
|
+
if (t < 2.5 / d1) return n1 * (t -= 2.25 / d1) * t + 0.9375;
|
|
70
|
+
return n1 * (t -= 2.625 / d1) * t + 0.984375;
|
|
71
|
+
},
|
|
72
|
+
bounceIn: (t) => 1 - Easing.bounceOut(1 - t),
|
|
73
|
+
bounceInOut: (t) => t < 0.5 ? (1 - Easing.bounceOut(1 - 2 * t)) / 2 : (1 + Easing.bounceOut(2 * t - 1)) / 2
|
|
74
|
+
};
|
|
75
|
+
exports.Easing = Easing;
|
|
76
|
+
//# sourceMappingURL=easing.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easing.cjs","sources":["../../src/animation/easing.ts"],"sourcesContent":["/**\n * Penner easing equations — complete set.\n *\n * All functions satisfy f(0) = 0, f(1) = 1.\n * These are pure math functions — no renderer dependencies.\n */\n\n/** Easing function: maps linear progress 0..1 to eased progress 0..1 */\nexport type EasingFn = (t: number) => number\n\nconst c1 = 1.70158\nconst c2 = c1 * 1.525\nconst c3 = c1 + 1\nconst c4 = (2 * Math.PI) / 3\nconst c5 = (2 * Math.PI) / 4.5\nconst n1 = 7.5625\nconst d1 = 2.75\n\n/**\n * Complete collection of Penner easing equations.\n */\nexport const Easing = {\n // --- Linear ---\n linear: (t: number): number => t,\n\n // --- Quad ---\n quadIn: (t: number): number => t * t,\n quadOut: (t: number): number => 1 - (1 - t) * (1 - t),\n quadInOut: (t: number): number => (t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2),\n\n // --- Cubic ---\n cubicIn: (t: number): number => t * t * t,\n cubicOut: (t: number): number => 1 - Math.pow(1 - t, 3),\n cubicInOut: (t: number): number => (t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2),\n\n // --- Quart ---\n quartIn: (t: number): number => t * t * t * t,\n quartOut: (t: number): number => 1 - Math.pow(1 - t, 4),\n quartInOut: (t: number): number =>\n t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2,\n\n // --- Quint ---\n quintIn: (t: number): number => t * t * t * t * t,\n quintOut: (t: number): number => 1 - Math.pow(1 - t, 5),\n quintInOut: (t: number): number =>\n t < 0.5 ? 16 * t * t * t * t * t : 1 - Math.pow(-2 * t + 2, 5) / 2,\n\n // --- Sine ---\n sineIn: (t: number): number => 1 - Math.cos((t * Math.PI) / 2),\n sineOut: (t: number): number => Math.sin((t * Math.PI) / 2),\n sineInOut: (t: number): number => -(Math.cos(Math.PI * t) - 1) / 2,\n\n // --- Expo ---\n expoIn: (t: number): number => (t === 0 ? 0 : Math.pow(2, 10 * t - 10)),\n expoOut: (t: number): number => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)),\n expoInOut: (t: number): number => {\n if (t === 0) return 0\n if (t === 1) return 1\n return t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2\n },\n\n // --- Circ ---\n circIn: (t: number): number => 1 - Math.sqrt(1 - Math.pow(t, 2)),\n circOut: (t: number): number => Math.sqrt(1 - Math.pow(t - 1, 2)),\n circInOut: (t: number): number =>\n t < 0.5\n ? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2\n : (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2,\n\n // --- Back ---\n backIn: (t: number): number => c3 * t * t * t - c1 * t * t,\n backOut: (t: number): number => 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2),\n backInOut: (t: number): number =>\n t < 0.5\n ? (Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2\n : (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2,\n\n // --- Elastic ---\n elasticIn: (t: number): number => {\n if (t === 0) return 0\n if (t === 1) return 1\n return -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * c4)\n },\n elasticOut: (t: number): number => {\n if (t === 0) return 0\n if (t === 1) return 1\n return Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1\n },\n elasticInOut: (t: number): number => {\n if (t === 0) return 0\n if (t === 1) return 1\n return t < 0.5\n ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * c5)) / 2\n : (Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * c5)) / 2 + 1\n },\n\n // --- Bounce ---\n bounceOut: (t: number): number => {\n if (t < 1 / d1) return n1 * t * t\n if (t < 2 / d1) return n1 * (t -= 1.5 / d1) * t + 0.75\n if (t < 2.5 / d1) return n1 * (t -= 2.25 / d1) * t + 0.9375\n return n1 * (t -= 2.625 / d1) * t + 0.984375\n },\n bounceIn: (t: number): number => 1 - Easing.bounceOut(1 - t),\n bounceInOut: (t: number): number =>\n t < 0.5 ? (1 - Easing.bounceOut(1 - 2 * t)) / 2 : (1 + Easing.bounceOut(2 * t - 1)) / 2,\n} as const satisfies Record<string, EasingFn>\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Penner easing equations — complete set.
|
|
3
|
+
*
|
|
4
|
+
* All functions satisfy f(0) = 0, f(1) = 1.
|
|
5
|
+
* These are pure math functions — no renderer dependencies.
|
|
6
|
+
*/
|
|
7
|
+
/** Easing function: maps linear progress 0..1 to eased progress 0..1 */
|
|
8
|
+
export type EasingFn = (t: number) => number;
|
|
9
|
+
/**
|
|
10
|
+
* Complete collection of Penner easing equations.
|
|
11
|
+
*/
|
|
12
|
+
export declare const Easing: {
|
|
13
|
+
readonly linear: (t: number) => number;
|
|
14
|
+
readonly quadIn: (t: number) => number;
|
|
15
|
+
readonly quadOut: (t: number) => number;
|
|
16
|
+
readonly quadInOut: (t: number) => number;
|
|
17
|
+
readonly cubicIn: (t: number) => number;
|
|
18
|
+
readonly cubicOut: (t: number) => number;
|
|
19
|
+
readonly cubicInOut: (t: number) => number;
|
|
20
|
+
readonly quartIn: (t: number) => number;
|
|
21
|
+
readonly quartOut: (t: number) => number;
|
|
22
|
+
readonly quartInOut: (t: number) => number;
|
|
23
|
+
readonly quintIn: (t: number) => number;
|
|
24
|
+
readonly quintOut: (t: number) => number;
|
|
25
|
+
readonly quintInOut: (t: number) => number;
|
|
26
|
+
readonly sineIn: (t: number) => number;
|
|
27
|
+
readonly sineOut: (t: number) => number;
|
|
28
|
+
readonly sineInOut: (t: number) => number;
|
|
29
|
+
readonly expoIn: (t: number) => number;
|
|
30
|
+
readonly expoOut: (t: number) => number;
|
|
31
|
+
readonly expoInOut: (t: number) => number;
|
|
32
|
+
readonly circIn: (t: number) => number;
|
|
33
|
+
readonly circOut: (t: number) => number;
|
|
34
|
+
readonly circInOut: (t: number) => number;
|
|
35
|
+
readonly backIn: (t: number) => number;
|
|
36
|
+
readonly backOut: (t: number) => number;
|
|
37
|
+
readonly backInOut: (t: number) => number;
|
|
38
|
+
readonly elasticIn: (t: number) => number;
|
|
39
|
+
readonly elasticOut: (t: number) => number;
|
|
40
|
+
readonly elasticInOut: (t: number) => number;
|
|
41
|
+
readonly bounceOut: (t: number) => number;
|
|
42
|
+
readonly bounceIn: (t: number) => number;
|
|
43
|
+
readonly bounceInOut: (t: number) => number;
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=easing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easing.d.ts","sourceRoot":"","sources":["../../src/animation/easing.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wEAAwE;AACxE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;AAU5C;;GAEG;AACH,eAAO,MAAM,MAAM;yBAEL,MAAM,KAAG,MAAM;yBAGf,MAAM,KAAG,MAAM;0BACd,MAAM,KAAG,MAAM;4BACb,MAAM,KAAG,MAAM;0BAGjB,MAAM,KAAG,MAAM;2BACd,MAAM,KAAG,MAAM;6BACb,MAAM,KAAG,MAAM;0BAGlB,MAAM,KAAG,MAAM;2BACd,MAAM,KAAG,MAAM;6BACb,MAAM,KAAG,MAAM;0BAIlB,MAAM,KAAG,MAAM;2BACd,MAAM,KAAG,MAAM;6BACb,MAAM,KAAG,MAAM;yBAInB,MAAM,KAAG,MAAM;0BACd,MAAM,KAAG,MAAM;4BACb,MAAM,KAAG,MAAM;yBAGlB,MAAM,KAAG,MAAM;0BACd,MAAM,KAAG,MAAM;4BACb,MAAM,KAAG,MAAM;yBAOlB,MAAM,KAAG,MAAM;0BACd,MAAM,KAAG,MAAM;4BACb,MAAM,KAAG,MAAM;yBAMlB,MAAM,KAAG,MAAM;0BACd,MAAM,KAAG,MAAM;4BACb,MAAM,KAAG,MAAM;4BAMf,MAAM,KAAG,MAAM;6BAKd,MAAM,KAAG,MAAM;+BAKb,MAAM,KAAG,MAAM;4BASlB,MAAM,KAAG,MAAM;2BAMhB,MAAM,KAAG,MAAM;8BACZ,MAAM,KAAG,MAAM;CAEW,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const c1 = 1.70158;
|
|
2
|
+
const c2 = c1 * 1.525;
|
|
3
|
+
const c3 = c1 + 1;
|
|
4
|
+
const c4 = 2 * Math.PI / 3;
|
|
5
|
+
const c5 = 2 * Math.PI / 4.5;
|
|
6
|
+
const n1 = 7.5625;
|
|
7
|
+
const d1 = 2.75;
|
|
8
|
+
const Easing = {
|
|
9
|
+
// --- Linear ---
|
|
10
|
+
linear: (t) => t,
|
|
11
|
+
// --- Quad ---
|
|
12
|
+
quadIn: (t) => t * t,
|
|
13
|
+
quadOut: (t) => 1 - (1 - t) * (1 - t),
|
|
14
|
+
quadInOut: (t) => t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2,
|
|
15
|
+
// --- Cubic ---
|
|
16
|
+
cubicIn: (t) => t * t * t,
|
|
17
|
+
cubicOut: (t) => 1 - Math.pow(1 - t, 3),
|
|
18
|
+
cubicInOut: (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2,
|
|
19
|
+
// --- Quart ---
|
|
20
|
+
quartIn: (t) => t * t * t * t,
|
|
21
|
+
quartOut: (t) => 1 - Math.pow(1 - t, 4),
|
|
22
|
+
quartInOut: (t) => t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2,
|
|
23
|
+
// --- Quint ---
|
|
24
|
+
quintIn: (t) => t * t * t * t * t,
|
|
25
|
+
quintOut: (t) => 1 - Math.pow(1 - t, 5),
|
|
26
|
+
quintInOut: (t) => t < 0.5 ? 16 * t * t * t * t * t : 1 - Math.pow(-2 * t + 2, 5) / 2,
|
|
27
|
+
// --- Sine ---
|
|
28
|
+
sineIn: (t) => 1 - Math.cos(t * Math.PI / 2),
|
|
29
|
+
sineOut: (t) => Math.sin(t * Math.PI / 2),
|
|
30
|
+
sineInOut: (t) => -(Math.cos(Math.PI * t) - 1) / 2,
|
|
31
|
+
// --- Expo ---
|
|
32
|
+
expoIn: (t) => t === 0 ? 0 : Math.pow(2, 10 * t - 10),
|
|
33
|
+
expoOut: (t) => t === 1 ? 1 : 1 - Math.pow(2, -10 * t),
|
|
34
|
+
expoInOut: (t) => {
|
|
35
|
+
if (t === 0) return 0;
|
|
36
|
+
if (t === 1) return 1;
|
|
37
|
+
return t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2;
|
|
38
|
+
},
|
|
39
|
+
// --- Circ ---
|
|
40
|
+
circIn: (t) => 1 - Math.sqrt(1 - Math.pow(t, 2)),
|
|
41
|
+
circOut: (t) => Math.sqrt(1 - Math.pow(t - 1, 2)),
|
|
42
|
+
circInOut: (t) => t < 0.5 ? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2 : (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2,
|
|
43
|
+
// --- Back ---
|
|
44
|
+
backIn: (t) => c3 * t * t * t - c1 * t * t,
|
|
45
|
+
backOut: (t) => 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2),
|
|
46
|
+
backInOut: (t) => t < 0.5 ? Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2) / 2 : (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2,
|
|
47
|
+
// --- Elastic ---
|
|
48
|
+
elasticIn: (t) => {
|
|
49
|
+
if (t === 0) return 0;
|
|
50
|
+
if (t === 1) return 1;
|
|
51
|
+
return -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * c4);
|
|
52
|
+
},
|
|
53
|
+
elasticOut: (t) => {
|
|
54
|
+
if (t === 0) return 0;
|
|
55
|
+
if (t === 1) return 1;
|
|
56
|
+
return Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
|
|
57
|
+
},
|
|
58
|
+
elasticInOut: (t) => {
|
|
59
|
+
if (t === 0) return 0;
|
|
60
|
+
if (t === 1) return 1;
|
|
61
|
+
return t < 0.5 ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * c5)) / 2 : Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * c5) / 2 + 1;
|
|
62
|
+
},
|
|
63
|
+
// --- Bounce ---
|
|
64
|
+
bounceOut: (t) => {
|
|
65
|
+
if (t < 1 / d1) return n1 * t * t;
|
|
66
|
+
if (t < 2 / d1) return n1 * (t -= 1.5 / d1) * t + 0.75;
|
|
67
|
+
if (t < 2.5 / d1) return n1 * (t -= 2.25 / d1) * t + 0.9375;
|
|
68
|
+
return n1 * (t -= 2.625 / d1) * t + 0.984375;
|
|
69
|
+
},
|
|
70
|
+
bounceIn: (t) => 1 - Easing.bounceOut(1 - t),
|
|
71
|
+
bounceInOut: (t) => t < 0.5 ? (1 - Easing.bounceOut(1 - 2 * t)) / 2 : (1 + Easing.bounceOut(2 * t - 1)) / 2
|
|
72
|
+
};
|
|
73
|
+
export {
|
|
74
|
+
Easing
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=easing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easing.js","sources":["../../src/animation/easing.ts"],"sourcesContent":["/**\n * Penner easing equations — complete set.\n *\n * All functions satisfy f(0) = 0, f(1) = 1.\n * These are pure math functions — no renderer dependencies.\n */\n\n/** Easing function: maps linear progress 0..1 to eased progress 0..1 */\nexport type EasingFn = (t: number) => number\n\nconst c1 = 1.70158\nconst c2 = c1 * 1.525\nconst c3 = c1 + 1\nconst c4 = (2 * Math.PI) / 3\nconst c5 = (2 * Math.PI) / 4.5\nconst n1 = 7.5625\nconst d1 = 2.75\n\n/**\n * Complete collection of Penner easing equations.\n */\nexport const Easing = {\n // --- Linear ---\n linear: (t: number): number => t,\n\n // --- Quad ---\n quadIn: (t: number): number => t * t,\n quadOut: (t: number): number => 1 - (1 - t) * (1 - t),\n quadInOut: (t: number): number => (t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2),\n\n // --- Cubic ---\n cubicIn: (t: number): number => t * t * t,\n cubicOut: (t: number): number => 1 - Math.pow(1 - t, 3),\n cubicInOut: (t: number): number => (t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2),\n\n // --- Quart ---\n quartIn: (t: number): number => t * t * t * t,\n quartOut: (t: number): number => 1 - Math.pow(1 - t, 4),\n quartInOut: (t: number): number =>\n t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2,\n\n // --- Quint ---\n quintIn: (t: number): number => t * t * t * t * t,\n quintOut: (t: number): number => 1 - Math.pow(1 - t, 5),\n quintInOut: (t: number): number =>\n t < 0.5 ? 16 * t * t * t * t * t : 1 - Math.pow(-2 * t + 2, 5) / 2,\n\n // --- Sine ---\n sineIn: (t: number): number => 1 - Math.cos((t * Math.PI) / 2),\n sineOut: (t: number): number => Math.sin((t * Math.PI) / 2),\n sineInOut: (t: number): number => -(Math.cos(Math.PI * t) - 1) / 2,\n\n // --- Expo ---\n expoIn: (t: number): number => (t === 0 ? 0 : Math.pow(2, 10 * t - 10)),\n expoOut: (t: number): number => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)),\n expoInOut: (t: number): number => {\n if (t === 0) return 0\n if (t === 1) return 1\n return t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2\n },\n\n // --- Circ ---\n circIn: (t: number): number => 1 - Math.sqrt(1 - Math.pow(t, 2)),\n circOut: (t: number): number => Math.sqrt(1 - Math.pow(t - 1, 2)),\n circInOut: (t: number): number =>\n t < 0.5\n ? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2\n : (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2,\n\n // --- Back ---\n backIn: (t: number): number => c3 * t * t * t - c1 * t * t,\n backOut: (t: number): number => 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2),\n backInOut: (t: number): number =>\n t < 0.5\n ? (Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2\n : (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2,\n\n // --- Elastic ---\n elasticIn: (t: number): number => {\n if (t === 0) return 0\n if (t === 1) return 1\n return -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * c4)\n },\n elasticOut: (t: number): number => {\n if (t === 0) return 0\n if (t === 1) return 1\n return Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1\n },\n elasticInOut: (t: number): number => {\n if (t === 0) return 0\n if (t === 1) return 1\n return t < 0.5\n ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * c5)) / 2\n : (Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * c5)) / 2 + 1\n },\n\n // --- Bounce ---\n bounceOut: (t: number): number => {\n if (t < 1 / d1) return n1 * t * t\n if (t < 2 / d1) return n1 * (t -= 1.5 / d1) * t + 0.75\n if (t < 2.5 / d1) return n1 * (t -= 2.25 / d1) * t + 0.9375\n return n1 * (t -= 2.625 / d1) * t + 0.984375\n },\n bounceIn: (t: number): number => 1 - Easing.bounceOut(1 - t),\n bounceInOut: (t: number): number =>\n t < 0.5 ? (1 - Easing.bounceOut(1 - 2 * t)) / 2 : (1 + Easing.bounceOut(2 * t - 1)) / 2,\n} as const satisfies Record<string, EasingFn>\n"],"names":[],"mappings":"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"}
|