Build your own easing curve and use it on keys and Lerp (#247)
The built-in eases cover the usual shapes, but a game often wants its own: a coin that bounces twice, a door that overshoots and settles. A new asset type holds such a curve, and keys and the Lerp node can pick it instead of a built-in ease. - New asset type "curve": points like in Vector art, x is t and y is the value. A new curve is the straight line from (0, 0) to (1, 1). - One pure evaluation in src/core/model/curve.ts serves the timeline preview, the running game and the Lerp node. - The curve always has one value per t. The end points stay at t 0 and 1, points cannot pass each other, and a handle that reaches past its neighbour is shortened along its direction. Loading a hand-edited file applies the same rules. - Curve tab: click on the line to insert a point that keeps the shape, click on free space to put one there, drag points and handles, double-click or Delete removes, Alt-click toggles round and sharp. Every step is one undo step. - Presets: all 30 built-in eases plus Linear, fitted with adaptive subdivision. Each stays within 0.4 % of the built-in ease. - Preview: a dot runs along the curve once a second, a second dot shows only the value. The Preview button stops it. - Animation keys get "Curve" under Easing with a curve picker. Lerp gets "Curve" under Ease, and its result may overshoot b. - A missing or unpicked curve runs linear. The inspector says so, the node shows it as a problem, and deleting a used curve warns with the number of keys and Lerp nodes. Tests: - ./check.sh: 180 files, 2612 tests, CHECK EXIT 0 - GM_STEPS=1-6,25,53: ALL PASSED, 309 checks - New e2e module 53 with 13 checks, all with the real mouse. Expected values come from its own Bezier evaluation. - Counter-checks bite: without Bezier evaluation 4 unit tests fail, without handle clamping 2. In the browser, a key that cannot find its curve, a click that sets no point and a handle drag that moves the point all turn checks red. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
320d3e27e1
commit
393b8ec7f9
41 files changed
+1981
-67
No files matched your search
@@ -52,6 +52,19 @@ const machineWithStates = (states: { id: string; name: string }[]): GraphLookup
|
||||
machine: (id) => (id === 'm' ? { name: 'M', states, start: '', transitions: [] } : null),
|
||||
});
|
||||
|
||||
/** A lookup holding one curve "c" (#247): straight up to 1.5 at the middle, back down to 1 at the end. */
|
||||
const overshootingCurve: GraphLookup = {
|
||||
...NO_LOOKUP,
|
||||
curve: (id) =>
|
||||
id === 'c'
|
||||
? [
|
||||
{ x: 0, y: 0 },
|
||||
{ x: 0.5, y: 1.5 },
|
||||
{ x: 1, y: 1 },
|
||||
]
|
||||
: null,
|
||||
};
|
||||
|
||||
/** A lookup holding one machine "m" with the given transitions – what `State transition` reads. */
|
||||
const machineLookup = (transitions: { from: string; to: string; name?: string }[]): GraphLookup => ({
|
||||
...NO_LOOKUP,
|
||||
@@ -579,6 +592,20 @@ const CASES: Record<string, Case[]> = {
|
||||
params: { ease: 'out' },
|
||||
outputs: { result: 3 },
|
||||
},
|
||||
{
|
||||
name: 'along a Curve asset, overshooting b',
|
||||
inputs: { a: 0, b: 8, t: 0.5 },
|
||||
params: { ease: 'curve', curve: 'c' },
|
||||
lookup: overshootingCurve,
|
||||
outputs: { result: 12 },
|
||||
},
|
||||
{
|
||||
name: 'along a Curve asset that is gone: linear',
|
||||
inputs: { a: 0, b: 8, t: 0.25 },
|
||||
params: { ease: 'curve', curve: 'gone' },
|
||||
lookup: overshootingCurve,
|
||||
outputs: { result: 2 },
|
||||
},
|
||||
],
|
||||
Floor: [
|
||||
{ name: 'rounds down', inputs: { value: 2.9 }, outputs: { result: 2 } },
|
||||
|
||||
Reference in new issue
Block a user