@msb235/blits 0.15.1 → 0.16.1
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 +184 -0
- package/README.md +1 -1
- package/dist/ahead.js +11 -13
- package/dist/chain.js +2 -3
- package/dist/clock.d.ts +11 -1
- package/dist/clock.js +28 -9
- package/dist/color.d.ts +36 -14
- package/dist/color.js +186 -58
- package/dist/columns.d.ts +1 -11
- package/dist/columns.js +1 -6
- package/dist/contribution.js +11 -4
- package/dist/crowd.d.ts +0 -6
- package/dist/crowd.js +0 -11
- package/dist/cue.js +19 -7
- package/dist/due.d.ts +18 -0
- package/dist/due.js +101 -2
- package/dist/everyone.d.ts +17 -6
- package/dist/everyone.js +17 -8
- package/dist/fade.d.ts +22 -1
- package/dist/fade.js +81 -12
- package/dist/fill.js +2 -1
- package/dist/fit.js +8 -0
- package/dist/fold.js +4 -7
- package/dist/gone.js +1 -0
- package/dist/handle.d.ts +1 -1
- package/dist/handle.js +3 -1
- package/dist/held.d.ts +2 -1
- package/dist/held.js +17 -10
- package/dist/hosts.d.ts +7 -0
- package/dist/hosts.js +23 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lane.d.ts +2 -0
- package/dist/lane.js +2 -0
- package/dist/lanes.d.ts +26 -1
- package/dist/lanes.js +9 -1
- package/dist/lch.d.ts +23 -0
- package/dist/lch.js +126 -0
- package/dist/meet.js +9 -0
- package/dist/mixer.d.ts +6 -1
- package/dist/mixer.js +5 -0
- package/dist/motion.js +6 -6
- package/dist/motions.d.ts +4 -1
- package/dist/motions.js +16 -2
- package/dist/move.js +311 -79
- package/dist/origin.d.ts +2 -0
- package/dist/origin.js +4 -0
- package/dist/owner.d.ts +7 -2
- package/dist/owner.js +17 -5
- package/dist/paging.d.ts +5 -1
- package/dist/paging.js +13 -3
- package/dist/patch.js +24 -4
- package/dist/place.js +67 -31
- package/dist/project.d.ts +5 -2
- package/dist/project.js +9 -11
- package/dist/pull.d.ts +11 -0
- package/dist/pull.js +10 -6
- package/dist/qualify.js +7 -2
- package/dist/rests.js +9 -1
- package/dist/revive.d.ts +11 -1
- package/dist/revive.js +7 -0
- package/dist/roles.js +6 -5
- package/dist/roster.d.ts +6 -0
- package/dist/roster.js +8 -1
- package/dist/rows.js +4 -1
- package/dist/sample.js +2 -1
- package/dist/seat.d.ts +5 -1
- package/dist/seat.js +5 -1
- package/dist/seek.js +6 -16
- package/dist/shared.d.ts +1 -1
- package/dist/shared.js +1 -1
- package/dist/spans.d.ts +13 -4
- package/dist/spans.js +125 -32
- package/dist/touch.js +1 -2
- package/dist/trace.js +7 -2
- package/dist/turns.js +2 -1
- package/dist/types/transport.d.ts +2 -1
- package/dist/types/voice.d.ts +3 -2
- package/dist/voice.d.ts +59 -2
- package/dist/voice.js +76 -2
- package/dist/weigh.js +1 -1
- package/docs/schema.html +38 -12
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,190 @@ This package follows [semver](https://semver.org). Below 1.0.0, a breaking chang
|
|
|
4
4
|
version and everything else the patch. Each release lists its changes as **Breaking**, **Added** and
|
|
5
5
|
**Fixed**, and the release workflow refuses a tag with no section here.
|
|
6
6
|
|
|
7
|
+
## 0.16.1
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- A child anchored to a sibling under an owner at rate 0 plays where its anchor puts it when the
|
|
12
|
+
owner is sought forward past both. Its anchor's time went through mix time on a clock standing
|
|
13
|
+
still, which maps every time it has passed to the seek's moment, so the child was placed at the
|
|
14
|
+
time sought plus its offset and never played.
|
|
15
|
+
- `inert` reads false while a motion voice has a subject it met inside its `stagger` and has not
|
|
16
|
+
read since, which moves once it is probed. It read true, so a host that stops on `inert` stopped
|
|
17
|
+
a subject that had yet to start.
|
|
18
|
+
- A span's child whose cue a seek back plays again waits for the span's fit, as it did when first
|
|
19
|
+
cued, so the span lays it out as before. It started at once wherever its span's clock had passed
|
|
20
|
+
the start the fit first gave it: the fit then took it for ended, so it skipped nothing else, or,
|
|
21
|
+
in a span running back, the child ran back to its start and left.
|
|
22
|
+
- A child its owner's seek put back before its start stays where it was through a mix sought back to
|
|
23
|
+
after that seek: a later fit keeps it in its place, and an anchor does not place it again. The
|
|
24
|
+
seek took it for one still to start, so a span laid it out afresh, and a child anchored to a
|
|
25
|
+
sibling's end was placed again from that end, and played on as if its owner had not been sought.
|
|
26
|
+
- A voice cued while the mix is paused, its `start` a host time still ahead, waits for that time
|
|
27
|
+
again when a seek back plays its cue again. It started at once, at the paused mix time, since
|
|
28
|
+
the voice was taken for one cued while the mix slept and its start was moved to the next sync.
|
|
29
|
+
- A span whose budget runs out between two frames fits again from that moment, in turn with its
|
|
30
|
+
siblings' starts and ends: a child it places at a start already passed starts in that frame, and
|
|
31
|
+
one queued after it starts where it lapsed at any frame rate. The span lapsed only after the
|
|
32
|
+
frame had started its siblings, so a sibling whose old start the frame passed kept it, and one
|
|
33
|
+
placed in the past waited a frame to start.
|
|
34
|
+
- An owner running back holds a child placed where its clock stands unplayed, whether or not a
|
|
35
|
+
frame lands there. An owner cued backward with a child at 0 started that child, ended it, and
|
|
36
|
+
left with it only when a frame fell exactly on the owner's start; otherwise both waited for good.
|
|
37
|
+
- A read ahead that throws partway, on a call the tape holds that it cannot play, puts the tape
|
|
38
|
+
back. It left the live tape moved past the call, so a later seek restored the wrong state.
|
|
39
|
+
- Under `history`, a voice faded out of one subject is let go when history lets it go. The mix
|
|
40
|
+
held every such voice for good, and each `drop` walked them all.
|
|
41
|
+
- What `prepare` loads is let go once `history.ms` of mix time passes without a seek or read
|
|
42
|
+
taking it. Until one did, the mix kept every record paged since, for good.
|
|
43
|
+
- `trace` of a voice sought past its end, with a `fade.out`, follows the fade from the voice's
|
|
44
|
+
start, where the mix runs it. It called the run exact and read 0 throughout.
|
|
45
|
+
- `weightOf` with lanes on reports the weight a subject was given when its voice moved onto a lane
|
|
46
|
+
after the subject's probe that frame. It reported 0.
|
|
47
|
+
- A `pull` right after two or more cues folds the new voices in voice order, as a probe does. It
|
|
48
|
+
folded them newest first, which on a `mul` or `sum` channel could differ in the last bit.
|
|
49
|
+
- An owner's fade in counts from when the owner started, under an owner turned back or slowed.
|
|
50
|
+
It was worked out again each frame from where the outer owner's clock would next reach the
|
|
51
|
+
inner owner's start, so a clip under an inner owner with a fade in vanished when the outer
|
|
52
|
+
owner turned back, and slowing the outer owner jumped the fade to its end.
|
|
53
|
+
- A fade set for now or earlier, on a voice whose owner runs back, begins then. It was put off to
|
|
54
|
+
when the owner's clock would come back to the voice's start, playing at full weight until then.
|
|
55
|
+
- A fade in stands still while a fade out runs, and climbs on from there after `rise`, rather than
|
|
56
|
+
jumping to where its clock had reached. A subject's own fade out stops its fade in climbing too,
|
|
57
|
+
as the voice's does; before, the two multiplied into a rise.
|
|
58
|
+
- A span child with `faster` or `slower` at `Infinity` is retimed to fill its span. It got a rate
|
|
59
|
+
of Infinity, jumping to its end, or 0, and was skipped as never fitting.
|
|
60
|
+
- A `from: 'current'` voice whose stop lists fewer axes than its `vec` channel reads the missing
|
|
61
|
+
axes as the lerp does. They read NaN.
|
|
62
|
+
- `spring` and `glide` throw for an infinite parameter. A glide with an infinite `ms` or
|
|
63
|
+
`stiffness` read NaN, and a spring with infinite `damping` or `mass` jumped to its target.
|
|
64
|
+
- A role member at weight 0 holds its role's place whatever its patch's form, and a band switched
|
|
65
|
+
off by a frame at weight 0 stays off when the weight comes back between `off` and `on`. A `keys`
|
|
66
|
+
member at weight 0 was read and so held the role's place; any other was not, so its role folded
|
|
67
|
+
at the next member's place, which on a `last` channel changed which value won, and the role's
|
|
68
|
+
band, along with every band in a mix with a role in it, survived the frame at 0.
|
|
69
|
+
- A frame with span children in it costs less than before this release's span-order fixes, which
|
|
70
|
+
had made it about 5% dearer: a child's visit reads its owners' clocks once, and the voices
|
|
71
|
+
visited every frame, which include every voice an owner holds, are kept in a list of their own
|
|
72
|
+
rather than sifted through the due queue's heap and sorted each frame. The new `spans` bench row,
|
|
73
|
+
ten staggered clips cued under one owner every four frames, reads 5.0% faster than with the
|
|
74
|
+
fixes (0.141 to 0.134 ms a frame) and 3.4% faster than before them (0.179 to 0.173 on another
|
|
75
|
+
node), 7 rounds each, U 7.
|
|
76
|
+
- A voice an owner holds, first read while the owner runs back, shows at once instead of waiting
|
|
77
|
+
on its fade in. The fade in counted from where the owner's clock, running back, would next reach
|
|
78
|
+
the voice's start, a time still to come, so the voice read nothing until then.
|
|
79
|
+
- An owner sought forward passes the span children it crosses as played straight through,
|
|
80
|
+
whatever its rate: they start and end in order, and their span fits from each end. Sought ahead
|
|
81
|
+
while turned back, it started them in the order its clock running back put their starts, last
|
|
82
|
+
first, and ended none; turning forward later ended them all at once, out of order, and a span
|
|
83
|
+
holding spans left in a later frame at a time still to come, so a mix sought back left it
|
|
84
|
+
fading and its clips silent. A timeline's reel jumped ahead in reverse played its scenes slowed
|
|
85
|
+
and overlapping.
|
|
86
|
+
- A span child kept quiet at its start, its owner having run back to it, comes back and ends in
|
|
87
|
+
turn when a seek of the owner takes it past its end, and its span fits from that end. It stayed
|
|
88
|
+
quiet, so the children playing past it kept the rate they had before its end.
|
|
89
|
+
- Under `history`, an owner another owner holds no longer leaves once none of its children plays:
|
|
90
|
+
it stays with its own owner, quiet, so turning the outer owner back brings back a clip under an
|
|
91
|
+
owner inside it, as it does a direct child.
|
|
92
|
+
- A span an owner ran back over keeps the layout it made going forward. Before, each child it ran
|
|
93
|
+
back to the start of fitted the span again from there, and so did a seek back into it, counting
|
|
94
|
+
the children waiting for the clock to come back as playing: the ones still to start moved
|
|
95
|
+
earlier, and the playing ones changed speed.
|
|
96
|
+
- A span lays out its children the same at any frame rate. When a child ended between two frames,
|
|
97
|
+
its span fitted again from that moment, and a sibling whose start had passed by then, but which
|
|
98
|
+
no frame had started yet, was placed again from there at a new start and rate: two children of a
|
|
99
|
+
`stagger` span read 420 stepped every 10 ms and 389.47 every 25 ms.
|
|
100
|
+
- A voice under an owner whose rate ramps through 0 (from forward to back) ends where its passes
|
|
101
|
+
run out while the owner still runs forward. The time was taken as never, so it ended at the
|
|
102
|
+
frame that noticed, and a span holding it fitted again from there, its layout following the
|
|
103
|
+
frame rate.
|
|
104
|
+
- A placement whose names make a loop is taken where no mark in it waits on itself: a cue whose
|
|
105
|
+
`out` is its follow's `start`, the follow starting off the cue's `coast`, was refused as waiting
|
|
106
|
+
on itself, since the check followed every name whatever mark it asked for. A voice's `start`,
|
|
107
|
+
`in`, `coast` and the marks placed inside it wait only on what places its start; its `out` and
|
|
108
|
+
`end` on that and what places its out.
|
|
109
|
+
- A placement that waits on itself through a query by tag or by channel is refused at `cue`, as
|
|
110
|
+
one through names is: a voice starting after the one tagged `b`, cued beside one tagged `b`
|
|
111
|
+
starting after the one tagged `a`, was taken. A query is followed to the voices it can pick at
|
|
112
|
+
the cue, the voice being cued among them.
|
|
113
|
+
- A voice no owner holds, placed by a timestamp in its anchor, stays where it was placed through a
|
|
114
|
+
seek back. Each placing read the timestamp against the mix's offset at that moment, which a seek
|
|
115
|
+
moves, so after `seek(1000)` from 2100 an owner anchored to start at 2000 had started at 900, and
|
|
116
|
+
one anchored to end at 4000 left at 0. The timestamp is now read against the offset in force when
|
|
117
|
+
the voice was cued, as a plain `start` is.
|
|
118
|
+
- Under `history`, a span an owner holds no longer leaves once its budget is out and none of its
|
|
119
|
+
children plays: it stays with its owner, quiet, so turning the owner back brings back a clip
|
|
120
|
+
under a span, or under a span in a span, as it does one under an owner.
|
|
121
|
+
- A child cued into a span an owner ran back over queues after the children it holds. The span
|
|
122
|
+
was fitted again at the cue, counting the children waiting for the clock to come back as
|
|
123
|
+
playing, so the new one started beside them. No fit, from a cue, an arc, a sibling leaving or a
|
|
124
|
+
seek, moves a span run back over until the clock passes it again.
|
|
125
|
+
- A child whose rate a fit changed reads, run back over by an owner, what it read going forward. Its
|
|
126
|
+
clock read the new rate all the way back past where the fit changed it; it now runs back on the
|
|
127
|
+
clock it had before, and forward again the fit changes it at the same place.
|
|
128
|
+
- An owner sought past a span's child fits the rest of the span from where that child ended. The
|
|
129
|
+
owner's clock now put the end before the mix began, where a span read its own clock as 0, so the
|
|
130
|
+
children still to come were laid out from the span's start: a timeline's reel jumped into its
|
|
131
|
+
fifth sequence started the third scene beside the second.
|
|
132
|
+
- A span whose children end in one frame fits from each end in the order they came. They were
|
|
133
|
+
taken in cue order, so an end the frame noticed first could be one that a fit from an earlier
|
|
134
|
+
end would have moved, and two children of a `stagger` span read 509.5 stepped every 50 ms where
|
|
135
|
+
1 ms steps read 525.3.
|
|
136
|
+
- A child a fit skipped reads, once its owner is sought or run back before the skip, what it read
|
|
137
|
+
going forward. One skipped while playing kept its jump to its end and read on from there, and
|
|
138
|
+
one skipped before it started, placed at its end at its start, played its passes backward from
|
|
139
|
+
its start.
|
|
140
|
+
- A span child its owner ran or was sought back over takes the change a fit made to it again as
|
|
141
|
+
the owner's clock comes forward to it, as the layout made going forward stands. The span was
|
|
142
|
+
fitted again there instead, with the children it had skipped counted as still playing or left
|
|
143
|
+
out, so the ones it had skipped together with them played on, slowed, beside them.
|
|
144
|
+
- An owner sought past a span lays the span out in that frame as played straight through. Its
|
|
145
|
+
children that started and ended in the frame were taken in cue order once their span had started,
|
|
146
|
+
each started and ended in one step, so a fit from one end missed the children it should have
|
|
147
|
+
moved.
|
|
148
|
+
- A span its owner was sought back before keeps the layout it made going forward, as one run
|
|
149
|
+
back over does. A child's end there fitted it again with the children ahead, left quiet by the
|
|
150
|
+
seek, counted as gone, so the playing ones slowed to fill the span.
|
|
151
|
+
- A mix sought back into a span plays on as it stood at that moment. A seek fitted every span
|
|
152
|
+
again from the moment sought, which a span played straight through is not, so its children's
|
|
153
|
+
rates followed where the seek landed. A span's end and `result` are now kept with its history and
|
|
154
|
+
put back by the seek.
|
|
155
|
+
|
|
156
|
+
## 0.16.0
|
|
157
|
+
|
|
158
|
+
### Added
|
|
159
|
+
|
|
160
|
+
- `ink()`, a color channel for colors that stand for a meaning (a status, a level, a team), beside
|
|
161
|
+
`color()` for colors as the real world shows them. It takes the same `oklab()` values. It travels
|
|
162
|
+
round the hue the short way, and overlapping voices blend round the hue too: the pose holds
|
|
163
|
+
`[Σw·L, Σw·a, Σw·b, Σw·C, Σw]` and shows the hue of `Σw·(a, b)` at the average chroma, so red and
|
|
164
|
+
blue at equal weight show a vivid purple rather than the grayed one `color()` shows. Near-opposite
|
|
165
|
+
hues swing round the wheel as their weights cross. `ink(last())` replaces, traveling round the
|
|
166
|
+
hue, and holds four numbers. `toHex` and `css` read a pose of either length. Both run on lanes.
|
|
167
|
+
|
|
168
|
+
### Changed
|
|
169
|
+
|
|
170
|
+
- A `tween`, `spring` or `glide` on an `ink`, or on the deprecated `color({ lerp: 'oklch' })`,
|
|
171
|
+
goes round the hue rather than straight across each OKLab axis through gray. A tween reads as the
|
|
172
|
+
channel's lerp along its easing; a spring and a glide are solved in lightness, chroma and hue
|
|
173
|
+
with coverage alongside, so velocity carries through a retarget and the path bends rather than
|
|
174
|
+
starting over. What the patch takes and reports stays premultiplied OKLab, four numbers. A glide
|
|
175
|
+
with `bounds` on such a channel is refused at `cue`. Lanes read it as the general path does, to
|
|
176
|
+
the bit; such a voice on one subject no longer joins a crowd. `color()` is unchanged.
|
|
177
|
+
|
|
178
|
+
- Under `history`, turning an owner back (a rate below 0) brings back the children that already
|
|
179
|
+
left, so playback reverses completely. A child an owner holds no longer leaves when its passes
|
|
180
|
+
run out: it fades as before, then stays with its owner, `live` and showing nothing, until the
|
|
181
|
+
owner leaves, and comes back, climbing over its `fade.out`, once its clock is back in its
|
|
182
|
+
passes. Its `done` now resolves when its owner leaves rather than at its own end. The owner
|
|
183
|
+
leaves when it did before, and without `history` nothing changes.
|
|
184
|
+
|
|
185
|
+
### Deprecated
|
|
186
|
+
|
|
187
|
+
- `color({ lerp })`: `lerp: 'oklch'` is `ink()`, which also blends overlapping voices round the
|
|
188
|
+
hue, and `lerp: 'oklab'` is `color()`. It keeps its old behavior for this release and warns once.
|
|
189
|
+
The playground loads compositions saved with it.
|
|
190
|
+
|
|
7
191
|
## 0.15.1
|
|
8
192
|
|
|
9
193
|
### Added
|
package/README.md
CHANGED
|
@@ -151,7 +151,7 @@ do yet.
|
|
|
151
151
|
|
|
152
152
|
## Status
|
|
153
153
|
|
|
154
|
-
v0.
|
|
154
|
+
v0.16.1, with five consumers. magicsmoke runs every fault on it, wod its wheel, tricks and
|
|
155
155
|
transitions, weasel its animator's tweens, sherpa its seams, and
|
|
156
156
|
[klieg](https://github.com/orochi235/klieg) composes all three of its systems — letter motion,
|
|
157
157
|
part effects, and the environment a sign is lit by — on a mix each.
|
package/dist/ahead.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ownBlends } from './blend.js';
|
|
2
2
|
import { headOf } from './chain.js';
|
|
3
|
-
import { open, sighted, weightAt } from './everyone.js';
|
|
4
3
|
import { copyHeld, unread } from './history.js';
|
|
5
4
|
import { markOf, voiceMarks } from './marks.js';
|
|
6
5
|
import { Mixer } from './mixer.js';
|
|
@@ -21,13 +20,12 @@ import { unreached } from './unreached.js';
|
|
|
21
20
|
export function playAhead(transport, c, copies, t, earlier) {
|
|
22
21
|
const tape = transport.tape;
|
|
23
22
|
const depth = tape?.undoDepth() ?? 0;
|
|
24
|
-
let played = false;
|
|
25
23
|
try {
|
|
26
24
|
for (;;) {
|
|
27
25
|
const e = nextEvent(tape, c, t);
|
|
28
26
|
if (!(e < t))
|
|
29
27
|
break;
|
|
30
|
-
|
|
28
|
+
playTo(transport, c, copies, e);
|
|
31
29
|
if (!carries(c))
|
|
32
30
|
continue;
|
|
33
31
|
// Placed now, as the next move would place them, while a target that has just left is here.
|
|
@@ -39,6 +37,7 @@ export function playAhead(transport, c, copies, t, earlier) {
|
|
|
39
37
|
const on = new Mixer(copy.kit, { ...copy.opts, transport: next }, null);
|
|
40
38
|
on.slot = copy.slot;
|
|
41
39
|
on.projecting = true;
|
|
40
|
+
on.share = copy.share;
|
|
42
41
|
copyAhead(copy, on);
|
|
43
42
|
const stages = earlier.get(mix);
|
|
44
43
|
if (stages === undefined)
|
|
@@ -49,11 +48,12 @@ export function playAhead(transport, c, copies, t, earlier) {
|
|
|
49
48
|
}
|
|
50
49
|
c = next;
|
|
51
50
|
}
|
|
52
|
-
|
|
51
|
+
playTo(transport, c, copies, t);
|
|
53
52
|
}
|
|
54
53
|
finally {
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
// A call that throws partway has moved the tape already, so this asks the tape, not `playTo`.
|
|
55
|
+
if (tape !== undefined && tape.undoDepth() !== depth)
|
|
56
|
+
tape.goto(depth);
|
|
57
57
|
}
|
|
58
58
|
return c;
|
|
59
59
|
}
|
|
@@ -108,14 +108,13 @@ function nextEvent(tape, c, t) {
|
|
|
108
108
|
}
|
|
109
109
|
/**
|
|
110
110
|
* Makes the calls the tape holds up to mix time `to` on a read ahead's copies and moves them
|
|
111
|
-
* there.
|
|
111
|
+
* there.
|
|
112
112
|
*/
|
|
113
113
|
function playTo(transport, c, copies, to) {
|
|
114
114
|
const tape = transport.tape;
|
|
115
115
|
const due = (at) => (c.pace === null ? at : c.pace.reading(at)) <= to;
|
|
116
116
|
const next = tape?.timestampAt(tape.undoDepth());
|
|
117
117
|
c.u = hostAhead(c, to);
|
|
118
|
-
let played = false;
|
|
119
118
|
if (next !== undefined && due(next)) {
|
|
120
119
|
// A call may write what a copy shares with the voice it was copied from.
|
|
121
120
|
for (const copy of c.members)
|
|
@@ -125,7 +124,6 @@ function playTo(transport, c, copies, to) {
|
|
|
125
124
|
if (v.parted !== null)
|
|
126
125
|
v.parted = new Map(v.parted);
|
|
127
126
|
}
|
|
128
|
-
played = true;
|
|
129
127
|
const last = replay(transport, due, c, {
|
|
130
128
|
transport: () => c,
|
|
131
129
|
mix: (of) => copies.get(of),
|
|
@@ -136,7 +134,6 @@ function playTo(transport, c, copies, to) {
|
|
|
136
134
|
if (!(c.now >= to))
|
|
137
135
|
for (const copy of c.members)
|
|
138
136
|
move(copy, to);
|
|
139
|
-
return played;
|
|
140
137
|
}
|
|
141
138
|
/** A transport for a read ahead's copies to go on from where those on `c` stand. */
|
|
142
139
|
function restage(c) {
|
|
@@ -196,11 +193,12 @@ export function recordOf(mix, voice, subject) {
|
|
|
196
193
|
// the subject for the caller to copy from.
|
|
197
194
|
if (voice.sharing) {
|
|
198
195
|
const slot = headOf(mix, subject)?.slot ?? -1;
|
|
199
|
-
|
|
196
|
+
const share = mix.share;
|
|
197
|
+
if (!share.sighted(voice, slot))
|
|
200
198
|
return undefined;
|
|
201
199
|
const all = voice.everyone;
|
|
202
|
-
open(voice, all, slot);
|
|
203
|
-
all.weight = weightAt(voice, slot);
|
|
200
|
+
share.open(voice, all, slot);
|
|
201
|
+
all.weight = share.weightAt(voice, slot);
|
|
204
202
|
return all;
|
|
205
203
|
}
|
|
206
204
|
const held = voice.subjects.get(subject);
|
package/dist/chain.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { everyoneOf, sight } from './everyone.js';
|
|
2
1
|
import { record } from './record.js';
|
|
3
2
|
/** The first record of a subject no live voice reaches, so a probe of it still makes one lookup. */
|
|
4
3
|
function stub() {
|
|
@@ -98,10 +97,10 @@ export function linkable(voice, subject, slot, guess = null) {
|
|
|
98
97
|
if (state === 'done' || (state === 'pending' && !voice.freezesBefore))
|
|
99
98
|
return null;
|
|
100
99
|
// A voice sharing one record is in no chain: a fold takes it from `sharers` at its place.
|
|
101
|
-
if (voice.sharing && everyoneOf(this, voice) !== null) {
|
|
100
|
+
if (voice.sharing && this.share.everyoneOf(this, voice) !== null) {
|
|
102
101
|
// A projection numbers no subject, and keeps nothing by subject.
|
|
103
102
|
if (slot >= 0)
|
|
104
|
-
sight(voice, slot, this.lanes.cap);
|
|
103
|
+
this.share.sight(voice, slot, this.lanes.cap);
|
|
105
104
|
return null;
|
|
106
105
|
}
|
|
107
106
|
const held = this.held(voice, subject, slot, guess);
|
package/dist/clock.d.ts
CHANGED
|
@@ -9,6 +9,16 @@ export declare function passesOf(loop: boolean | number | undefined): number;
|
|
|
9
9
|
export declare function phaseAt(elapsed: number, duration: number, passes: number): number;
|
|
10
10
|
/** The pass `elapsed` voice ms falls in, held at the last once they are done. */
|
|
11
11
|
export declare function passAt(elapsed: number, duration: number, passes: number): number;
|
|
12
|
+
/**
|
|
13
|
+
* A fade in from `since` over `fadeIn` at mix time `now`, 0..1. It stands still where a fade out
|
|
14
|
+
* began, or the two ramps multiply into a rise, from `stop` on, and through `stalls`, pairs of mix
|
|
15
|
+
* times.
|
|
16
|
+
*/
|
|
17
|
+
export declare function fadeInAt(fadeIn: number, out: {
|
|
18
|
+
at: number;
|
|
19
|
+
over: number;
|
|
20
|
+
rest: boolean;
|
|
21
|
+
} | null, ease: Curve | undefined, now: number, since: number, stalls: readonly number[] | null, stop?: number): number;
|
|
12
22
|
/**
|
|
13
23
|
* A voice's own fade this frame, 0..1: in from `since` over `fadeIn`, out along its ramp, and back
|
|
14
24
|
* up the same curve where a fade out was turned around.
|
|
@@ -21,7 +31,7 @@ export declare function envelope(fadeIn: number, out: {
|
|
|
21
31
|
from: number;
|
|
22
32
|
at: number;
|
|
23
33
|
over: number;
|
|
24
|
-
} | null): number;
|
|
34
|
+
} | null, stalls?: readonly number[] | null): number;
|
|
25
35
|
/**
|
|
26
36
|
* A subject's voice time `raw` once the voice's freezes apply: 0 before it starts if it freezes
|
|
27
37
|
* before, else NaN, where it shows nothing; `span` once its passes end if it freezes after. A `raw`
|
package/dist/clock.js
CHANGED
|
@@ -21,19 +21,36 @@ export function passAt(elapsed, duration, passes) {
|
|
|
21
21
|
return 0;
|
|
22
22
|
return over(elapsed, duration, passes) ? passes - 1 : Math.floor(elapsed / duration);
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* A fade in from `since` over `fadeIn` at mix time `now`, 0..1. It stands still where a fade out
|
|
26
|
+
* began, or the two ramps multiply into a rise, from `stop` on, and through `stalls`, pairs of mix
|
|
27
|
+
* times.
|
|
28
|
+
*/
|
|
29
|
+
export function fadeInAt(fadeIn, out, ease, now, since, stalls, stop = Number.POSITIVE_INFINITY) {
|
|
30
|
+
let end = out && !out.rest && out.at < now ? out.at : now;
|
|
31
|
+
if (stop < end)
|
|
32
|
+
end = stop;
|
|
33
|
+
let climbed = end - since;
|
|
34
|
+
if (stalls !== null)
|
|
35
|
+
for (let i = 0; i < stalls.length; i += 2) {
|
|
36
|
+
const a = Math.max(stalls[i], since);
|
|
37
|
+
const b = Math.min(stalls[i + 1], end);
|
|
38
|
+
if (b > a)
|
|
39
|
+
climbed -= b - a;
|
|
40
|
+
}
|
|
41
|
+
const u = climbed / fadeIn;
|
|
42
|
+
if (u >= 1)
|
|
43
|
+
return 1;
|
|
44
|
+
return ease ? ease(Math.max(0, u)) : Math.max(0, u);
|
|
45
|
+
}
|
|
24
46
|
/**
|
|
25
47
|
* A voice's own fade this frame, 0..1: in from `since` over `fadeIn`, out along its ramp, and back
|
|
26
48
|
* up the same curve where a fade out was turned around.
|
|
27
49
|
*/
|
|
28
|
-
export function envelope(fadeIn, out, ease, reduced, now, since, back = null) {
|
|
50
|
+
export function envelope(fadeIn, out, ease, reduced, now, since, back = null, stalls = null) {
|
|
29
51
|
let w = 1;
|
|
30
|
-
if (fadeIn > 0 && !reduced)
|
|
31
|
-
|
|
32
|
-
const end = out && !out.rest && out.at < now ? out.at : now;
|
|
33
|
-
const u = (end - since) / fadeIn;
|
|
34
|
-
if (u < 1)
|
|
35
|
-
w *= ease ? ease(Math.max(0, u)) : Math.max(0, u);
|
|
36
|
-
}
|
|
52
|
+
if (fadeIn > 0 && !reduced)
|
|
53
|
+
w *= fadeInAt(fadeIn, out, ease, now, since, stalls);
|
|
37
54
|
if (back && !reduced) {
|
|
38
55
|
const u = back.from + (now - back.at) / back.over;
|
|
39
56
|
if (u < 1)
|
|
@@ -114,7 +131,9 @@ export function timeWith(c, elapsed) {
|
|
|
114
131
|
return r.from > 0 ? c.anchorNow + (elapsed - e0) / r.from : c.anchorNow;
|
|
115
132
|
const a = (r.to - r.from) / (2 * r.over);
|
|
116
133
|
const atEnd = e0 + r.from * r.over + a * r.over * r.over;
|
|
117
|
-
|
|
134
|
+
// A ramp that turns the clock back reads furthest where its rate crosses 0, not at its end.
|
|
135
|
+
const top = r.from > 0 && r.to < 0 ? e0 - (r.from * r.from) / (4 * a) : atEnd;
|
|
136
|
+
if (elapsed <= top) {
|
|
118
137
|
const k = e0 - elapsed;
|
|
119
138
|
const dt = Math.abs(a) < 1e-12
|
|
120
139
|
? -k / r.from
|
package/dist/color.d.ts
CHANGED
|
@@ -8,44 +8,66 @@ import type { Channel } from './types.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function mixHex(a: number, b: number, u: number): number;
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* What `color` took before `ink` existed: `lerp: 'oklch'` overlaps straight across OKLab and
|
|
12
|
+
* travels round the hue.
|
|
13
13
|
*
|
|
14
14
|
* @category channel
|
|
15
15
|
*/
|
|
16
16
|
export interface ColorOptions {
|
|
17
|
+
/** @deprecated `'oklch'` is `ink()`, which also blends overlapping voices round the hue; `'oklab'` is `color()`. */
|
|
17
18
|
lerp?: 'oklab' | 'oklch';
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*
|
|
21
|
+
* Whether `channel` travels round the hue, as `ink` does, so a motion patch cued on it moves round
|
|
22
|
+
* the hue too.
|
|
23
|
+
*/
|
|
24
|
+
export declare function roundsHue(channel: Channel<unknown>): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Color as the real world shows it, light, sky, smoke or paint: OKLab `[L, a, b, coverage]`, its
|
|
27
|
+
* merge rule given as `of`. `color()` averages: voices stack as a premultiplied sum, so a pose
|
|
28
|
+
* holds `[Σw·L, Σw·a, Σw·b, Σw]` and runs on lanes; `toHex` divides it out and lays it over what
|
|
29
|
+
* is under it. `color(last())` replaces, the last voice to pass winning, at the coverage it was
|
|
30
|
+
* authored with. It travels between two colors, in a motion or a role's handoff, straight across
|
|
31
|
+
* OKLab, so opposite hues cross through gray. For colors that stand for a meaning, use `ink`.
|
|
26
32
|
*
|
|
27
33
|
* @category channel
|
|
28
34
|
*/
|
|
29
35
|
export declare function color(opts?: ColorOptions): Channel<number[]>;
|
|
30
36
|
export declare function color(of: Channel<number> | Channel<unknown>, opts?: ColorOptions): Channel<number[]>;
|
|
31
37
|
/**
|
|
32
|
-
*
|
|
38
|
+
* Color standing for a meaning, a status, a level or a team, rather than for a physical
|
|
39
|
+
* phenomenon: choose it over `color` when the colors are symbols. People picture the midpoint
|
|
40
|
+
* between red and blue as purple, reached by turning the hue, not as the grayed mix light makes,
|
|
41
|
+
* and `ink` gives them that. It travels round the hue the short way, in a motion, between keys
|
|
42
|
+
* and in a role's handoff, and `ink()` blends overlapping voices round the hue too: each voice
|
|
43
|
+
* sums as `[w·L, w·a, w·b, w·C, w]`, C its chroma, so a pose shows lightness `ΣwL/Σw`, the hue of
|
|
44
|
+
* `Σw·(a, b)`, which a gray voice pulls on not at all, and chroma `ΣwC/Σw`, so two vivid colors
|
|
45
|
+
* stay vivid. Near-opposite hues overlapping swing round the wheel as their weights cross, with
|
|
46
|
+
* no tiebreak, and exactly opposite ones cancel to gray. A patch writes it the `oklab()` values a
|
|
47
|
+
* `color` takes, and `toHex` and `css` read either. `ink(last())` replaces, traveling round the
|
|
48
|
+
* hue, and holds the four numbers it was written, since it never sums.
|
|
49
|
+
*
|
|
50
|
+
* @category channel
|
|
51
|
+
*/
|
|
52
|
+
export declare function ink(of?: Channel<number> | Channel<unknown>): Channel<number[]>;
|
|
53
|
+
/**
|
|
54
|
+
* Converts 0xrrggbb to a `color` or `ink` value. The value is OKLab `[L, a, b]` at full coverage. Convert
|
|
33
55
|
* keyframe stops once when authoring them, and call it outside the hot path in an `fn` patch.
|
|
34
56
|
*
|
|
35
57
|
* @category channel
|
|
36
58
|
*/
|
|
37
59
|
export declare function oklab(rgb: number): number[];
|
|
38
60
|
/**
|
|
39
|
-
* A `color` pose as 0xrrggbb, laid over `under`. Its color is divided out of its
|
|
40
|
-
* coverage capped at 1 and laid over `under` in OKLab, then clipped to sRGB per
|
|
41
|
-
* coverage gives `under`.
|
|
61
|
+
* A `color` or `ink` pose as 0xrrggbb, laid over `under`. Its color is divided out of its
|
|
62
|
+
* coverage, the coverage capped at 1 and laid over `under` in OKLab, then clipped to sRGB per
|
|
63
|
+
* channel. No coverage gives `under`.
|
|
42
64
|
*
|
|
43
65
|
* @category channel
|
|
44
66
|
*/
|
|
45
67
|
export declare function toHex(pose: ArrayLike<number>, under?: number): number;
|
|
46
68
|
/**
|
|
47
|
-
* A `color` pose as a CSS `oklab()` color, its coverage as the alpha. The coverage is
|
|
48
|
-
* For a host that lets the browser lay it over what is under it.
|
|
69
|
+
* A `color` or `ink` pose as a CSS `oklab()` color, its coverage as the alpha. The coverage is
|
|
70
|
+
* capped at 1. For a host that lets the browser lay it over what is under it.
|
|
49
71
|
*
|
|
50
72
|
* @category channel
|
|
51
73
|
*/
|