@penner/responsive-easing 0.0.4 → 0.1.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/README.md +114 -66
- package/dist/index.cjs.js +2 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +991 -0
- package/dist/index.es.js +1721 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.iife.js +2 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +13 -71
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,112 +1,160 @@
|
|
|
1
1
|
# Responsive Easing
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
> [!WARNING] > **🚧 Work in Progress** - This package is currently under active development. The API shown in this README is aspirational and not yet implemented. Please check back later for the actual release!
|
|
3
|
+
Mix and merge easing curves to create motion that feels exactly right.
|
|
6
4
|
|
|
7
5
|
[](https://www.npmjs.com/package/@penner/responsive-easing)
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
## Install
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
```bash
|
|
10
|
+
npm install @penner/responsive-easing
|
|
11
|
+
```
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Overview
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Responsive Easing opens up new creative possibilities by splitting easing curves into two independent phases:
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
- **Head** — the first phase of the curve, easing away from the start
|
|
18
|
+
- **Tail** — the second phase, easing into the destination
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
- Overshoots that don’t scale properly
|
|
21
|
-
- Janky joins between motion segments
|
|
22
|
-
- Manual tweaking of durations and curves for each use case
|
|
20
|
+
The `fuse()` function seamlessly joins them at a configurable point, producing a single smooth easing function. Because each phase is independent, you can mix any head with any tail — anticipation into a bounce, a Bézier swoop into a spring, or anything in between — creating curves that would be impossible with a single easing function.
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
Use the **[Fuse Editor](https://robertpenner.com/fuse)** to visually design curves, tweak parameters in real time, and copy out CSS easing strings or config values for the JS API.
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
## Quick start
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
```ts
|
|
27
|
+
import { fuse } from '@penner/responsive-easing';
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
// Backwards anticipation into a bouncy landing
|
|
30
|
+
const { easing, easingFn } = fuse({
|
|
31
|
+
head: { kind: 'back', overshoot: 0.2 }, // backwards by 20%
|
|
32
|
+
tail: { kind: 'spring', bounces: 4, decay: 0.95 },
|
|
33
|
+
joinTime: 0.7, // head is 70% of the curve, tail is 30%
|
|
34
|
+
});
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
// `easing` is a CSS linear() string - for CSS transitions, animations and web animations
|
|
37
|
+
element.animate(keyframes, { duration: 500, easing });
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
// `easingFn` is a mathematical function — for JS-driven animation or direct evaluation
|
|
40
|
+
const y = easingFn(0.5);
|
|
38
41
|
```
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
## 🧪 Basic Usage
|
|
43
|
+
The `.easing` property is a CSS `linear()` string, so it also works directly in style assignments:
|
|
43
44
|
|
|
44
45
|
```ts
|
|
45
|
-
|
|
46
|
+
element.style.transition = `transform 600ms ${easing}`;
|
|
47
|
+
element.style.animationTimingFunction = easing;
|
|
48
|
+
```
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
distance: 400, // in pixels
|
|
49
|
-
duration: 600, // in milliseconds
|
|
50
|
-
overshoot: true,
|
|
51
|
-
});
|
|
50
|
+
## Easing definitions
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
```
|
|
52
|
+
Eight easing types, each with its own tunable parameters. Any head can be paired with any tail, giving you a wide palette of motion curves to design with.
|
|
55
53
|
|
|
56
|
-
|
|
54
|
+
| Kind | Parameters | Character |
|
|
55
|
+
| ------------ | --------------------------- | -------------------------------------------------------- |
|
|
56
|
+
| `power` | `exponent` | Smooth acceleration (quadratic, cubic, etc.) |
|
|
57
|
+
| `back` | `overshoot` | Anticipation — dips backward before moving forward |
|
|
58
|
+
| `power-back` | `exponent`, `overshoot` | Combined power + back |
|
|
59
|
+
| `bezier` | `x1`, `y1`, `x2`, `y2` | Cubic Bézier (same param space as CSS) |
|
|
60
|
+
| `expo` | `decay` | Exponential decay (tail only) |
|
|
61
|
+
| `spring` | `bounces`, `decay` | Damped oscillation (tail only) |
|
|
62
|
+
| `bounce` | `bounces`, `decay` | Hard-surface rebound (tail only) |
|
|
63
|
+
| `swim` | `strokes`, `effort`, `drag` | Rhythmic propulsion — pulsed force through viscous fluid |
|
|
57
64
|
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
## The `fuse()` API
|
|
66
|
+
|
|
67
|
+
`fuse()` takes a plain config object describing head and tail easings and returns an `EasingKit` — a bundle containing the composed easing function, its CSS `linear()` string, and a velocity function.
|
|
60
68
|
|
|
61
|
-
|
|
62
|
-
|
|
69
|
+
```ts
|
|
70
|
+
function fuse(config: FuseConfig): EasingKit;
|
|
71
|
+
|
|
72
|
+
interface EasingKit {
|
|
73
|
+
easing: CSSEasing; // CSS linear() string for transitions, animations, WAAPI
|
|
74
|
+
easingFn: EasingFn; // (t: number) => number, [0,1] → [0,1]
|
|
75
|
+
velocityFn: VelocityFn; // speed of the easing at any point in time
|
|
76
|
+
meta: Record<string, unknown>;
|
|
77
|
+
}
|
|
63
78
|
```
|
|
64
79
|
|
|
65
|
-
|
|
80
|
+
### FuseConfig
|
|
66
81
|
|
|
67
|
-
|
|
82
|
+
| Property | Type | Default | Description |
|
|
83
|
+
| ---------- | ------------------------- | -------------- | ----------------------------------------------------- |
|
|
84
|
+
| `head` | `AnyEasingDef` | — | Head easing definition (required) |
|
|
85
|
+
| `tail` | `AnyEasingDef` | — | Tail easing definition (required) |
|
|
86
|
+
| `joinTime` | `number` | `0.5` | Where head meets tail, in [0, 1] |
|
|
87
|
+
| `movement` | `'transition' \| 'pulse'` | `'transition'` | Transition goes A→B; pulse goes A→B→A |
|
|
88
|
+
| `mirror` | `boolean` | `false` | Tail = reversed head (symmetric inOut curve) |
|
|
89
|
+
| `maxSpeed` | `number` | — | Cap join velocity; inserts a cruise phase if exceeded |
|
|
68
90
|
|
|
69
|
-
|
|
70
|
-
- ✅ **Cruise segments** with constant velocity
|
|
71
|
-
- ✅ **Responsive overshoot / bounce**
|
|
72
|
-
- ✅ **Velocity-matched joins**
|
|
73
|
-
- ✅ **Composable easing parts** (intro, cruise, outro)
|
|
74
|
-
- ✅ **Exportable to CSS `linear()` timing functions**
|
|
75
|
-
- ✅ Works with any animation system (CSS, JS, Web Animations API, GSAP, Framer Motion)
|
|
91
|
+
## Examples
|
|
76
92
|
|
|
77
|
-
|
|
93
|
+
```ts
|
|
94
|
+
// Smooth power curve (equivalent to cubic ease-in-out when mirrored)
|
|
95
|
+
fuse({
|
|
96
|
+
head: { kind: 'power', exponent: 3 },
|
|
97
|
+
tail: { kind: 'power', exponent: 3 },
|
|
98
|
+
}).easingFn;
|
|
99
|
+
|
|
100
|
+
// Bézier head + bounce tail
|
|
101
|
+
fuse({
|
|
102
|
+
head: { kind: 'bezier', x1: 0.4, y1: 1.6, x2: 0.8, y2: -0.4 },
|
|
103
|
+
tail: { kind: 'bounce', bounces: 3, decay: 0.95 },
|
|
104
|
+
joinTime: 0.3,
|
|
105
|
+
}).easingFn;
|
|
106
|
+
|
|
107
|
+
// Swim head + bounce tail
|
|
108
|
+
fuse({
|
|
109
|
+
head: { kind: 'swim', strokes: 3.3, effort: 0.33, drag: 13 },
|
|
110
|
+
tail: { kind: 'bounce', bounces: 1, decay: 0 },
|
|
111
|
+
}).easingFn;
|
|
112
|
+
|
|
113
|
+
// Symmetric curve via mirror
|
|
114
|
+
fuse({
|
|
115
|
+
head: { kind: 'power-back', exponent: 2, overshoot: 0.1 },
|
|
116
|
+
tail: { kind: 'power', exponent: 2 }, // ignored when mirror=true
|
|
117
|
+
mirror: true,
|
|
118
|
+
}).easingFn;
|
|
119
|
+
```
|
|
78
120
|
|
|
79
|
-
##
|
|
121
|
+
## Responsive Easing Modules (REMs)
|
|
80
122
|
|
|
81
|
-
|
|
82
|
-
- [Comparison to traditional easing](TODO)
|
|
83
|
-
- [Curve visualizer](TODO)
|
|
123
|
+
Under the hood, each easing definition resolves to an `EasingRem` (Responsive Easing Module) — an object that bundles the easing math with metadata for building UIs like sliders and parameter editors.
|
|
84
124
|
|
|
85
|
-
|
|
125
|
+
```ts
|
|
126
|
+
import { PowerBackRem, SwimRem, getEasingRem } from '@penner/responsive-easing';
|
|
86
127
|
|
|
87
|
-
|
|
128
|
+
// Factory creation
|
|
129
|
+
const rem = getEasingRem('power-back', { exponent: 3, overshoot: 0.15 });
|
|
88
130
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
- [Design Principles](TODO)
|
|
92
|
-
- [FAQ](TODO)
|
|
131
|
+
// Immutable update
|
|
132
|
+
const updated = rem.with({ overshoot: 0.3 });
|
|
93
133
|
|
|
94
|
-
|
|
134
|
+
// Evaluate
|
|
135
|
+
const y = rem.easeIn(0.5);
|
|
136
|
+
|
|
137
|
+
// Static knob specs for UI generation
|
|
138
|
+
PowerBackRem.EXPONENT_KNOB; // { key: 'exponent', type: 'number', min: 0.1, max: 10, ... }
|
|
139
|
+
SwimRem.DRAG_KNOB; // { key: 'drag', type: 'number', min: 0.5, max: 30, ... }
|
|
140
|
+
```
|
|
95
141
|
|
|
96
|
-
|
|
142
|
+
Available REMs: `PowerRem`, `BackRem`, `PowerBackRem`, `BezierRem`, `ExpoRem`, `SpringRem`, `BounceRem`, `SwimRem`.
|
|
97
143
|
|
|
98
|
-
|
|
144
|
+
## Technical notes
|
|
99
145
|
|
|
100
|
-
|
|
146
|
+
- The fuse config is a plain serializable object — no class instances or functions, just data. Easy to store in a database, share via URL, or pass between workers.
|
|
147
|
+
- Types like `NormalizedTime`, `CSSEasing`, and `EasingFn` are powered by [`@penner/smart-primitive`](https://www.npmjs.com/package/@penner/smart-primitive), which catches unit mix-ups at compile time with zero runtime cost.
|
|
148
|
+
- Each easing definition resolves to an immutable `EasingRem` (Responsive Easing Module) that encapsulates the math, velocity computation, and UI knob metadata for a single easing type. REMs can be created, updated, and evaluated directly for advanced use cases.
|
|
101
149
|
|
|
102
|
-
##
|
|
150
|
+
## Mathematical notes
|
|
103
151
|
|
|
104
|
-
|
|
152
|
+
The join between head and tail maintains **C¹ continuity** — both position and velocity (first derivative) match at the join point. This is what makes the transition feel smooth rather than abrupt.
|
|
105
153
|
|
|
106
|
-
|
|
154
|
+
Internally, `fuse()` scales each phase (head or tail) to fit its portion of the [0, 1] time range. The head is stretched or compressed to fill the interval `[0, joinTime]`, and the tail fills `[joinTime, 1]`. Velocity at the join point is computed from the head's ending slope, and the tail's amplitude and time scale are adjusted so its starting slope matches — guaranteeing a seamless handoff regardless of which easing types are combined.
|
|
107
155
|
|
|
108
|
-
|
|
156
|
+
For easing types like `spring`, `bounce`, and `swim` where analytical derivatives aren't available, velocity is computed numerically.
|
|
109
157
|
|
|
110
|
-
##
|
|
158
|
+
## License
|
|
111
159
|
|
|
112
160
|
MIT © [Robert Penner](https://github.com/robertpenner)
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("@penner/smart-primitive"),v=require("@penner/easing"),ot=1.70158,ft=ot+1,nt=e=>ft*e*e*e-ot*e*e,at=e=>3*ft*e*e-2*ot*e,j={id:"bounce",label:"Bounce (hard-surface)",build({joinTime:e,bounces:t,decayPct:a,L:n=nt,Ld:o=at}){if(e<it)return{p:O=>C.clampNormalized(O),v:O=>1,meta:{r:0,finalPct:0}};if(e>Mt)return{p:O=>O>=1?1:n(O),v:O=>O>=1?0:o(O),meta:{r:0,finalPct:0}};const r=Math.ceil(t),s=t-Math.floor(t);let i;if(t<=1)i=C.clampNormalized(1-a/100);else{const h=C.clampNormalized(1-a/100);h===0?i=0:i=Math.pow(h,1/(2*(t-1)))}const u=h=>n(h/e),d=h=>o(h/e)/e,l=d(e),c=Math.abs(-i*l);if(i===0||c===0)return{p:O=>O<=e?u(O):1,v:O=>O<=e?d(O):0,meta:{r:0,finalPct:0,g:0,edges:[e,1]}};const M=1-e,b=Math.floor(t),P=Math.abs(1-i)<1e-6?t:(1-Math.pow(i,b))/(1-i)+s*Math.pow(i,b);let y=2*c/M*P,f=0;const I=50;for(let h=0;h<=I;h++){const w=h/I*e,O=u(w);O<f&&(f=O)}const E=1-f,p=c*c/(2*y);let x=c,V=!1,_=1;if(p>E){x=Math.sqrt(2*y*E),V=!0;const h=Math.abs(1-i)<1e-6?t:(1-Math.pow(i,b))/(1-i)+s*Math.pow(i,b),w=2*x*h/y;_=e+w,_>1&&(_=1)}const S=x,H=Array.from({length:r},(h,w)=>2*S*Math.pow(i,w)/y),k=[e];H.forEach(h=>k.push(k[k.length-1]+h)),V?k[k.length-1]=_:k[k.length-1]=1;const F=h=>-S*Math.pow(i,h),N=h=>{if(h>=_)return 1;let w=k.findIndex((B,z)=>z<k.length-1&&h<=k[z+1]);w<0&&(w=r-1);const O=k[w],$=h-O;return 1+(F(w)*$+.5*y*$*$)},A=h=>{if(h>=_)return 0;let w=k.findIndex((T,B)=>B<k.length-1&&h<=k[B+1]);w<0&&(w=r-1);const O=k[w],$=h-O;return F(w)+y*$},K=h=>h<=e?u(h):N(h),m=h=>h<=e?d(h):A(h),g=r<=1?100:100*(1-a/100);return{p:K,v:m,meta:{r:i,finalPct:g,g:y,edges:k,clamped:V,settleTime:_}}}},_t=12;function Pt({joinTime:e,L:t=nt,Ld:a=at,bridge:n}){const o=_t;n&&n.joinHeight;const r=n?e+n.duration:e,s=1-r;let i;if(n)i=n.joinHeight;else{const x=a(1)*(1-e)+o*e;Math.abs(x)<1e-9?i=.5:i=o*e/x,i=Math.max(.01,Math.min(.999,i))}const u=n?1:i,d=u-1,l=n?n.velocity*s:i*a(1)*(1-e)/e,c=l+o*d,M=p=>{if(p<=0)return u;if(p>=1)return 1;const x=Math.exp(-o*p);return 1+(d+c*p)*x},b=p=>{if(p<=0)return l;if(p>=1)return 0;const x=Math.exp(-o*p);return(c-o*(d+c*p))*x},P=n?n.joinHeight:i,y=p=>P*t(p/e),f=p=>P/e*a(p/e);return{p:p=>{if(p<=0)return 0;if(p>=1)return 1;if(p<=e)return y(p);if(n&&p<=r)return n.joinHeight+n.velocity*(p-e);const x=(p-r)/s;return M(x)},v:p=>{if(p<=0||p>=1)return 0;if(p<=e)return f(p);if(n&&p<=r)return n.velocity;const x=(p-r)/s;return b(x)/s},meta:{r:0,finalPct:0,k:o,B:0,P:i,guard:"critically-damped",useBridge:!!n}}}function It(e,t,a,n){const o=C.clampNormalized(a/100),r=t+.5,s=v.amplitudeRatio(o,r),i=r,u=Math.PI*i,d=v.dampingRate(i,s),l=1-e,c=e<=it*10,M=l>0?u/l:u,b=l>0?d/l:d,P=n(1);let y;if(c)y=0;else{const E=P/e,p=u,x=E*(1-e)+p*e;y=Math.abs(x)<1e-9?.5:p*e/x,y=Math.max(.01,Math.min(.999,y))}const f=c?0:y*P/e,I=t<=1?100:100*(1-a/100);return{P:y,v0:f,r:s,N:i,w:M,g:b,alpha:l,finalPct:I}}function Et({joinTime:e,bounces:t,decayPct:a,L:n=nt,Ld:o=at}){const r=It(e,t,a,o),{r:s,g:i,alpha:u,finalPct:d}=r,l=o(1);let c;if(l>1e-6){const g=Math.min(u/(8*Math.max(t,1)),u*.1),h=e/(e+l*g),O=t>0?.5*e*t*Math.PI/(l*u):.5;c=Math.min(h,O),c=Math.max(.01,Math.min(.999,c))}else c=r.P;const M=c*l/e,b=t>0?u/(2*t+1):u,P=t>0?u*.5:u,y=1e-6;let f;if(M>1e-6){const g=(1-c)/M;f=Math.max(y,Math.min(P,g))}else f=Math.max(y,Math.min(P,b));const I=f>0?2*(1-c-M*f)/(f*f):0,E=g=>.5*I*g*g+M*g+c,p=g=>I*g+M,x=I*f+M,V=u-f,_=V>0?t*Math.PI/V:0,S=_>0?x/_:0,H=g=>1+S*Math.exp(-i*g)*Math.sin(_*g),k=g=>S*Math.exp(-i*g)*(_*Math.cos(_*g)-i*Math.sin(_*g)),F=g=>c*n(g/e),N=g=>c/e*o(g/e),A=e+f;return{p:g=>{if(g<=0)return 0;if(g>=1)return 1;if(g<=e)return F(g);if(g<=A){const w=g-e;return E(w)}const h=g-A;return H(h)},v:g=>{if(g<=0||g>=1)return 0;if(g<=e)return N(g);if(g<=A){const w=g-e;return p(w)}const h=g-A;return k(h)},meta:{r:s,finalPct:d,k:i,B:_,P:c,guard:"quadratic-sine"}}}const Ot=Et,Z={id:"spring",label:"Spring (phase-locked; bounce = half-cycle)",getNaturalStartVelocity({bounces:e,decayPct:t},a,n){const o=e;if(o<=0)return a(1);let r;if(o<=1)r=C.clampNormalized(1-t/100);else{const M=C.clampNormalized(1-t/100);M===0?r=0:r=Math.pow(M,1/(o-1))}if(r===0)return 0;const s=a(1),i=n?.headWeight??1,u=n?.freqWeight??1,d=n?.freqExponent??1,l=n?.baseMultiplier??1,c=Math.pow(o,d);return s*i+l*c*u},build({joinTime:e,bounces:t,decayPct:a,L:n=nt,Ld:o=at,bridge:r}){if(e<it)return{p:h=>C.clampNormalized(h),v:h=>1,meta:{r:0,finalPct:0,k:0,B:0,P:0}};if(e>Mt)return{p:h=>h>=1?1:n(h),v:h=>h>=1?0:o(h),meta:{r:0,finalPct:0,k:0,B:0,P:1}};if(t<=0)return Pt({joinTime:e,L:n,Ld:o,bridge:r});if(!r)return Ot({joinTime:e,bounces:t,decayPct:a,L:n,Ld:o});let s;if(t<=1)s=C.clampNormalized(1-a/100);else{const m=C.clampNormalized(1-a/100);m===0?s=0:s=Math.pow(m,1/(t-1))}const i=r?r.joinHeight:1,u=r?e+r.duration:e;if(s===0){const m=O=>i*n(O/e),g=O=>i/e*o(O/e);return{p:O=>O<=e?m(O):r&&O<=u?r.joinHeight+r.velocity*(O-e):1,v:O=>O<=e?g(O):r&&O<=u?r.velocity:0,meta:{r:0,finalPct:0,k:1/0,B:0,P:i,guard:"no-oscillation",useBridge:!!r}}}const d=1-u,l=t<=0||d<=0?0:t*Math.PI/d,c=s<=0?50:l/Math.PI*-Math.log(s),M=m=>Math.exp(-c*m)*Math.sin(l*m),b=m=>Math.exp(-c*m)*(l*Math.cos(l*m)-c*Math.sin(l*m));let P="";const y=Math.PI/(2*l),f=Math.exp(-c*y),I=f>1e-9?f:1;f<=1e-9&&(P="high-decay-fallback");const E=m=>M(d*m)/I,p=m=>d*b(d*m)/I,x=()=>!r||l===0?0:r.joinHeight/e*o(1)*I/l,V=m=>k+(1-k)*m,_=m=>r?1+x()*E(m):V(m)+(1-k)*E(m),S=m=>r?x()/(1-u)*p(m):(1-k)*(1+p(m))/(1-u),H=()=>{if(r){const m=p(0),g=1-u;return Math.abs(m)<1e-9?i:1-r.velocity*g/m}else{const m=o(1),h=1+p(0);return Math.abs(m*(1-e)+h*e)<1e-9?.5:h*e/(m*(1-e)+h*e)}},k=H(),F=globalThis;typeof F.__SPRING_TEST_HELPERS__=="object"&&(F.__SPRING_TEST_HELPERS__.calculateBridgeAmplitude=x,F.__SPRING_TEST_HELPERS__.calculateNonBridgeBaseline=V,F.__SPRING_TEST_HELPERS__.calculatePulsePosition=_,F.__SPRING_TEST_HELPERS__.calculatePulseVelocity=S,F.__SPRING_TEST_HELPERS__.calculateScalingFactor=H);const N=m=>{if(m<=e)return(r?r.joinHeight:k)*n(m/e);if(r&&m<=u)return r.joinHeight+r.velocity*(m-e);const g=(m-u)/(1-u);return _(g)},A=m=>{if(m<=e)return(r?r.joinHeight:k)/e*o(m/e);if(r&&m<=u)return r.velocity;const g=(m-u)/(1-u);return S(g)},K=t<=1?100:100*(1-a/100);return{p:N,v:A,meta:{r:s,finalPct:K,k:c,B:l,P:k,guard:P||"ok",useBridge:!!r}}}},ct=Z;function xt(e,t,a,n){const o=Math.PI/2,r=T=>Math.abs(T)<222e-17,s=T=>{const B=Math.sign(T),z=T*B;return((((-.021641405*z+.077981383)*z+-.213301322)*z+o)*Math.sqrt(1-z)-o)*B+o},i=T=>{if(Math.abs(T)<1){const B=T*T,z=B*T,bt=z*B;return T+z/6+bt/120}return Math.sinh(T)},u=e-a,d=t-n,l=3*e,c=3*t,M=3*u+1,b=-l-3*u,P=l,y=3*d+1,f=-c-3*d,I=c,E=1/M,p=b*E,x=P*E,V=p/-3*p+x,_=p/3,S=(2*_*_-x)*_,H=Math.sign(V),k=Math.sign(b);let F=1,N=1,A=1,K,m,g;if(r(M)&&r(b))K=1,F=1/P,N=0,m=1,g=0;else if(r(M))K=2,F=k,N=-(P/(2*b)),m=1/b,g=N*N;else if(r(V))K=3,N=-_,m=E,g=-S;else{if(M<0)K=4;else if(V>0)K=5;else if(V<0)K=6,A=k;else throw new Error("Invalid curve type");F=-2*H*A*Math.sqrt(Math.abs(V)/3),N=-_,m=3*H*E/(V*F),g=3*H*(-S/V/F)}const h=y*F*F*F,w=(3*y*N+f)*F*F,O=((3*y*N+2*f)*N+I)*F,$=((y*N+f)*N+I)*N;return T=>{if(T<=0)return 0;if(T>=1)return 1;let B=m*T+g;switch(K){case 1:break;case 2:B=Math.sqrt(Math.max(0,B));break;case 3:B=Math.cbrt(B);break;case 4:B=Math.cos(s(Math.max(-1,Math.min(1,B)))/3-2.094395102393195);break;case 5:B=i(Math.log(B+Math.sqrt(B*B+1))/3);break;case 6:B=B>=1?Math.cosh(Math.log(B+Math.sqrt(B*B-1))/3):Math.cos(s(Math.max(-1,B))/3);break;default:throw new Error("Invalid curve type")}return((h*B+w)*B+O)*B+$}}function tt(e,t,a,n){if(e<0||e>1||a<0||a>1)throw new Error("x1 & x2 must be in [0, 1]");return e===t&&a===n?o=>o:xt(e,t,a,n)}function vt(e,t){if(e<=0)return 0;if(e>=1)return Number.POSITIVE_INFINITY;if(t<=1)return 0;if(t-1<1e-10){const n=e/(1-e);return Math.max(0,n*Math.pow(t-1,2))}const a=Math.pow((t-1)/t,t-1)/t;return Math.pow(e,t)/(1-e)*a}function Q(e,t){if(e<=0||t<=1)return 0;const a=e;let n=0,o=1-1e-9;for(let s=0;s<60;s++){const i=.5*(n+o);vt(i,t)<a?n=i:o=i}const r=.5*(n+o);return r/(1-r)}function pt(e,t,a){const n=t;if(a===0||n<=1)return Math.pow(e,Math.max(n,0));if(n-1<1e-10)return(a+1)*e-a;const r=Math.pow(e,n-1)*((a+1)*e-a);return r===0?0:r}function gt(e,t,a){const n=t;return a===0||n<=1?n*Math.pow(e,n-1):n-1<1e-10?a+1:Math.abs(n-2)<1e-10?2*(a+1)*e-a:e===0&&n>2?0:e===0&&n<=2?n*(a+1)*Math.pow(1e-10,n-1):n*(a+1)*Math.pow(e,n-1)-a*(n-1)*Math.pow(e,n-2)}function kt(e,t){if(t<=0||e<=1)return 0;const a=e,n=Q(t,a);return n<=0?0:(a-1)*n/(a*(n+1))}function St(e){const t=e;if(t<=1)return{u:.5,p:Math.pow(.5,Math.max(t,0))};const a=Math.pow(t,-1/(t-1));return{u:a,p:Math.pow(a,t)}}function Bt(e,t,a=1.01,n=10){if(e<=0||t<=0||t>=1)return null;const o=d=>{const l=Q(e,d);return l<=0?0:(d-1)*l/(d*(l+1))},r=o(a),s=o(n);if(t<=r&&r>0)return a;if(t>=s)return n;let i=a,u=n;for(let d=0;d<50;d++){const l=.5*(i+u),c=o(l);if(Math.abs(c-t)<1e-9)return l;c<t?i=l:u=l}return .5*(i+u)}function Vt(e=.1){const t=v.solveBackStrength(e),a=o=>{const r=1-o;return 1-((t+1)*r*r*r-t*r*r)},n=o=>{const r=1-o;return(t+1)*3*r*r-t*2*r};return{id:"back-out",label:`Back Out (${(e*100).toFixed(0)}%)`,easingFn:a,velocityFn:n,config:{overshoot:e}}}function rt(e=2){const t=Math.max(.1,e);return{id:"power-out",label:`Power Out (t^${t})`,easingFn:a=>{const n=1-a;return 1-Math.pow(n,t)},velocityFn:a=>{const n=1-a;return t*Math.pow(n,t-1)},config:{exponent:t}}}function wt(e=2,t=.1){const a=Math.max(.1,e);if(t<=0||a<=1)return rt(e);const n=Q(t,a),o=s=>{const i=1-s;return n===0||a<=1?1-Math.pow(i,a):a-1<1e-10?1-((n+1)*i-n):1-Math.pow(i,a-1)*((n+1)*i-n)},r=s=>{const i=1-s;return gt(i,a,n)};return{id:"power-back-out",label:`Power Back Out (${(t*100).toFixed(0)}%, n=${a.toFixed(2)})`,easingFn:o,velocityFn:r,config:{exponent:a,overshoot:t,strength:n}}}function Ft(e=.5,t=0,a=1,n=.5){const o=tt(e,t,a,n),r=v.createVelocityFn(o,{step:1e-8,boundarySample:.001});return{id:"bezier-out",label:`Bezier (${e.toFixed(2)}, ${t.toFixed(2)}, ${a.toFixed(2)}, ${n.toFixed(2)})`,easingFn:o,velocityFn:r,config:{x1:e,y1:t,x2:a,y2:n}}}function Nt(e=.95){const t=Math.max(0,Math.min(1,e));if(t===0)return{id:"expo-out",label:"Expo Out (linear)",easingFn:s=>s<=0?0:s>=1?1:s,velocityFn:()=>1,config:{decay:t}};if(t===1)return{id:"expo-out",label:"Expo Out (step)",easingFn:s=>s>0?1:0,velocityFn:()=>0,config:{decay:t}};const a=Math.log1p(-t),n=1/Math.expm1(a),o=v.makeExpoEaseOut(t),r=s=>a*Math.exp(a*s)*n;return{id:"expo-out",label:`Expo Out (${(t*100).toFixed(0)}%)`,easingFn:o,velocityFn:r,config:{decay:t}}}const Ht={back:Vt,power:rt,"power-back":wt,bezier:Ft,expo:Nt};function Kt(e,t){const a=Ht[e];return e==="back"?a(t?.overshoot??.1):e==="power"?a(t?.exponent??2):e==="power-back"?a(t?.exponent??2,t?.overshoot??.1):e==="expo"?a(t?.decay??.95):a(t?.x1??.5,t?.y1??0,t?.x2??1,t?.y2??.5)}function et(e,t,a){let n;Object.defineProperty(e,t,{get:()=>n??=a(),configurable:!0,enumerable:!0})}class Y{params;constructor(t){this.params=Object.freeze({...t}),et(this,"easeInVelocity",()=>v.createVelocityFn(this.easeIn)),et(this,"easeOutVelocity",()=>v.createVelocityFn(this.easeOut))}easeOut=t=>1-this.easeIn(1-t);get easeOutBoundary(){return{start:this.easeInBoundary.end,end:this.easeInBoundary.start}}}class J extends Y{static STROKES_KNOB={key:"strokes",label:"Strokes",type:"number",default:2,min:1,max:10,step:.05,isPrimary:!0};static EFFORT_KNOB={key:"effort",label:"Effort",type:"percent",default:.4,min:.05,max:.95,step:.01};static DRAG_KNOB={key:"drag",label:"Drag",type:"number",default:6,min:.5,max:30,step:.1};kind="swim";metadata={variants:{easeIn:!0,easeOut:!0},modes:{transition:!0,pulse:!1}};knobSpecs=[J.STROKES_KNOB,J.EFFORT_KNOB,J.DRAG_KNOB];easeInBoundary={start:"zero",end:"nonzero"};constructor(t){super(t);const a=v.swim(t);this.easeIn=n=>a(n)}with(t){return new J({...this.params,...t})}static create(t={}){return new J({strokes:t.strokes??2,effort:t.effort??.2,drag:t.drag??6})}}function Tt(e=.1){const t=v.solveBackStrength(e),a=t+1;return{id:"back",label:`Back (${(e*100).toFixed(0)}% overshoot)`,easingFn:n=>n*n*(a*n-t),velocityFn:n=>n*(3*a*n-2*t),config:{overshoot:e,strength:t}}}Tt(.1);function At(e,t,a){const n=Math.max(.001,Math.min(.999,a));return o=>{if(o<=0||o>=1)return 0;if(o<=n){const r=o/n;return e(r)}else{const r=(o-n)/(1-n);return 1-t(r)}}}function zt(e={}){const{bounces:t=4,decay:a=90}=e,n=Math.max(.5,t),o=Math.max(0,1-a/100),r=n<=1?o:o===0?0:Math.pow(o,1/(n-1)),s=n*Math.PI,i=r<=0?50:s/Math.PI*-Math.log(r),u=i/s,d=Math.exp(-i)*(Math.cos(s)+u*Math.sin(s));return l=>l<=0?1:l>=1?0:Math.exp(-i*l)*(Math.cos(s*l)+u*Math.sin(s*l))-d*l}function Dt(e={}){const{bounces:t=4,decay:a=90}=e,n=Math.max(1,Math.round(t)),o=Math.max(0,1-a/100),r=n<=1?Math.sqrt(o):o===0?0:Math.pow(o,1/(2*(n-1)));if(r===0)return c=>c<=0?1:c>=1?0:1-c*c;const s=Math.abs(1-r)<1e-6?1+2*n:1+2*r*(1-Math.pow(r,n))/(1-r),i=2*s*s,u=1/s,d=i*u,l=[0,u];for(let c=1;c<=n;c++){const M=2*Math.pow(r,c)*d/i;l.push(l[l.length-1]+M)}return l[l.length-1]=1,c=>{if(c<=0)return 1;if(c>=1)return 0;if(c<=u)return 1-.5*i*c*c;let M=0;for(let f=1;f<l.length-1;f++)if(c<=l[f+1]){M=f;break}M===0&&(M=l.length-2);const P=Math.pow(r,M)*d,y=c-l[M];return P*y-.5*i*y*y}}function lt(e,t,a){const n=Math.max(.001,Math.min(.999,a));return o=>{if(o<=0||o>=1)return 0;if(o<=n){const r=o/n;return e(r)}else{const r=(o-n)/(1-n);return t(r)}}}function Ct(e,t){return{isValid:!0,point:{x:1-e.x,y:1-e.y}}}function Lt(e,t){return{isValid:!0,point:{x:1-e.x,y:1-e.y}}}class R extends Y{static EXPONENT_KNOB={key:"exponent",label:"Exponent",type:"number",default:2,min:.1,max:10,step:.01,isPrimary:!0};kind="power";metadata={variants:{easeIn:!0,easeOut:!0},modes:{transition:!0,pulse:!0}};knobSpecs=[R.EXPONENT_KNOB];constructor(t){super(t)}get easeInBoundary(){return{start:this.params.exponent>1?"zero":"nonzero",end:"nonzero"}}easeIn=t=>Math.pow(t,this.params.exponent);easeInVelocity=t=>{const a=this.params.exponent;return a*Math.pow(t,a-1)};easeOutVelocity=t=>this.easeInVelocity(1-t);with(t){return new R({...this.params,...t,exponent:Math.max(.1,t.exponent??this.params.exponent)})}static create(t={}){const a=Math.max(.1,t.exponent??2);return new R({exponent:a})}}const Jt=1e-4,Yt=.9999,$t=0,Gt=1;function qt(e){if(Number.isNaN(e))return{atStart:!1,atEnd:!1};const t=Math.max($t,Math.min(Gt,e));return{atStart:t<=Jt,atEnd:t>=Yt}}function ut(e){const{joinTime:t,headVelocityAtEnd:a,tailVelocityAtStart:n}=e;if(t<=0||t>=1)return{joinHeight:0,isValid:!1,warning:`Invalid joinTime: ${t}. Must be in range (0, 1).`};if(a===0)return{joinHeight:0,isValid:!1,warning:`Invalid headVelocityAtEnd: ${a}. Must be non-zero.`};if(n<=0)return{joinHeight:0,isValid:!1,warning:`Invalid tailVelocityAtStart: ${n}. Must be positive.`};const o=a*(1-t)+t*n;if(Math.abs(o)<1e-10)return{joinHeight:0,isValid:!1,warning:"Denominator too close to zero. Cannot calculate join height."};const r=t*n/o;let s;return r<0?s=`Join height is negative (${r.toFixed(4)}). This may indicate incompatible velocities.`:r>1?a<0?s=`Join height exceeds 1 (${r.toFixed(4)}) due to negative head slope. This creates a natural reflection/dip effect.`:s=`Join height exceeds 1 (${r.toFixed(4)}). This may cause overshoot beyond target.`:a<0&&r<=1&&(s=`Head ends with negative slope (${a.toFixed(4)}). Curve will dip below join height before tail recovers.`),{joinHeight:r,isValid:!0,warning:s}}function yt(e){const{joinTime:t,headVelocityAtEnd:a,pulseNaturalStartVelocity:n,isBounceStrategy:o}=e;if(o)return{isValid:!1,failureReason:"bounce_tail_unsupported"};if(n<=0)return{isValid:!1,failureReason:"invalid_pulse_velocity"};const r=n;let s=r*t/a;s<0&&(s=1),s>=1&&(s=.9999);const u=(1-s)/r;return u<=0?{isValid:!1,failureReason:"invalid_bridge_duration"}:t+u>=1?{isValid:!1,failureReason:"bridge_exceeds_timeline"}:{isValid:!0,bridgeParams:{joinHeight:s,duration:u,velocity:r}}}function Xt(e,t,a){return e!==void 0&&Number.isFinite(e)&&e>0&&t>0&&a>0}function Rt(e,t,a,n){return t?e*a/n:0}function Ut(e,t,a){const n=e;return 1/(1/n+(a-a/n)+(1-a)/t)}function Wt(e){const{joinTime:t,headVelocityAtEnd:a,tailVelocityAtStart:n,maxSpeed:o,naturalJoinHeight:r,naturalJoinHeightIsValid:s}=e;if(Rt(r,s,a,t)<=o)return null;const u=a,d=Ut(u,n,t),l=Math.max(o,Math.max(d,1));let c;if(Math.abs(1/u-1)<1e-9)c=0;else{const E=1/u-1,p=1-1/n,x=1/l-1/n,V=t*E/(1-t),_=p-V;let S;Math.abs(_)<1e-9?S=t:S=(x-V)/_,S=Math.max(t,Math.min(1-.01,S)),c=t*(1-S)/(1-t),c=Math.max(0,Math.min(t,c))}const M=c>0?l*c/u:0,b=c>0?t+(t-c)*(1-t)/t:t+(1-t)*(1-1/(l*(1/n))),P=Math.max(t,Math.min(1-.01,b)),f=M+l*(t-c)+l*(P-t),I=1-P;return f<=0||f>=1||I<=.01?null:{cruiseSpeed:l,tStar:c,tC:P,headHeight:M,tailStartPos:f}}function Zt(e,t,a){const{cruiseSpeed:n,tStar:o,tC:r,headHeight:s,tailStartPos:i}=e,u=1-r;return d=>{if(d<=0)return 0;if(d>=1)return 1;if(o>0&&d<=o){const l=d/o;return s*t(l)}else{if(d<=r)return(o>0?s:0)+n*(d-o);{const l=(d-r)/u;return i+(1-i)*a(l)}}}}function Qt(e){const{joinTime:t,headBounces:a,headDecay:n,tailBounces:o,tailDecay:r,springTailBuilder:s}=e,i=s.build({joinTime:.5,bounces:a,decayPct:n,bridge:void 0}),u=v.reverseEasingFn(i.p),d=y=>u(y*.5),l=y=>i.v(1-y*.5)*.5,c=t,M=y=>y<=0?0:y>=t?t:c*d(y/t),b=y=>y<=0||y>=t?0:c/t*l(y/t);return s.build({joinTime:t,bounces:o,decayPct:r,L:M,Ld:b,bridge:void 0}).p}const jt=10;function te(e){const{joinTime:t,headBounces:a,headDecay:n,tailBounces:o,tailDecay:r}=e;if(t<=0||t>=1)return{easingFn:null};if(a<1||o<1)return{easingFn:null};const s=ct.build({joinTime:.5,bounces:a,decayPct:n,bridge:void 0}),i=ct.build({joinTime:.5,bounces:o,decayPct:r,bridge:void 0}),u=v.reverseEasingFn(s.p),d=_=>u(_*.5),l=jt,c=t,M=c/l,b=(1-c)/l,P=t-M,y=t+b,f=1-y;if(P<=0||M<=0||b<=0||f<=0)return{easingFn:null};const I=2*P,E=2*f,p=d(1),x=i.p(.5);return{easingFn:_=>{if(_<=0)return 0;if(_>=1)return 1;if(_<=P){const S=_/P;return I*d(S)}else if(_<=t){const S=I*p,H=(_-P)/M;return S+(c-S)*H}else if(_<=y){const S=1-E*(1-x),H=(_-t)/b;return c+(S-c)*H}else{const S=(_-y)/f,H=i.p(.5+S*.5);return 1-E*(1-H)}},diagnostics:{joinPosition:c,headBridgeDuration:M,tailBridgeDuration:b,headPulseDuration:P,tailPulseDuration:f,bridgeVelocity:l}}}function ee(){return{easingFn:e=>e,velocityFn:()=>1}}function ne(e,t){const{joinTime:a,pulseTail:n,useBridge:o=!0,bridgeTuning:r}=e;if(a<=0||a>=1)throw new Error(`Invalid joinTime: ${a}. Must be in range (0, 1).`);if(n.bounces<1)throw new Error(`Invalid pulse tail bounces: ${n.bounces}. Must be >= 1.`);const s=ee(),i=1-a,u=t(n.strategy,{head:s.easingFn,headVelocityFn:s.velocityFn,join:i,bounces:n.bounces,decay:n.decay,useBridge:o,bridgeTuning:r});return v.reverseEasingFn(u)}function L(e){return e.params}function ae(e,t,a={}){const{joinTime:n=.5,movement:o="transition",mirror:r=!1,useBridge:s=!0,bridgeTuning:i,allowGeneralizedBackTail:u=!1,maxSpeed:d}=a,l={movement:o,headKind:e.kind,tailKind:t.kind,joinTime:n,mirror:r};return o==="pulse"?re(e,t,n,l):se(e,t,{joinTime:n,mirror:r,useBridge:s,bridgeTuning:i,allowGeneralizedBackTail:u,maxSpeed:d,meta:l})}function re(e,t,a,n){const r=(e.kind==="spring"?R.create({exponent:L(e).bounces??2}):e).easeOut;let s;if(t.kind==="spring"){const{bounces:i,decay:u}=L(t);s=lt(r,zt({bounces:i,decay:u*100}),a)}else if(t.kind==="bounce"){const{bounces:i,decay:u}=L(t);s=lt(r,Dt({bounces:i,decay:u*100}),a)}else s=At(r,t.easeIn,a);return v.easingKit(s,n)}function se(e,t,a){const{joinTime:n,mirror:o}=a,r=qt(n);return r.atStart&&!(t.kind==="spring"||t.kind==="bounce")?v.easingKit(s=>Math.max(0,Math.min(1,s)),a.meta):r.atEnd?v.easingKit(e.easeIn,a.meta):e.kind==="spring"?oe(e,t,a):t.kind==="spring"||t.kind==="bounce"?ie(e,t,a):e.kind==="bezier"&&t.kind==="bezier"?ce(e,t,a):le(e,t,a)}function oe(e,t,a){const{joinTime:n,useBridge:o,bridgeTuning:r}=a,s=L(e),i=s.bounces??4,u=(s.decay??.95)*100;if(t.kind==="spring"){const f=L(t),I=te({joinTime:n,headBounces:i,headDecay:u,tailBounces:f.bounces,tailDecay:f.decay*100});if(I.easingFn)return v.easingKit(I.easingFn,a.meta);const E=Qt({joinTime:n,headBounces:i,headDecay:u,tailBounces:f.bounces,tailDecay:f.decay*100,springTailBuilder:Z});return v.easingKit(E,a.meta)}if(t.kind==="bounce"){const f=L(t),I=ne({joinTime:n,springHead:{decay:f.decay*100},pulseTail:{strategy:j,bounces:f.bounces,decay:f.decay*100},useBridge:o,bridgeTuning:r},(E,p)=>dt(E,p));return v.easingKit(I,a.meta)}const d=a.mirror?v.reverseEasingFn(e.easeIn):t.easeOut,l=a.mirror?f=>e.easeInVelocity(1-f):t.easeOutVelocity,c=v.reverseEasingFn(d),M=f=>l(1-f),b=1-n,P=dt(Z,{head:c,headVelocityFn:M,joinTime:b,bounces:i,decay:u,useBridge:!0,bridgeTuning:r}),y=v.reverseEasingFn(P);return v.easingKit(y,a.meta)}function ie(e,t,a){const{joinTime:n,useBridge:o,bridgeTuning:r}=a,s=L(t),i=s.bounces,u=s.decay*100,d=(t.kind==="spring",t.constructor.tailStrategy),l=e.easeIn,c=e.easeInVelocity;let M;const b=t.kind==="spring";if(o&&!b&&d.getNaturalStartVelocity){const y=d.getNaturalStartVelocity({bounces:i,decayPct:u},c,r),f=yt({joinTime:n,headVelocityAtEnd:c(1),pulseNaturalStartVelocity:y,isBounceStrategy:t.kind==="bounce"});f.isValid&&(M=f.bridgeParams)}const P=d.build({joinTime:n,bounces:i,decayPct:u,L:l,Ld:c,bridge:M});return v.easingKit(P.p,a.meta)}function ce(e,t,a){const{joinTime:n}=a,o=L(e),r=L(t),s=n,i=o.x1*n,u=o.y1*s,d=o.x2*n,l=o.y2*s,c=n,M=s;let b;Math.abs(c-d)<1e-8?b=1e8:b=(M-l)/(c-d);const P=n+r.x1*(1-n),y=s+b*(P-n),f=n+r.x2*(1-n),I=s+r.y2*(1-s),E=i/n,p=u/s,x=d/n,V=l/s,_=tt(E,p,x,V),S=(P-n)/(1-n),H=(y-s)/(1-s),k=(f-n)/(1-n),F=(I-s)/(1-s),N=tt(S,H,k,F),A=K=>{if(K<=0)return 0;if(K>=1)return 1;if(K<=n){const m=K/n;return s*_(m)}else{const m=(K-n)/(1-n);return s+(1-s)*N(m)}};return v.easingKit(A,a.meta)}function le(e,t,a){const{joinTime:n,mirror:o,allowGeneralizedBackTail:r,maxSpeed:s}=a,i=e.easeIn,u=e.easeInVelocity;let d,l;o?(d=v.reverseEasingFn(i),l=I=>u(1-I)):(d=t.easeOut,l=t.easeOutVelocity);const c=u(1),M=l(0);if(Xt(s,c,M)){const I=ut({joinTime:n,headVelocityAtEnd:c,tailVelocityAtStart:M}),E=Wt({joinTime:n,headVelocityAtEnd:c,tailVelocityAtStart:M,maxSpeed:s,naturalJoinHeight:I.joinHeight,naturalJoinHeightIsValid:I.isValid});if(E){const p=Zt(E,i,d);return v.easingKit(p,a.meta)}}let b,P=!1,y=c;if(c<0&&(t.kind==="power"||t.kind==="back"))b=1,P=!0,y=c*(b/n);else{const I=ut({joinTime:n,headVelocityAtEnd:c,tailVelocityAtStart:M});if(!I.isValid)return v.easingKit(p=>Math.max(0,Math.min(1,p)),a.meta);const E=I.joinHeight;b=Math.max(0,Math.min(1,E)),r&&b>=.9999&&(t.kind==="power-back"||t.kind==="back"||t.kind==="power")&&(P=!0,b=1,y=c*(b/n))}const f=I=>{if(I<=0)return 0;if(I>=1)return 1;if(I<=n){const E=I/n;return b*i(E)}else{const E=(I-n)/(1-n);if(P){const p=y*(1-n),x=b,V=p,_=(3*(1-x)-2*V)/(V-(1-x));return(1-V-x)*((_+1)*E*E*E-_*E*E)+V*E+x}else return b+(1-b)*d(E)}};return v.easingKit(f,a.meta)}function dt(e,t){const{head:a=c=>c,headVelocityFn:n=()=>1,joinTime:o=.5,bounces:r=4,decay:s=95,useBridge:i=!0,bridgeTuning:u}=t;let d;if(i&&e.getNaturalStartVelocity){const c=e.getNaturalStartVelocity({bounces:r,decayPct:s},n,u),M=yt({joinTime:o,headVelocityAtEnd:n(1),pulseNaturalStartVelocity:c,isBounceStrategy:e===j});M.isValid&&(d=M.bridgeParams)}return e.build({joinTime:o,bounces:r,decayPct:s,L:a,Ld:n,bridge:d}).p}class U extends Y{static OVERSHOOT_KNOB={key:"overshoot",label:"Overshoot",type:"percent",default:.1,min:0,max:1,step:.01,isPrimary:!0};kind="back";metadata={variants:{easeIn:!0,easeOut:!0},modes:{transition:!0,pulse:!0}};knobSpecs=[U.OVERSHOOT_KNOB];easeInBoundary={start:"zero",end:"nonzero"};strength;constructor(t){super(t),this.strength=v.solveBackStrength(t.overshoot)}easeIn=t=>v.backEaseIn(t,this.strength);easeInVelocity=t=>v.backEaseInVelocity(t,this.strength);easeOutVelocity=t=>v.backEaseInVelocity(1-t,this.strength);with(t){return new U({...this.params,...t})}static create(t={}){const a=t.overshoot??.1;return new U({overshoot:a})}}class G extends Y{static EXPONENT_KNOB={key:"exponent",label:"Exponent",type:"number",default:3,min:.1,max:10,step:.01,isPrimary:!0};static OVERSHOOT_KNOB={key:"overshoot",label:"Overshoot",type:"percent",default:0,min:0,max:1,step:.01};kind="power-back";metadata={variants:{easeIn:!0,easeOut:!0},modes:{transition:!0,pulse:!0}};knobSpecs=[G.EXPONENT_KNOB,G.OVERSHOOT_KNOB];strength;constructor(t){super(t),this.strength=Q(t.overshoot,t.exponent)}get easeInBoundary(){return{start:this.params.exponent>2||this.params.overshoot<=0?"zero":"nonzero",end:"nonzero"}}easeIn=t=>pt(t,this.params.exponent,this.strength);easeInVelocity=t=>gt(t,this.params.exponent,this.strength);easeOutVelocity=t=>this.easeInVelocity(1-t);with(t){return new G({...this.params,...t,exponent:Math.max(.1,t.exponent??this.params.exponent)})}static create(t={}){const a=Math.max(.1,t.exponent??3),n=t.overshoot??.3;return new G({exponent:a,overshoot:n})}}class D extends Y{static X1_KNOB={key:"x1",label:"X1",type:"number",default:.42,min:0,max:1,step:.01};static Y1_KNOB={key:"y1",label:"Y1",type:"number",default:0,min:-.5,max:1.5,step:.01};static X2_KNOB={key:"x2",label:"X2",type:"number",default:1,min:0,max:1,step:.01};static Y2_KNOB={key:"y2",label:"Y2",type:"number",default:1,min:-.5,max:1.5,step:.01};kind="bezier";metadata={variants:{easeIn:!0,easeOut:!0},modes:{transition:!0,pulse:!0}};knobSpecs=[D.X1_KNOB,D.Y1_KNOB,D.X2_KNOB,D.Y2_KNOB];easeInBoundary={start:"nonzero",end:"nonzero"};bezier=tt(this.params.x1,this.params.y1,this.params.x2,this.params.y2);easeIn=t=>this.bezier(t);easeOut=t=>this.bezier(t);constructor(t){super(t);const a=()=>v.createVelocityFn(this.bezier,{boundarySample:.001});et(this,"easeInVelocity",a),et(this,"easeOutVelocity",a)}with(t){return new D({...this.params,...t})}static create(t={}){return new D({x1:t.x1??.42,y1:t.y1??0,x2:t.x2??1,y2:t.y2??1})}}class W extends Y{static DECAY_KNOB={key:"decay",label:"Decay",type:"percent",default:.95,min:.8,max:.999,step:.001,isPrimary:!0};kind="expo";metadata={variants:{easeIn:!1,easeOut:!0},modes:{transition:!0,pulse:!1}};knobSpecs=[W.DECAY_KNOB];easeInBoundary={start:"nonzero",end:"nonzero"};easeOutFn;negK;scale;d;constructor(t){super(t),this.d=Math.max(0,Math.min(1,t.decay)),this.d===0?(this.easeOutFn=a=>Math.max(0,Math.min(1,a)),this.negK=0,this.scale=1):this.d===1?(this.easeOutFn=a=>a>0?1:0,this.negK=-1/0,this.scale=0):(this.negK=Math.log1p(-this.d),this.scale=1/Math.expm1(this.negK),this.easeOutFn=v.makeExpoEaseOut(this.d))}easeIn=t=>1-this.easeOutFn(1-t);easeInVelocity=t=>this.easeOutVelocityImpl(1-t);easeOut=t=>this.easeOutFn(t);easeOutVelocity=t=>this.easeOutVelocityImpl(t);easeOutVelocityImpl(t){return this.d===0?1:this.d===1?0:this.negK*Math.exp(this.negK*t)*this.scale}with(t){return new W({...this.params,...t})}static create(t={}){return new W({decay:t.decay??.95})}}const ue=e=>e,de=e=>1,he=1e-4;class q extends Y{static BOUNCES_KNOB={key:"bounces",label:"Bounces",type:"number",default:4,min:0,max:10,step:1,isPrimary:!0};static DECAY_KNOB={key:"decay",label:"Decay",type:"percent",default:.95,min:0,max:.99,step:.01};kind="spring";metadata={variants:{easeIn:!1,easeOut:!0},modes:{transition:!0,pulse:!0}};knobSpecs=[q.BOUNCES_KNOB,q.DECAY_KNOB];easeInBoundary={start:"nonzero",end:"nonzero"};builtP;builtV;constructor(t){super(t);const a=Z.build({joinTime:he,bounces:t.bounces,decayPct:t.decay*100,L:ue,Ld:de});this.builtP=a.p,this.builtV=a.v}easeIn=t=>1-this.builtP(1-t);easeInVelocity=t=>this.builtV(1-t);easeOut=t=>this.builtP(t);easeOutVelocity=t=>this.builtV(t);static get tailStrategy(){return Z}with(t){return new q({...this.params,...t})}static create(t={}){return new q({bounces:t.bounces??4,decay:t.decay??.95})}}const fe=e=>e,pe=e=>1,ge=1e-4;class X extends Y{static BOUNCES_KNOB={key:"bounces",label:"Bounces",type:"number",default:4,min:1,max:10,step:1,isPrimary:!0};static DECAY_KNOB={key:"decay",label:"Decay",type:"percent",default:.95,min:0,max:.99,step:.01};kind="bounce";metadata={variants:{easeIn:!1,easeOut:!0},modes:{transition:!0,pulse:!0}};knobSpecs=[X.BOUNCES_KNOB,X.DECAY_KNOB];easeInBoundary={start:"nonzero",end:"nonzero"};builtP;builtV;constructor(t){super(t);const a=j.build({joinTime:ge,bounces:t.bounces,decayPct:t.decay*100,L:fe,Ld:pe});this.builtP=a.p,this.builtV=a.v}easeIn=t=>1-this.builtP(1-t);easeInVelocity=t=>this.builtV(1-t);easeOut=t=>this.builtP(t);easeOutVelocity=t=>this.builtV(t);static get tailStrategy(){return j}with(t){return new X({...this.params,...t})}static create(t={}){return new X({bounces:t.bounces??4,decay:t.decay??.95})}}const ye={power:R,back:U,"power-back":G,bezier:D,expo:W,spring:q,bounce:X,swim:J};function st(e,t){return ye[e].create(t)}function ht(e){const{kind:t,...a}=e;return a}function me(e){const{movement:t="transition",head:a,tail:n,joinTime:o=.5,mirror:r=!1,useBridge:s,bridgeTuning:i,allowGeneralizedBackTail:u,maxSpeed:d}=e,l=st(a.kind,ht(a)),c=st(n.kind,ht(n));return ae(l,c,{movement:t,joinTime:o,mirror:r,useBridge:s,bridgeTuning:i,allowGeneralizedBackTail:u,maxSpeed:d})}const mt=1e-6,it=mt,Mt=1-mt;function Me(e,t,a=!1){return!a&&(t==="power-back"||t==="back"||t==="power")?Math.min(1,e):e}function be(e,t,a=!1){return!a&&t==="power-back"?Math.max(0,e):e}exports.BackRem=U;exports.BezierRem=D;exports.BounceRem=X;exports.ExpoRem=W;exports.PowerBackRem=G;exports.PowerRem=R;exports.SpringRem=q;exports.SwimRem=J;exports.calculateHeadP2FromTailP1=Lt;exports.calculateTailP1FromHeadP2=Ct;exports.clampBezierY1ForHead=be;exports.clampBezierY2ForTail=Me;exports.evalPowerBackIn=pt;exports.findExponentForMinimumPosition=Bt;exports.fuse=me;exports.getEasingRem=st;exports.getLocalMinimumPosition=kt;exports.getPowerCurveCanonicalPoint=St;exports.getTailStrategy=Kt;exports.solvePowerBackStrength=Q;
|
|
2
|
+
//# sourceMappingURL=index.cjs.js.map
|