@altpsyche/maths 0.11.0 → 0.12.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 +25 -0
- package/dist/figure/frames.d.ts +57 -0
- package/dist/figure/frames.js +43 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -360,6 +360,31 @@ marks onto a two-dimensional canvas, which is what a recording needs, because an
|
|
|
360
360
|
one surface. A test holds the two to emitting the same geometry and the same style for every
|
|
361
361
|
mark.
|
|
362
362
|
|
|
363
|
+
## Frames out
|
|
364
|
+
|
|
365
|
+
`framesOf(figure, options)` walks a figure at a fixed step and hands back a frame at a time. A frame
|
|
366
|
+
is its index, its time, its marks and the view those marks are painted through, read together at one
|
|
367
|
+
moment. A consumer that asks for the marks and the view in two calls has two chances to pass different
|
|
368
|
+
times, and a figure whose view moves then paints its marks through the matrix of some other moment:
|
|
369
|
+
the flat demo's view is carried 312 across its own walk, in the units a 1080 by 600 surface counts in.
|
|
370
|
+
|
|
371
|
+
Frames come back one at a time rather than as a list. Ten seconds at sixty frames a second is six
|
|
372
|
+
hundred frames of every mark a figure draws, and a recorder encodes a frame and throws it away.
|
|
373
|
+
`frameTimes` answers the times up front, since a recorder showing a reader how far along it is needs
|
|
374
|
+
the total before it has drawn anything.
|
|
375
|
+
|
|
376
|
+
The step is given as a rate or as a count, and the two are different questions. A recorder knows how
|
|
377
|
+
fast the frames play and needs a step of exactly one over that, or the encoded video drifts from the
|
|
378
|
+
figure's own clock. A strip knows how many pictures fit across a page and wants them spread over the
|
|
379
|
+
whole figure. A walk stops strictly before the duration either way: the frame at the duration of a
|
|
380
|
+
figure that loops is its own first frame, and a recording would show it twice. The rotation strip
|
|
381
|
+
above is a walk of four frames over a six second turn, and it draws the same bytes as the four times
|
|
382
|
+
that were written out by hand before it.
|
|
383
|
+
|
|
384
|
+
Nothing here writes a file. Every frame of both demos is painted through `paintCanvas` and written by
|
|
385
|
+
`svgMarkup` in the suite, which is the whole claim and needs no browser, and what a consumer does with
|
|
386
|
+
a painted frame is the consumer's own.
|
|
387
|
+
|
|
363
388
|
## The way in
|
|
364
389
|
|
|
365
390
|
`pathFromData` reads an SVG `d` attribute as a path, which is the inverse of what the SVG painter
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A figure walked at a fixed step, a frame at a time.
|
|
3
|
+
*
|
|
4
|
+
* A frame is the marks and the view read at one time, handed over together. A
|
|
5
|
+
* consumer that asked for them separately holds two calls it can pass different
|
|
6
|
+
* times, and a figure whose view moves then paints its marks through the matrix
|
|
7
|
+
* of some other moment.
|
|
8
|
+
*
|
|
9
|
+
* Frames come back one at a time rather than as a list. A ten second figure at
|
|
10
|
+
* sixty frames a second is six hundred frames of every mark it draws, and a
|
|
11
|
+
* recorder encodes a frame and throws it away.
|
|
12
|
+
*/
|
|
13
|
+
import { type Figure } from './figure.js';
|
|
14
|
+
import type { Mark } from './mark.js';
|
|
15
|
+
import type { Mat3 } from '../values/mat3.js';
|
|
16
|
+
export interface Frame {
|
|
17
|
+
/** Its place in the walk, counting from nothing. */
|
|
18
|
+
index: number;
|
|
19
|
+
/** The time it was read at, in seconds. */
|
|
20
|
+
seconds: number;
|
|
21
|
+
marks: readonly Mark[];
|
|
22
|
+
/** The matrix a painter needs for these marks, built at this frame's own
|
|
23
|
+
* time. */
|
|
24
|
+
view: Mat3;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* How the walk is stepped, as a rate or as a count.
|
|
28
|
+
*
|
|
29
|
+
* The two are different questions. A recorder knows how fast the frames play and
|
|
30
|
+
* needs a step of exactly one over that, or the encoded video drifts from the
|
|
31
|
+
* figure's own clock. A strip knows how many pictures fit across a page and wants
|
|
32
|
+
* them spread over the whole figure.
|
|
33
|
+
*/
|
|
34
|
+
export type FrameStep = {
|
|
35
|
+
fps: number;
|
|
36
|
+
frames?: never;
|
|
37
|
+
} | {
|
|
38
|
+
frames: number;
|
|
39
|
+
fps?: never;
|
|
40
|
+
};
|
|
41
|
+
export type FramesOptions = FrameStep & {
|
|
42
|
+
/** The surface the view is built for, in whatever units a painter counts in. */
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* The times a walk reads, which a recorder needs before it has drawn anything to
|
|
48
|
+
* say how far along it is.
|
|
49
|
+
*
|
|
50
|
+
* A walk stops strictly before the duration. The frame at the duration of a
|
|
51
|
+
* figure that loops is its own first frame, and a recording would show it twice.
|
|
52
|
+
* A figure with no duration is one frame, since a picture that never moves still
|
|
53
|
+
* has a picture.
|
|
54
|
+
*/
|
|
55
|
+
export declare function frameTimes(figure: Figure, step: FrameStep): number[];
|
|
56
|
+
/** A figure walked at a fixed step, a frame at a time. */
|
|
57
|
+
export declare function framesOf(figure: Figure, options: FramesOptions): Generator<Frame>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A figure walked at a fixed step, a frame at a time.
|
|
3
|
+
*
|
|
4
|
+
* A frame is the marks and the view read at one time, handed over together. A
|
|
5
|
+
* consumer that asked for them separately holds two calls it can pass different
|
|
6
|
+
* times, and a figure whose view moves then paints its marks through the matrix
|
|
7
|
+
* of some other moment.
|
|
8
|
+
*
|
|
9
|
+
* Frames come back one at a time rather than as a list. A ten second figure at
|
|
10
|
+
* sixty frames a second is six hundred frames of every mark it draws, and a
|
|
11
|
+
* recorder encodes a frame and throws it away.
|
|
12
|
+
*/
|
|
13
|
+
import { at, durationOf, viewAt } from './figure.js';
|
|
14
|
+
/**
|
|
15
|
+
* The times a walk reads, which a recorder needs before it has drawn anything to
|
|
16
|
+
* say how far along it is.
|
|
17
|
+
*
|
|
18
|
+
* A walk stops strictly before the duration. The frame at the duration of a
|
|
19
|
+
* figure that loops is its own first frame, and a recording would show it twice.
|
|
20
|
+
* A figure with no duration is one frame, since a picture that never moves still
|
|
21
|
+
* has a picture.
|
|
22
|
+
*/
|
|
23
|
+
export function frameTimes(figure, step) {
|
|
24
|
+
const duration = durationOf(figure);
|
|
25
|
+
const count = step.fps === undefined
|
|
26
|
+
? Math.max(1, Math.round(step.frames))
|
|
27
|
+
: Math.max(1, Math.round(duration * step.fps));
|
|
28
|
+
const gap = step.fps === undefined ? duration / count : 1 / step.fps;
|
|
29
|
+
return Array.from({ length: count }, (_, index) => index * gap);
|
|
30
|
+
}
|
|
31
|
+
/** A figure walked at a fixed step, a frame at a time. */
|
|
32
|
+
export function* framesOf(figure, options) {
|
|
33
|
+
const times = frameTimes(figure, options);
|
|
34
|
+
for (let index = 0; index < times.length; index += 1) {
|
|
35
|
+
const seconds = times[index];
|
|
36
|
+
yield {
|
|
37
|
+
index,
|
|
38
|
+
seconds,
|
|
39
|
+
marks: at(figure, seconds),
|
|
40
|
+
view: viewAt(figure, seconds, options.width, options.height),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -70,6 +70,8 @@ export { lengthOf, pointAlong } from './figure/length.js';
|
|
|
70
70
|
export { trimPath } from './figure/trim.js';
|
|
71
71
|
export { alignPaths, lerpPath } from './figure/morph.js';
|
|
72
72
|
export { at, durationOf, loops, sameMarks, viewAt } from './figure/figure.js';
|
|
73
|
+
export { frameTimes, framesOf } from './figure/frames.js';
|
|
74
|
+
export type { Frame, FrameStep, FramesOptions } from './figure/frames.js';
|
|
73
75
|
export type { Figure, Values } from './figure/figure.js';
|
|
74
76
|
export { pathData, paintSvg, svgElements, svgMarkup } from './paint/svg.js';
|
|
75
77
|
export type { ElementMaker, PaintNode, PaintTarget, SvgElement } from './paint/svg.js';
|
package/dist/index.js
CHANGED
|
@@ -42,6 +42,7 @@ export { lengthOf, pointAlong } from './figure/length.js';
|
|
|
42
42
|
export { trimPath } from './figure/trim.js';
|
|
43
43
|
export { alignPaths, lerpPath } from './figure/morph.js';
|
|
44
44
|
export { at, durationOf, loops, sameMarks, viewAt } from './figure/figure.js';
|
|
45
|
+
export { frameTimes, framesOf } from './figure/frames.js';
|
|
45
46
|
export { pathData, paintSvg, svgElements, svgMarkup } from './paint/svg.js';
|
|
46
47
|
export { paintCanvas } from './paint/canvas.js';
|
|
47
48
|
export { arrow, brace, bracePath, callout, dot } from './figure/annotate.js';
|
package/package.json
CHANGED