@msb235/blits 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +154 -0
- package/README.md +3 -3
- package/dist/ahead.d.ts +26 -0
- package/dist/ahead.js +264 -0
- package/dist/around.d.ts +11 -0
- package/dist/around.js +32 -0
- package/dist/bare.js +15 -7
- package/dist/blank.d.ts +10 -0
- package/dist/blank.js +26 -0
- package/dist/blend.d.ts +2 -1
- package/dist/blend.js +1 -6
- package/dist/bound.d.ts +70 -0
- package/dist/bound.js +351 -0
- package/dist/chain.d.ts +2 -1
- package/dist/chain.js +7 -5
- package/dist/changes.d.ts +24 -0
- package/dist/changes.js +189 -0
- package/dist/channels.d.ts +39 -13
- package/dist/channels.js +14 -5
- package/dist/color.d.ts +12 -10
- package/dist/color.js +25 -25
- package/dist/columns.js +7 -3
- package/dist/contribution.d.ts +30 -0
- package/dist/contribution.js +374 -0
- package/dist/copyout.d.ts +10 -0
- package/dist/copyout.js +69 -24
- package/dist/crowd.d.ts +8 -2
- package/dist/crowd.js +4 -5
- package/dist/cue.d.ts +8 -1
- package/dist/cue.js +39 -13
- package/dist/cut.d.ts +8 -0
- package/dist/cut.js +4 -0
- package/dist/drop.d.ts +9 -0
- package/dist/drop.js +84 -0
- package/dist/due.d.ts +24 -5
- package/dist/due.js +113 -33
- package/dist/easing.d.ts +4 -4
- package/dist/easing.js +3 -3
- package/dist/everyone.d.ts +3 -2
- package/dist/everyone.js +3 -3
- package/dist/fade.d.ts +2 -1
- package/dist/fade.js +2 -1
- package/dist/fill.d.ts +3 -2
- package/dist/fill.js +51 -19
- package/dist/fit.d.ts +44 -26
- package/dist/fit.js +10 -9
- package/dist/fold.d.ts +4 -37
- package/dist/fold.js +5 -513
- package/dist/gather.d.ts +12 -7
- package/dist/gather.js +179 -44
- package/dist/gone.js +2 -2
- package/dist/grid.d.ts +47 -0
- package/dist/grid.js +247 -0
- package/dist/handle.d.ts +2 -0
- package/dist/handle.js +14 -8
- package/dist/held.d.ts +2 -1
- package/dist/history.d.ts +6 -5
- package/dist/history.js +7 -9
- package/dist/hosts.js +9 -15
- package/dist/index.d.ts +5 -4
- package/dist/keyfill.d.ts +1 -1
- package/dist/keyfill.js +5 -3
- package/dist/keyrows.d.ts +12 -0
- package/dist/keyrows.js +99 -12
- package/dist/lane.d.ts +36 -6
- package/dist/lane.js +32 -1
- package/dist/lanes.d.ts +23 -8
- package/dist/lanes.js +29 -8
- package/dist/leavings.d.ts +2 -2
- package/dist/leavings.js +1 -1
- package/dist/lives.d.ts +47 -0
- package/dist/lives.js +180 -0
- package/dist/meet.d.ts +2 -2
- package/dist/meet.js +90 -4
- package/dist/mixer.d.ts +54 -36
- package/dist/mixer.js +53 -171
- package/dist/motion.d.ts +14 -118
- package/dist/motion.js +16 -8
- package/dist/motions.d.ts +62 -155
- package/dist/motions.js +56 -370
- package/dist/moved.d.ts +1 -1
- package/dist/moved.js +16 -7
- package/dist/named.d.ts +0 -1
- package/dist/named.js +20 -2
- package/dist/numbers.d.ts +2 -0
- package/dist/numbers.js +4 -0
- package/dist/owed.d.ts +2 -0
- package/dist/owed.js +4 -0
- package/dist/pack.d.ts +2 -1
- package/dist/pack.js +2 -3
- package/dist/patch.d.ts +7 -3
- package/dist/patch.js +6 -2
- package/dist/places.d.ts +53 -0
- package/dist/places.js +171 -0
- package/dist/plot.d.ts +12 -0
- package/dist/plot.js +52 -0
- package/dist/project.d.ts +4 -4
- package/dist/project.js +9 -212
- package/dist/pull.js +11 -8
- package/dist/qualify.js +84 -21
- package/dist/reading.d.ts +6 -0
- package/dist/reading.js +5 -0
- package/dist/record.d.ts +5 -1
- package/dist/record.js +3 -2
- package/dist/relink.d.ts +1 -1
- package/dist/restored.d.ts +2 -2
- package/dist/restored.js +1 -1
- package/dist/rests.d.ts +9 -0
- package/dist/rests.js +76 -0
- package/dist/revive.d.ts +3 -2
- package/dist/revive.js +2 -2
- package/dist/{locus.d.ts → role.d.ts} +10 -9
- package/dist/{locus.js → role.js} +3 -3
- package/dist/roles.d.ts +10 -0
- package/dist/roles.js +158 -0
- package/dist/roster.js +3 -3
- package/dist/rotation.d.ts +1 -1
- package/dist/rotation.js +1 -1
- package/dist/rows.js +1 -1
- package/dist/sample.d.ts +2 -2
- package/dist/sample.js +33 -7
- package/dist/seek.js +5 -5
- package/dist/setting.d.ts +27 -0
- package/dist/setting.js +55 -0
- package/dist/shared.d.ts +1 -1
- package/dist/shared.js +1 -1
- package/dist/signals.d.ts +64 -32
- package/dist/signals.js +20 -18
- package/dist/stack.d.ts +5 -5
- package/dist/stack.js +5 -5
- package/dist/standing.d.ts +2 -1
- package/dist/standing.js +3 -2
- package/dist/store.d.ts +9 -0
- package/dist/store.js +24 -0
- package/dist/strays.d.ts +2 -1
- package/dist/strays.js +20 -13
- package/dist/stretch.d.ts +112 -0
- package/dist/stretch.js +9 -0
- package/dist/subject.d.ts +142 -0
- package/dist/subject.js +1 -0
- package/dist/tape.d.ts +9 -5
- package/dist/tape.js +5 -1
- package/dist/then.d.ts +9 -0
- package/dist/then.js +57 -0
- package/dist/ticker.d.ts +4 -4
- package/dist/transport.d.ts +0 -8
- package/dist/transport.js +0 -4
- package/dist/turns.d.ts +4 -3
- package/dist/turns.js +4 -3
- package/dist/types/arc.d.ts +12 -11
- package/dist/types/channel.d.ts +12 -8
- package/dist/types/history.d.ts +35 -19
- package/dist/types/mix.d.ts +222 -163
- package/dist/types/motion.d.ts +151 -0
- package/dist/types/motion.js +1 -0
- package/dist/types/patch.d.ts +67 -34
- package/dist/types/place.d.ts +51 -36
- package/dist/types/transport.d.ts +20 -18
- package/dist/types/voice.d.ts +136 -70
- package/dist/types/watch.d.ts +88 -40
- package/dist/types.d.ts +1 -0
- package/dist/voice.d.ts +7 -143
- package/dist/voice.js +28 -79
- package/dist/warn.d.ts +2 -0
- package/dist/warn.js +1 -1
- package/dist/watch.d.ts +2 -2
- package/dist/watch.js +5 -3
- package/dist/wave.d.ts +4 -3
- package/dist/wave.js +3 -2
- package/dist/weigh.d.ts +7 -1
- package/dist/weigh.js +27 -0
- package/docs/schema.html +212 -34
- package/package.json +2 -2
package/dist/channels.d.ts
CHANGED
|
@@ -26,6 +26,11 @@ export interface Numeric {
|
|
|
26
26
|
axes: number;
|
|
27
27
|
/** An angle's full turn: each value is taken the short way round before it folds. */
|
|
28
28
|
turn?: number;
|
|
29
|
+
/**
|
|
30
|
+
* An `'own'` channel whose fold is this plain arithmetic, its lerp alone its own: a lane folds
|
|
31
|
+
* it as the op and lerps it through the channel. A copy that predates it folds it as `'own'`.
|
|
32
|
+
*/
|
|
33
|
+
folds?: 'sum';
|
|
29
34
|
}
|
|
30
35
|
/**
|
|
31
36
|
* The stock arithmetic of a channel `sum`, `mul`, `max` or `vec` made, or `vouch` was given, keyed
|
|
@@ -55,49 +60,71 @@ export interface NumberOptions {
|
|
|
55
60
|
bounds?: readonly [min: number, max: number];
|
|
56
61
|
}
|
|
57
62
|
/**
|
|
58
|
-
*
|
|
63
|
+
* A number whose contributions add, resting at 0.
|
|
64
|
+
*
|
|
65
|
+
* A weight scales a contribution toward 0, so two voices each moving `x` by 10 at half weight move it
|
|
66
|
+
* 10 in all. For position axes, rotation, crawl, yaw, pitch, offset.
|
|
59
67
|
*
|
|
60
68
|
* @category channel
|
|
61
69
|
*/
|
|
62
70
|
export declare function sum(opts?: NumberOptions): Channel<number>;
|
|
63
71
|
/**
|
|
64
|
-
*
|
|
72
|
+
* A number whose contributions multiply, resting at 1.
|
|
73
|
+
*
|
|
74
|
+
* A weight fades a contribution toward 1 rather than 0, so 0.5 at half weight multiplies by 0.75, and
|
|
75
|
+
* at weight 0 it leaves the value alone. For gain, scale, opacity, hold.
|
|
65
76
|
*
|
|
66
77
|
* @category channel
|
|
67
78
|
*/
|
|
68
79
|
export declare function mul(opts?: NumberOptions): Channel<number>;
|
|
69
80
|
/**
|
|
70
|
-
*
|
|
81
|
+
* A number where the largest contribution wins, resting at 0.
|
|
82
|
+
*
|
|
83
|
+
* A weight scales a contribution toward 0 before the comparison, so a fading voice gives way once
|
|
84
|
+
* another's value passes its scaled one. For dark, aperture.
|
|
71
85
|
*
|
|
72
86
|
* @category channel
|
|
73
87
|
*/
|
|
74
88
|
export declare function max(opts?: NumberOptions): Channel<number>;
|
|
75
89
|
/**
|
|
76
|
-
*
|
|
90
|
+
* What `last` takes.
|
|
91
|
+
*
|
|
92
|
+
* @category channel
|
|
93
|
+
*/
|
|
94
|
+
export interface LastOptions<V> {
|
|
95
|
+
/** How to interpolate between two values. Default: step at the midpoint. */
|
|
96
|
+
lerp?: (a: V, b: V, u: number) => V;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A channel with no rest, where the last contribution to pass wins. A weight can only gate it. The
|
|
77
100
|
* default `lerp` steps at the midpoint, which is all a value with no arithmetic can promise; a
|
|
78
101
|
* consumer with a real interpolation passes its own, as `hex` does.
|
|
79
102
|
*
|
|
80
103
|
* @category channel
|
|
81
104
|
*/
|
|
82
|
-
export declare function last<V>(opts?:
|
|
83
|
-
lerp?: (a: V, b: V, u: number) => V;
|
|
84
|
-
}): Channel<V>;
|
|
105
|
+
export declare function last<V>(opts?: LastOptions<V>): Channel<V>;
|
|
85
106
|
/**
|
|
86
107
|
* `n` copies of `v` in an array the engine stores as doubles from the start, so a copy of it, and
|
|
87
108
|
* every fraction written into that copy, keeps one element kind: a pose's arrays then look alike to
|
|
88
109
|
* every fold, whichever path made them.
|
|
89
110
|
*/
|
|
90
111
|
export declare function doubles(n: number, v: number): number[];
|
|
91
|
-
type Tuple<N extends number, T extends number[] = []> = T['length'] extends N ? T : Tuple<N, [...T, number]>;
|
|
92
112
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
113
|
+
* A tuple of `N` numbers, as `NumberTuple<3>` is `[number, number, number]`. `T` is the tuple built
|
|
114
|
+
* so far; leave it out.
|
|
115
|
+
*
|
|
116
|
+
* @category channel
|
|
117
|
+
*/
|
|
118
|
+
export type NumberTuple<N extends number, T extends number[] = []> = T['length'] extends N ? T : NumberTuple<N, [...T, number]>;
|
|
119
|
+
/**
|
|
120
|
+
* `N` numbers, as a tuple where `N` is a literal. `Vec<3>` is `[number, number, number]`, and a
|
|
121
|
+
* `Vec` is `number[]` where `N` is only known to be a number.
|
|
95
122
|
*
|
|
96
123
|
* @category channel
|
|
97
124
|
*/
|
|
98
|
-
export type Vec<N extends number> = number extends N ? number[] :
|
|
125
|
+
export type Vec<N extends number> = number extends N ? number[] : NumberTuple<N>;
|
|
99
126
|
/**
|
|
100
|
-
*
|
|
127
|
+
* One channel's arithmetic applied down an axis list. For a Vec3 position, or premultiplied light.
|
|
101
128
|
*
|
|
102
129
|
* @category channel
|
|
103
130
|
*/
|
|
@@ -108,4 +135,3 @@ export declare function vec<N extends number>(n: N, of: Channel<number>): Channe
|
|
|
108
135
|
* @category channel
|
|
109
136
|
*/
|
|
110
137
|
export declare function kit<O>(channels: Kit<O>): Kit<O>;
|
|
111
|
-
export {};
|
package/dist/channels.js
CHANGED
|
@@ -67,7 +67,10 @@ export function scalarOp(channel) {
|
|
|
67
67
|
/** Bounds change how a value folds at its edges, so they are part of the kind. */
|
|
68
68
|
const kindOf = (name, bounds) => bounds === undefined ? name : `${name}[${bounds[0]}, ${bounds[1]}]`;
|
|
69
69
|
/**
|
|
70
|
-
*
|
|
70
|
+
* A number whose contributions add, resting at 0.
|
|
71
|
+
*
|
|
72
|
+
* A weight scales a contribution toward 0, so two voices each moving `x` by 10 at half weight move it
|
|
73
|
+
* 10 in all. For position axes, rotation, crawl, yaw, pitch, offset.
|
|
71
74
|
*
|
|
72
75
|
* @category channel
|
|
73
76
|
*/
|
|
@@ -84,7 +87,10 @@ export function sum(opts) {
|
|
|
84
87
|
return channel;
|
|
85
88
|
}
|
|
86
89
|
/**
|
|
87
|
-
*
|
|
90
|
+
* A number whose contributions multiply, resting at 1.
|
|
91
|
+
*
|
|
92
|
+
* A weight fades a contribution toward 1 rather than 0, so 0.5 at half weight multiplies by 0.75, and
|
|
93
|
+
* at weight 0 it leaves the value alone. For gain, scale, opacity, hold.
|
|
88
94
|
*
|
|
89
95
|
* @category channel
|
|
90
96
|
*/
|
|
@@ -101,7 +107,10 @@ export function mul(opts) {
|
|
|
101
107
|
return channel;
|
|
102
108
|
}
|
|
103
109
|
/**
|
|
104
|
-
*
|
|
110
|
+
* A number where the largest contribution wins, resting at 0.
|
|
111
|
+
*
|
|
112
|
+
* A weight scales a contribution toward 0 before the comparison, so a fading voice gives way once
|
|
113
|
+
* another's value passes its scaled one. For dark, aperture.
|
|
105
114
|
*
|
|
106
115
|
* @category channel
|
|
107
116
|
*/
|
|
@@ -118,7 +127,7 @@ export function max(opts) {
|
|
|
118
127
|
return channel;
|
|
119
128
|
}
|
|
120
129
|
/**
|
|
121
|
-
* A channel with no rest
|
|
130
|
+
* A channel with no rest, where the last contribution to pass wins. A weight can only gate it. The
|
|
122
131
|
* default `lerp` steps at the midpoint, which is all a value with no arithmetic can promise; a
|
|
123
132
|
* consumer with a real interpolation passes its own, as `hex` does.
|
|
124
133
|
*
|
|
@@ -148,7 +157,7 @@ export function doubles(n, v) {
|
|
|
148
157
|
return a;
|
|
149
158
|
}
|
|
150
159
|
/**
|
|
151
|
-
*
|
|
160
|
+
* One channel's arithmetic applied down an axis list. For a Vec3 position, or premultiplied light.
|
|
152
161
|
*
|
|
153
162
|
* @category channel
|
|
154
163
|
*/
|
package/dist/color.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { Channel } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* OKLCH, hue the short way round
|
|
4
|
-
* instead of dipping through a muddy middle. A mix that leaves sRGB's
|
|
3
|
+
* Crossfades two hex colors in OKLCH, hue the short way round. A crossfade between hues then keeps
|
|
4
|
+
* its lightness and saturation instead of dipping through a muddy middle. A mix that leaves sRGB's
|
|
5
|
+
* gamut is clipped per channel.
|
|
5
6
|
*
|
|
6
7
|
* @category channel
|
|
7
8
|
*/
|
|
8
9
|
export declare function mixHex(a: number, b: number, u: number): number;
|
|
9
10
|
/**
|
|
10
|
-
* How a `color` channel interpolates two colors
|
|
11
|
+
* How a `color` channel interpolates two colors. Straight across OKLab, or in OKLCH with hue the
|
|
11
12
|
* short way round, as `mixHex` does.
|
|
12
13
|
*
|
|
13
14
|
* @category channel
|
|
@@ -21,29 +22,30 @@ export interface ColorOptions {
|
|
|
21
22
|
* `toHex` divides it out and lays it over what is under it. `color(last())` replaces, the last
|
|
22
23
|
* voice to pass winning, at the coverage it was authored with. `lerp` picks how two colors
|
|
23
24
|
* interpolate: OKLab, the default, crosses through gray between opposite hues, and `'oklch'`
|
|
24
|
-
* goes round the hue instead
|
|
25
|
+
* goes round the hue instead.
|
|
25
26
|
*
|
|
26
27
|
* @category channel
|
|
27
28
|
*/
|
|
28
29
|
export declare function color(opts?: ColorOptions): Channel<number[]>;
|
|
29
30
|
export declare function color(of: Channel<number> | Channel<unknown>, opts?: ColorOptions): Channel<number[]>;
|
|
30
31
|
/**
|
|
31
|
-
* 0xrrggbb
|
|
32
|
-
* when authoring them, and call it outside the hot path in an `fn` patch.
|
|
32
|
+
* Converts 0xrrggbb to a `color` value. The value is OKLab `[L, a, b]` at full coverage. Convert
|
|
33
|
+
* keyframe stops once when authoring them, and call it outside the hot path in an `fn` patch.
|
|
33
34
|
*
|
|
34
35
|
* @category channel
|
|
35
36
|
*/
|
|
36
37
|
export declare function oklab(rgb: number): number[];
|
|
37
38
|
/**
|
|
38
|
-
* A `color` pose as 0xrrggbb
|
|
39
|
-
* and laid over `under` in OKLab, then clipped to sRGB per channel. No
|
|
39
|
+
* A `color` pose as 0xrrggbb, laid over `under`. Its color is divided out of its coverage, the
|
|
40
|
+
* coverage capped at 1 and laid over `under` in OKLab, then clipped to sRGB per channel. No
|
|
41
|
+
* coverage gives `under`.
|
|
40
42
|
*
|
|
41
43
|
* @category channel
|
|
42
44
|
*/
|
|
43
45
|
export declare function toHex(pose: ArrayLike<number>, under?: number): number;
|
|
44
46
|
/**
|
|
45
|
-
* A `color` pose as a CSS `oklab()` color
|
|
46
|
-
* host that lets the browser lay it over what is under it.
|
|
47
|
+
* A `color` pose as a CSS `oklab()` color, its coverage as the alpha. The coverage is capped at 1.
|
|
48
|
+
* For a host that lets the browser lay it over what is under it.
|
|
47
49
|
*
|
|
48
50
|
* @category channel
|
|
49
51
|
*/
|
package/dist/color.js
CHANGED
|
@@ -82,8 +82,9 @@ function fromOklch(L, C, h) {
|
|
|
82
82
|
return fromLab(L, C * Math.cos(h), C * Math.sin(h));
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
85
|
-
* OKLCH, hue the short way round
|
|
86
|
-
* instead of dipping through a muddy middle. A mix that leaves sRGB's
|
|
85
|
+
* Crossfades two hex colors in OKLCH, hue the short way round. A crossfade between hues then keeps
|
|
86
|
+
* its lightness and saturation instead of dipping through a muddy middle. A mix that leaves sRGB's
|
|
87
|
+
* gamut is clipped per channel.
|
|
87
88
|
*
|
|
88
89
|
* @category channel
|
|
89
90
|
*/
|
|
@@ -98,14 +99,19 @@ export function mixHex(a, b, u) {
|
|
|
98
99
|
const ah = slotH[sa];
|
|
99
100
|
const sb = oklch(b);
|
|
100
101
|
const bc = slotC[sb];
|
|
101
|
-
const
|
|
102
|
-
|
|
102
|
+
const h = hueAt(ah, ac, slotH[sb], bc, u);
|
|
103
|
+
return fromOklch(mix(al, slotL[sb], u), mix(ac, bc, u), h);
|
|
104
|
+
}
|
|
105
|
+
/** The hue `u` of the way from `ah` to `bh` the short way round, a gray end taking the other's. */
|
|
106
|
+
function hueAt(ah, ac, bh, bc, u) {
|
|
107
|
+
const from = ac < GRAY ? bh : ah;
|
|
108
|
+
const to = bc < GRAY ? ah : bh;
|
|
103
109
|
let turn = to - from;
|
|
104
110
|
if (turn > Math.PI)
|
|
105
111
|
turn -= 2 * Math.PI;
|
|
106
112
|
else if (turn < -Math.PI)
|
|
107
113
|
turn += 2 * Math.PI;
|
|
108
|
-
return
|
|
114
|
+
return from + turn * u;
|
|
109
115
|
}
|
|
110
116
|
/** Two OKLab colors with coverage, interpolated in OKLCH: color by `u`, coverage by `u` alongside. */
|
|
111
117
|
function lerpLch(x, y, u) {
|
|
@@ -126,17 +132,8 @@ function lerpLch(x, y, u) {
|
|
|
126
132
|
const toB = yw > 0 ? yB : xB;
|
|
127
133
|
const xc = Math.sqrt(xA * xA + xB * xB);
|
|
128
134
|
const yc = Math.sqrt(toA * toA + toB * toB);
|
|
129
|
-
const xh = Math.atan2(xB, xA);
|
|
130
|
-
const yh = Math.atan2(toB, toA);
|
|
131
|
-
const from = xc < GRAY ? yh : xh;
|
|
132
|
-
const to = yc < GRAY ? xh : yh;
|
|
133
|
-
let turn = to - from;
|
|
134
|
-
if (turn > Math.PI)
|
|
135
|
-
turn -= 2 * Math.PI;
|
|
136
|
-
else if (turn < -Math.PI)
|
|
137
|
-
turn += 2 * Math.PI;
|
|
138
135
|
const C = mix(xc, yc, u);
|
|
139
|
-
const h =
|
|
136
|
+
const h = hueAt(Math.atan2(xB, xA), xc, Math.atan2(toB, toA), yc, u);
|
|
140
137
|
return [mix(xL, toL, u) * w, C * Math.cos(h) * w, C * Math.sin(h) * w, w];
|
|
141
138
|
}
|
|
142
139
|
export function color(ofOrOpts, maybe) {
|
|
@@ -149,8 +146,11 @@ export function color(ofOrOpts, maybe) {
|
|
|
149
146
|
(stock?.op === 'sum' && stock.turn === undefined && of.bounds === undefined)) {
|
|
150
147
|
const channel = vec(4, sum());
|
|
151
148
|
channel.kind = `color(sum${space})`;
|
|
152
|
-
|
|
153
|
-
|
|
149
|
+
if (!round)
|
|
150
|
+
return channel;
|
|
151
|
+
const turning = { ...channel, lerp: lerpLch };
|
|
152
|
+
vouch(turning, { op: 'own', axes: 4, folds: 'sum' });
|
|
153
|
+
return turning;
|
|
154
154
|
}
|
|
155
155
|
if (of.kind === 'last') {
|
|
156
156
|
const channel = {
|
|
@@ -159,15 +159,14 @@ export function color(ofOrOpts, maybe) {
|
|
|
159
159
|
lerp: round ? lerpLch : vec(4, sum()).lerp,
|
|
160
160
|
};
|
|
161
161
|
widen(channel, 4);
|
|
162
|
-
|
|
163
|
-
vouch(channel, { op: 'last', axes: 4 });
|
|
162
|
+
vouch(channel, { op: 'last', axes: 4 });
|
|
164
163
|
return channel;
|
|
165
164
|
}
|
|
166
165
|
throw new Error(`color takes sum() to average or last() to replace, not ${of.kind ?? 'a channel of its own'}`);
|
|
167
166
|
}
|
|
168
167
|
/**
|
|
169
|
-
* 0xrrggbb
|
|
170
|
-
* when authoring them, and call it outside the hot path in an `fn` patch.
|
|
168
|
+
* Converts 0xrrggbb to a `color` value. The value is OKLab `[L, a, b]` at full coverage. Convert
|
|
169
|
+
* keyframe stops once when authoring them, and call it outside the hot path in an `fn` patch.
|
|
171
170
|
*
|
|
172
171
|
* @category channel
|
|
173
172
|
*/
|
|
@@ -176,8 +175,9 @@ export function oklab(rgb) {
|
|
|
176
175
|
return [LAB[0], LAB[1], LAB[2], 1];
|
|
177
176
|
}
|
|
178
177
|
/**
|
|
179
|
-
* A `color` pose as 0xrrggbb
|
|
180
|
-
* and laid over `under` in OKLab, then clipped to sRGB per channel. No
|
|
178
|
+
* A `color` pose as 0xrrggbb, laid over `under`. Its color is divided out of its coverage, the
|
|
179
|
+
* coverage capped at 1 and laid over `under` in OKLab, then clipped to sRGB per channel. No
|
|
180
|
+
* coverage gives `under`.
|
|
181
181
|
*
|
|
182
182
|
* @category channel
|
|
183
183
|
*/
|
|
@@ -195,8 +195,8 @@ export function toHex(pose, under = 0x000000) {
|
|
|
195
195
|
return fromLab(mix(LAB[0], L, w), mix(LAB[1], A, w), mix(LAB[2], B, w));
|
|
196
196
|
}
|
|
197
197
|
/**
|
|
198
|
-
* A `color` pose as a CSS `oklab()` color
|
|
199
|
-
* host that lets the browser lay it over what is under it.
|
|
198
|
+
* A `color` pose as a CSS `oklab()` color, its coverage as the alpha. The coverage is capped at 1.
|
|
199
|
+
* For a host that lets the browser lay it over what is under it.
|
|
200
200
|
*
|
|
201
201
|
* @category channel
|
|
202
202
|
*/
|
package/dist/columns.js
CHANGED
|
@@ -22,6 +22,9 @@ export function pullRun(lanes, slots, list, was, since, from, columns, now, vers
|
|
|
22
22
|
const frame = lanes.frameProbes;
|
|
23
23
|
const subjects = lanes.subjects;
|
|
24
24
|
const unlinked = lanes.unlinked;
|
|
25
|
+
const holds = lanes.holds;
|
|
26
|
+
// Nothing in `pullRun` makes a subject owe a voice, so one with nobody owing need not ask.
|
|
27
|
+
const owing = lanes.owed.any();
|
|
25
28
|
const current = since === Number.POSITIVE_INFINITY;
|
|
26
29
|
if (columns !== lanes.queuedFor) {
|
|
27
30
|
flush(lanes);
|
|
@@ -47,14 +50,15 @@ export function pullRun(lanes, slots, list, was, since, from, columns, now, vers
|
|
|
47
50
|
per[o + 0 /* Per.FILLED */] >= busy ||
|
|
48
51
|
per[o + 2 /* Per.IDLE */] !== 0 ||
|
|
49
52
|
per[o + 1 /* Per.SEEN */] < wide ||
|
|
50
|
-
lanes.owes(slot))
|
|
53
|
+
(owing && lanes.owes(slot)))
|
|
51
54
|
break;
|
|
52
55
|
if (!(per[o + 3 /* Per.LANE_PROBE */] > frame ||
|
|
53
56
|
per[o + 4 /* Per.GENERAL_PROBE */] > frame))
|
|
54
57
|
lanes.distinct++;
|
|
55
58
|
per[o + 3 /* Per.LANE_PROBE */] = ++lanes.probes;
|
|
56
59
|
per[o + 5 /* Per.LANE_FILL */] = fills;
|
|
57
|
-
|
|
60
|
+
if (holds)
|
|
61
|
+
subjects[slot] = subject;
|
|
58
62
|
if (slot !== first + (n - start)) {
|
|
59
63
|
if (first >= 0) {
|
|
60
64
|
qSlots[k] = first;
|
|
@@ -73,7 +77,7 @@ export function pullRun(lanes, slots, list, was, since, from, columns, now, vers
|
|
|
73
77
|
k++;
|
|
74
78
|
}
|
|
75
79
|
lanes.queued = k;
|
|
76
|
-
if (n > from)
|
|
80
|
+
if (n > from && holds)
|
|
77
81
|
lanes.holding = true;
|
|
78
82
|
return n;
|
|
79
83
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Mixer } from './mixer.js';
|
|
2
|
+
import type { Subject } from './subject.js';
|
|
3
|
+
import { type Voice } from './voice.js';
|
|
4
|
+
/**
|
|
5
|
+
* One live voice's delta for one subject this frame, through its record for the subject, or null
|
|
6
|
+
* when it does not reach. Its weight is left in `w`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function contribution<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, subject: I, now: number, held: Subject<unknown>): Record<string, unknown> | null;
|
|
9
|
+
/** Reads a keys voice's stops at `held.phase` into the subject's delta, through the voice's scratch. */
|
|
10
|
+
export declare function keyed<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, subject: I, held: Subject<unknown>): Record<string, unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* Runs `step` once per whole interval between where this subject last stopped and now, on a grid
|
|
13
|
+
* counted from when its delay ran out, and leaves the remainder for the next sample. Counting
|
|
14
|
+
* rather than adding keeps the grid where it is however many samples it is reached through.
|
|
15
|
+
*/
|
|
16
|
+
export declare function tick<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, subject: I, held: Subject<unknown>, tick: number, to: number): void;
|
|
17
|
+
/**
|
|
18
|
+
* Stop 0 for a retargeting voice: the subject's pose in the frame before this voice contributes.
|
|
19
|
+
* With no such frame on record — a voice cued before the subject was ever probed, or a host that
|
|
20
|
+
* samples into its own object — it is this frame's pose with every other voice folded in.
|
|
21
|
+
*/
|
|
22
|
+
export declare function baseFor<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, subject: I): Record<string, unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* How fast each numeric channel this voice writes was moving, from the subject's last two probed
|
|
25
|
+
* poses, in units per ms. Undefined with fewer than two on record, which starts the voice at rest.
|
|
26
|
+
*/
|
|
27
|
+
export declare function slopeFor<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, subject: I): Record<string, unknown> | undefined;
|
|
28
|
+
export declare function isRest<I, O>(this: Mixer<I, O>, delta: Record<string, unknown>): boolean;
|
|
29
|
+
/** `contribution`, or for a dry fold a subject already probed this frame, without advancing it. */
|
|
30
|
+
export declare function read<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, subject: I, now: number, dry: boolean, held: Subject<unknown>): Record<string, unknown> | null;
|