pixi-effects 0.28.1 → 0.29.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 +67 -0
- package/README.md +11 -11
- package/ai/chat-template.html +5 -5
- package/ai/tools/check.mjs +18 -3
- package/ai/tools/pixi-effects.mjs +1 -1
- package/ai/tools/render.mjs +14 -9
- package/ai/tools/view.mjs +108 -16
- package/dist/Base-CB1_FPZD.d.cts +60 -0
- package/dist/Base-Ne74ztNl.d.ts +60 -0
- package/dist/Composition-MUKR3FYD.cjs +16 -0
- package/dist/{Composition-NI74UJT3.cjs.map → Composition-MUKR3FYD.cjs.map} +1 -1
- package/dist/Composition-RJGA7KDU.js +7 -0
- package/dist/{Composition-HFEVIYHN.js.map → Composition-RJGA7KDU.js.map} +1 -1
- package/dist/Controller.cjs +73 -45
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.d.cts +16 -22
- package/dist/Controller.d.ts +16 -22
- package/dist/Controller.js +74 -40
- package/dist/Controller.js.map +1 -1
- package/dist/{Movie-CHcM8HNB.d.ts → Movie-C2rZFkrO.d.ts} +227 -119
- package/dist/{Movie-Cx5ozUGb.d.cts → Movie-DdnpLpw1.d.cts} +227 -119
- package/dist/{blendModes-HDOP6R7T.cjs → blendModes-ETMYWATF.cjs} +5 -5
- package/dist/{blendModes-HDOP6R7T.cjs.map → blendModes-ETMYWATF.cjs.map} +1 -1
- package/dist/{blendModes-PAVTW3BO.js → blendModes-RIVZXL5A.js} +4 -4
- package/dist/{blendModes-PAVTW3BO.js.map → blendModes-RIVZXL5A.js.map} +1 -1
- package/dist/{chunk-P4GY3Z4G.cjs → chunk-2DXPTKQZ.cjs} +6 -6
- package/dist/chunk-2DXPTKQZ.cjs.map +1 -0
- package/dist/{chunk-TYWFKCPY.js → chunk-4KB3GUEK.js} +5 -5
- package/dist/chunk-4KB3GUEK.js.map +1 -0
- package/dist/{chunk-WEJAQAFX.js → chunk-A3Q3SDSH.js} +35 -28
- package/dist/chunk-A3Q3SDSH.js.map +1 -0
- package/dist/chunk-CRQFDY7E.js +4182 -0
- package/dist/chunk-CRQFDY7E.js.map +1 -0
- package/dist/chunk-HREBQAY4.cjs +4206 -0
- package/dist/chunk-HREBQAY4.cjs.map +1 -0
- package/dist/{chunk-ZMAD3KJU.cjs → chunk-LYOKH7KE.cjs} +22 -3
- package/dist/chunk-LYOKH7KE.cjs.map +1 -0
- package/dist/{chunk-45QKLD6M.js → chunk-RCVZX2JP.js} +22 -3
- package/dist/chunk-RCVZX2JP.js.map +1 -0
- package/dist/{chunk-SBOVUZZY.cjs → chunk-WHNADXXG.cjs} +121 -114
- package/dist/chunk-WHNADXXG.cjs.map +1 -0
- package/dist/{chunk-AK54FIWM.js → chunk-ZAXYPXKW.js} +17 -6
- package/dist/chunk-ZAXYPXKW.js.map +1 -0
- package/dist/{chunk-MZCDBRTY.cjs → chunk-ZVUO325O.cjs} +34 -23
- package/dist/chunk-ZVUO325O.cjs.map +1 -0
- package/dist/index.cjs +106 -4480
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -60
- package/dist/index.d.ts +15 -60
- package/dist/index.js +6 -4455
- package/dist/index.js.map +1 -1
- package/dist/loader.css +1 -1
- package/dist/{Presenter.cjs → present.cjs} +370 -31
- package/dist/present.cjs.map +1 -0
- package/dist/present.d.cts +278 -0
- package/dist/present.d.ts +278 -0
- package/dist/{Presenter.js → present.js} +358 -32
- package/dist/present.js.map +1 -0
- package/dist/three.cjs +6 -6
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +2 -2
- package/dist/{types-DpK1vwcl.d.ts → types-BzIB65Vk.d.cts} +11 -265
- package/dist/{types-DpK1vwcl.d.cts → types-BzIB65Vk.d.ts} +11 -265
- package/docs/api.md +44 -77
- package/docs/dsl.md +16 -14
- package/llms-full.txt +90 -118
- package/llms.txt +1 -1
- package/package.json +5 -5
- package/skills/pixi-effects/SKILL.md +6 -6
- package/skills/pixi-effects/reference/cheatsheet.md +9 -9
- package/skills/pixi-effects/reference/direction.md +4 -2
- package/skills/pixi-effects/reference/pitfalls.md +7 -6
- package/skills/pixi-effects/reference/recipes.md +4 -4
- package/skills/pixi-effects/template.html +7 -7
- package/dist/Base-C6f0fE8j.d.ts +0 -109
- package/dist/Base-DI1FCGcH.d.cts +0 -109
- package/dist/Composition-HFEVIYHN.js +0 -7
- package/dist/Composition-NI74UJT3.cjs +0 -16
- package/dist/Presenter.cjs.map +0 -1
- package/dist/Presenter.d.cts +0 -122
- package/dist/Presenter.d.ts +0 -122
- package/dist/Presenter.js.map +0 -1
- package/dist/chunk-45QKLD6M.js.map +0 -1
- package/dist/chunk-AK54FIWM.js.map +0 -1
- package/dist/chunk-MZCDBRTY.cjs.map +0 -1
- package/dist/chunk-P4GY3Z4G.cjs.map +0 -1
- package/dist/chunk-SBOVUZZY.cjs.map +0 -1
- package/dist/chunk-TYWFKCPY.js.map +0 -1
- package/dist/chunk-WEJAQAFX.js.map +0 -1
- package/dist/chunk-ZMAD3KJU.cjs.map +0 -1
|
@@ -1,5 +1,204 @@
|
|
|
1
1
|
import { Application } from 'pixi.js';
|
|
2
|
-
import {
|
|
2
|
+
import { Z as Stop, c as AssetSpec, k as CompositionSpec } from './types-BzIB65Vk.cjs';
|
|
3
|
+
|
|
4
|
+
type EaseFn = (p: number) => number;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A timeline that is a pure function of time (spike: see docs/superpowers/specs/2026-10-10-pure-timeline-design.md).
|
|
8
|
+
*
|
|
9
|
+
* For every (target, property) it keeps the segments that write it, ordered by start time. The value at `t`
|
|
10
|
+
* is the value of the last segment that has started, computed from `t` alone; nothing is remembered between
|
|
11
|
+
* two calls except the start values captured when the segment was built. GSAP is the oracle: the rules below
|
|
12
|
+
* were taken from black-box probes of `gsap.timeline` and are checked against it by tests/core/pure/timelineParity.test.ts.
|
|
13
|
+
*/
|
|
14
|
+
interface PureVars {
|
|
15
|
+
duration?: number;
|
|
16
|
+
ease?: string | EaseFn;
|
|
17
|
+
repeat?: number;
|
|
18
|
+
yoyo?: boolean;
|
|
19
|
+
repeatDelay?: number;
|
|
20
|
+
onUpdate?: () => void;
|
|
21
|
+
/** The Pixi plugin's shorthands: `scale`, `anchor`, `rotation` (degrees), `tint`, `autoAlpha` ... */
|
|
22
|
+
pixi?: Record<string, unknown>;
|
|
23
|
+
[prop: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
/** One thing a timeline writes: see `segments()`. */
|
|
26
|
+
interface SegmentInfo {
|
|
27
|
+
target: object;
|
|
28
|
+
/** The property (`'alpha'`, `'scale.x'`, `'fill'`). */
|
|
29
|
+
id: string;
|
|
30
|
+
start: number;
|
|
31
|
+
duration: number;
|
|
32
|
+
repeat: number;
|
|
33
|
+
yoyo: boolean;
|
|
34
|
+
repeatDelay: number;
|
|
35
|
+
kind: 'set' | 'to' | 'from' | 'fromTo';
|
|
36
|
+
}
|
|
37
|
+
/** A marker that only lengthens a timeline (what `gsap.to({}, { duration })` is used for). */
|
|
38
|
+
interface Spacer {
|
|
39
|
+
readonly spacer: true;
|
|
40
|
+
readonly duration: number;
|
|
41
|
+
}
|
|
42
|
+
declare class PureTimeline {
|
|
43
|
+
private readonly defaultEase;
|
|
44
|
+
private readonly channels;
|
|
45
|
+
private readonly channelList;
|
|
46
|
+
private readonly children;
|
|
47
|
+
private spans;
|
|
48
|
+
private now;
|
|
49
|
+
private order;
|
|
50
|
+
private killed;
|
|
51
|
+
private prepared;
|
|
52
|
+
constructor(opts?: {
|
|
53
|
+
paused?: boolean;
|
|
54
|
+
defaults?: {
|
|
55
|
+
ease?: string | EaseFn;
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
/** Adds a child timeline (played with its local time) or a spacer that lengthens this one. */
|
|
59
|
+
add(child: PureTimeline | Spacer, at?: number): this;
|
|
60
|
+
set(target: object, vars: PureVars, at?: number): this;
|
|
61
|
+
to(target: object, vars: PureVars, at?: number): this;
|
|
62
|
+
from(target: object, vars: PureVars, at?: number): this;
|
|
63
|
+
fromTo(target: object, fromVars: PureVars, toVars: PureVars, at?: number): this;
|
|
64
|
+
private build;
|
|
65
|
+
private channel;
|
|
66
|
+
/**
|
|
67
|
+
* A property moved by a function of the caller (a colour in OKLab, a gradient): `to` and `from` say how to get the two ends from
|
|
68
|
+
* the value before the segment, `make` the interpolator between them. The value is only written while the segment is the last
|
|
69
|
+
* one that has started, so nothing is read or kept between two frames.
|
|
70
|
+
*/
|
|
71
|
+
tweenValue<T>(spec: {
|
|
72
|
+
holder: object;
|
|
73
|
+
id: string;
|
|
74
|
+
get(): T;
|
|
75
|
+
set(v: T): void;
|
|
76
|
+
from?: (prev: T) => T;
|
|
77
|
+
to: (start: T, prev: T, base: T) => T;
|
|
78
|
+
make: (a: T, b: T) => (p: number) => T;
|
|
79
|
+
duration: number;
|
|
80
|
+
ease: string | EaseFn;
|
|
81
|
+
at: number;
|
|
82
|
+
repeat?: number;
|
|
83
|
+
yoyo?: boolean;
|
|
84
|
+
repeatDelay?: number;
|
|
85
|
+
}): this;
|
|
86
|
+
/**
|
|
87
|
+
* A write that is undone when time goes back before it: the property is `value` from `at` on, and what it was before otherwise.
|
|
88
|
+
* `holder` and `id` name the property, so a set and the tweens of the same property are one channel; `write` is the way the caller
|
|
89
|
+
* writes it (it may do more than assign: redraw), and runs again whenever this set is what the property shows.
|
|
90
|
+
*/
|
|
91
|
+
setValue<T>(holder: object, id: string, at: number, read: () => T, write: (v: T) => void, value: T): this;
|
|
92
|
+
/** What the timeline will write, for tools and tests: every segment of this timeline and of the ones under it, starts in this timeline's time. */
|
|
93
|
+
segments(offset?: number): SegmentInfo[];
|
|
94
|
+
/** How many timelines are directly under this one. */
|
|
95
|
+
timelines(): number;
|
|
96
|
+
duration(): number;
|
|
97
|
+
time(): number;
|
|
98
|
+
time(value: number): this;
|
|
99
|
+
/** GSAP's name for `time(t)`. */
|
|
100
|
+
seek(t: number): this;
|
|
101
|
+
progress(): number;
|
|
102
|
+
progress(p: number): this;
|
|
103
|
+
kill(): void;
|
|
104
|
+
/**
|
|
105
|
+
* What GSAP ended up with once it had been played to the end and back (what Movie used to do at build), as rules that depend
|
|
106
|
+
* on the segments of a property only:
|
|
107
|
+
* - a `from` / `fromTo` shows its start from the moment it is built, so a `to` that comes first starts at the start of the
|
|
108
|
+
* `from` built last, else at the property's own value;
|
|
109
|
+
* - a `to` (and a `set`) starts where the segment before it ended;
|
|
110
|
+
* - a `from` ends where the segment before it ended, or, with none before, where the property was when it was built;
|
|
111
|
+
* - before the first segment the property shows that segment's start.
|
|
112
|
+
*/
|
|
113
|
+
private prepare;
|
|
114
|
+
/** Every channel of this timeline and of its children reads the property it starts from before any of them writes. */
|
|
115
|
+
private prepareDeep;
|
|
116
|
+
/** How many channels write each (target, property) in this timeline and everything under it. */
|
|
117
|
+
private countChannels;
|
|
118
|
+
private isExclusive;
|
|
119
|
+
private markExclusive;
|
|
120
|
+
private evaluate;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The timeline of the library and the few things around it: a timeline is a pure function of time (a value at a time is computed from the
|
|
125
|
+
* script and the time alone, never from the way the playhead came), see docs/superpowers/specs/2026-10-10-pure-timeline-design.md.
|
|
126
|
+
*/
|
|
127
|
+
type Timeline = PureTimeline;
|
|
128
|
+
|
|
129
|
+
/** One note or chord of a track, as a score reader sees it. */
|
|
130
|
+
interface MusicNote {
|
|
131
|
+
/** Where it starts: beats from the start, and the same moment in seconds (the tempo map applied; swing and humanize are not). */
|
|
132
|
+
beat: number;
|
|
133
|
+
time: number;
|
|
134
|
+
/** How long it is held, in beats and in seconds. */
|
|
135
|
+
duration: number;
|
|
136
|
+
seconds: number;
|
|
137
|
+
/** The bar it starts in (1-based, from `meter`) and its beat inside that bar (1 = the downbeat, 1.5 = the "and" of 1). */
|
|
138
|
+
bar: number;
|
|
139
|
+
beatInBar: number;
|
|
140
|
+
/** The audible MIDI notes (`music.transpose` and the track's `transpose` are in). */
|
|
141
|
+
midi: number[];
|
|
142
|
+
/** What the score called it: `Am7`, `c4`, `[c4 e4 g4]`. */
|
|
143
|
+
name: string;
|
|
144
|
+
/** More than one note at once. */
|
|
145
|
+
chord: boolean;
|
|
146
|
+
/** 0–1 (0.8 normal, 1 accented with `!`, 0.55 soft with `,`). */
|
|
147
|
+
velocity: number;
|
|
148
|
+
}
|
|
149
|
+
interface MusicTrackEvents {
|
|
150
|
+
inst: string;
|
|
151
|
+
/** The track's length in beats and in bars (not a whole number when a bar is short: that is what to look for). */
|
|
152
|
+
beats: number;
|
|
153
|
+
bars: number;
|
|
154
|
+
notes: MusicNote[];
|
|
155
|
+
}
|
|
156
|
+
interface MusicDrumHit {
|
|
157
|
+
beat: number;
|
|
158
|
+
time: number;
|
|
159
|
+
bar: number;
|
|
160
|
+
beatInBar: number;
|
|
161
|
+
velocity: number;
|
|
162
|
+
}
|
|
163
|
+
interface MusicDrumEvents {
|
|
164
|
+
kind: string;
|
|
165
|
+
hits: MusicDrumHit[];
|
|
166
|
+
}
|
|
167
|
+
interface MusicEvents {
|
|
168
|
+
/** The tempo at the start. */
|
|
169
|
+
bpm: number;
|
|
170
|
+
meter: number;
|
|
171
|
+
beats: number;
|
|
172
|
+
bars: number;
|
|
173
|
+
/** The music without its reverb tail. */
|
|
174
|
+
seconds: number;
|
|
175
|
+
tracks: MusicTrackEvents[];
|
|
176
|
+
/** Every drum that is hit, over all sections, with every hit written out. */
|
|
177
|
+
drums: MusicDrumEvents[];
|
|
178
|
+
}
|
|
179
|
+
/** What the `check` tool prints about a music layer: lengths in bars (a short track shows), what starts in each bar, where the drums play. */
|
|
180
|
+
interface MusicSummary {
|
|
181
|
+
bpm: number;
|
|
182
|
+
meter: number;
|
|
183
|
+
/** The score set `meter`; when false 4 is only assumed. */
|
|
184
|
+
meterSet: boolean;
|
|
185
|
+
beats: number;
|
|
186
|
+
bars: number;
|
|
187
|
+
seconds: number;
|
|
188
|
+
tail: number;
|
|
189
|
+
tracks: Array<{
|
|
190
|
+
inst: string;
|
|
191
|
+
beats: number;
|
|
192
|
+
bars: number;
|
|
193
|
+
events: number;
|
|
194
|
+
perBar: string[];
|
|
195
|
+
}>;
|
|
196
|
+
drums: Array<{
|
|
197
|
+
from: number;
|
|
198
|
+
to: number;
|
|
199
|
+
kinds: string[];
|
|
200
|
+
}>;
|
|
201
|
+
}
|
|
3
202
|
|
|
4
203
|
interface AudioInspectOptions {
|
|
5
204
|
/** Width of each loudness window in seconds. Default 0.1. */
|
|
@@ -323,34 +522,10 @@ interface SnapshotOptions {
|
|
|
323
522
|
scale?: number;
|
|
324
523
|
/** `'image/png'` (default) or `'image/jpeg'`. */
|
|
325
524
|
type?: 'image/png' | 'image/jpeg';
|
|
326
|
-
/**
|
|
327
|
-
as?: 'blob' | 'dataURL';
|
|
328
|
-
}
|
|
329
|
-
/** One picture of a stop (see `movie.stopImages()`). */
|
|
330
|
-
interface StopImage {
|
|
331
|
-
stop: Stop; /** The page it belongs to (0-based). */
|
|
332
|
-
page: number;
|
|
333
|
-
image: Blob | string;
|
|
334
|
-
}
|
|
335
|
-
interface StopImagesOptions {
|
|
336
|
-
/** One picture per page (default) or one per stop. */
|
|
337
|
-
which?: 'pages' | 'stops';
|
|
338
|
-
/** With `which: 'pages'`: the page's last stop (default: the page fully built) or its first. */
|
|
339
|
-
pick?: 'last' | 'first';
|
|
340
|
-
/** Output size relative to the canvas. Default 1. */
|
|
341
|
-
scale?: number;
|
|
342
|
-
/** `'image/png'` (default) or `'image/jpeg'`. */
|
|
343
|
-
type?: 'image/png' | 'image/jpeg';
|
|
344
|
-
/** JPEG quality, 0–1. */
|
|
525
|
+
/** JPEG quality, 0 to 1 (the encoder's default when left out). */
|
|
345
526
|
quality?: number;
|
|
346
|
-
/** Return `data:`
|
|
347
|
-
as?: 'blob' | 'dataURL';
|
|
348
|
-
/** Motion blur for the pictures (off unless you ask: they are usually for looking at). */
|
|
349
|
-
motionBlur?: MotionBlurSpec;
|
|
350
|
-
/** Pictures for a PDF: stops flagged `pdf: false` are left out (a page whose stops are all flagged has no picture). `exportPDF` sets it. */
|
|
351
|
-
pdf?: boolean;
|
|
352
|
-
/** Called as each picture is ready, in order. */
|
|
353
|
-
onImage?: (image: StopImage) => void;
|
|
527
|
+
/** Return a `data:` URL string instead of a Blob (handy for scripts that can only return text), or `'imageData'`: the pixels as an `ImageData` (to measure, compare). */
|
|
528
|
+
as?: 'blob' | 'dataURL' | 'imageData';
|
|
354
529
|
}
|
|
355
530
|
interface ContactSheetOptions {
|
|
356
531
|
/** Motion blur for these pictures (see `MovieOptions.motionBlur`); overrides the movie's own setting, `false` turns it off. */
|
|
@@ -384,12 +559,6 @@ interface FrameEvent {
|
|
|
384
559
|
frame: number;
|
|
385
560
|
totalFrames: number;
|
|
386
561
|
}
|
|
387
|
-
/** A presentation reached a stop (`movie.next()` played to it, or `prev()` / `goToStop()` / `goToPage()` jumped to it). */
|
|
388
|
-
interface StopEvent {
|
|
389
|
-
index: number;
|
|
390
|
-
stop: Stop;
|
|
391
|
-
pageIndex: number;
|
|
392
|
-
}
|
|
393
562
|
interface ProgressEvent {
|
|
394
563
|
progress: number;
|
|
395
564
|
frame: number;
|
|
@@ -413,17 +582,14 @@ declare class Movie {
|
|
|
413
582
|
app: Application | null;
|
|
414
583
|
timeline: Timeline | null;
|
|
415
584
|
audioBuffer: AudioBuffer | null;
|
|
416
|
-
audioSource: AudioBufferSourceNode | null;
|
|
417
|
-
gainNode: GainNode | null;
|
|
418
585
|
private _cancelAudioStart;
|
|
419
586
|
/** The poster time in seconds (`movie.init({ poster })`), or null. */
|
|
420
587
|
poster: number | null;
|
|
421
|
-
/** The stops of the composition (`composition.stops`), checked and in order:
|
|
588
|
+
/** The stops of the composition (`composition.stops`), checked and in order: named times for a presentation to pause on (`pixi-effects/present`). Empty for an ordinary movie. */
|
|
422
589
|
stops: Stop[];
|
|
423
|
-
/** The frame `
|
|
424
|
-
private
|
|
425
|
-
private
|
|
426
|
-
private _arriving;
|
|
590
|
+
/** The frame `playUntil()` is playing toward, or null (also null while it plays to the end). */
|
|
591
|
+
private _until;
|
|
592
|
+
private _untilWaiters;
|
|
427
593
|
/** The motion blur `render()`, `snapshot()` and `contactSheet()` apply unless told otherwise (`movie.init({ motionBlur })`), or null. */
|
|
428
594
|
motionBlur: ResolvedMotionBlur | null;
|
|
429
595
|
private _posterFrame;
|
|
@@ -454,8 +620,6 @@ declare class Movie {
|
|
|
454
620
|
private _audioSources;
|
|
455
621
|
private _mixStats;
|
|
456
622
|
on(event: 'ready', fn: () => void): this;
|
|
457
|
-
/** A presentation is now on a stop (see `stops` in the composition, `next()`, `prev()`). */
|
|
458
|
-
on(event: 'stop', fn: (e: StopEvent) => void): this;
|
|
459
623
|
on(event: 'frame', fn: (e: FrameEvent) => void): this;
|
|
460
624
|
/** A jump to another frame (`gotoFrame`, a seek bar) starts / finishes. Not emitted for playback ticks, `render()`, `snapshot()` or `contactSheet()`. */
|
|
461
625
|
on(event: 'seeking' | 'seeked', fn: (e: FrameEvent) => void): this;
|
|
@@ -469,7 +633,6 @@ declare class Movie {
|
|
|
469
633
|
on(event: 'play', fn: () => void): this;
|
|
470
634
|
on(event: 'pause', fn: () => void): this;
|
|
471
635
|
off(event: string, fn: Listener): this;
|
|
472
|
-
emit(event: string, ...args: unknown[]): void;
|
|
473
636
|
get isReady(): boolean;
|
|
474
637
|
/** Milliseconds `init()` spent in each stage (assets, build, sound, frames), or null before it has finished: `check` says which stage is the slow one. */
|
|
475
638
|
get loadStages(): Record<LoadStage, number> | null;
|
|
@@ -514,55 +677,13 @@ declare class Movie {
|
|
|
514
677
|
snapshot(frame: number | undefined, opts: SnapshotOptions & {
|
|
515
678
|
as: 'dataURL';
|
|
516
679
|
}): Promise<string>;
|
|
680
|
+
snapshot(frame: number | undefined, opts: SnapshotOptions & {
|
|
681
|
+
as: 'imageData';
|
|
682
|
+
}): Promise<ImageData>;
|
|
517
683
|
/** Seek to `frame` (quietly, and stay there) and draw the canvas on a new canvas of `scale` times its size. */
|
|
518
684
|
private _frameCanvas;
|
|
519
|
-
/** The pixels of `frame`, small (about 320 px wide) and without motion blur, to compare pictures. */
|
|
520
|
-
private _framePixels;
|
|
521
685
|
/** Seek to `frame` (quietly, and stay there) and encode the canvas as a picture. */
|
|
522
686
|
private _captureFrame;
|
|
523
|
-
/**
|
|
524
|
-
* A picture of the settled state of each page (default: the page's last stop, fully built) or of every stop, for a page list, an
|
|
525
|
-
* overview, an export. Pauses the movie, and leaves the playhead where it was. `onImage` is called as each picture is ready.
|
|
526
|
-
*/
|
|
527
|
-
stopImages(opts: StopImagesOptions & {
|
|
528
|
-
as: 'dataURL';
|
|
529
|
-
}): Promise<Array<StopImage & {
|
|
530
|
-
image: string;
|
|
531
|
-
}>>;
|
|
532
|
-
stopImages(opts?: StopImagesOptions): Promise<StopImage[]>;
|
|
533
|
-
/**
|
|
534
|
-
* Look at every stop: is the picture there still changing? A stop is compared with the picture `lookback` frames before it (default 3):
|
|
535
|
-
* when more than `tolerance` (default 0.4 %) of the picture differs, the audience, a page overview and a PDF all see a half-finished
|
|
536
|
-
* animation. `issues` says which stop, which page and what to do; leaves the playhead where it was.
|
|
537
|
-
*/
|
|
538
|
-
inspectStops(opts?: {
|
|
539
|
-
lookback?: number;
|
|
540
|
-
tolerance?: number;
|
|
541
|
-
}): Promise<{
|
|
542
|
-
stops: Array<{
|
|
543
|
-
index: number;
|
|
544
|
-
page: string | null;
|
|
545
|
-
at: number;
|
|
546
|
-
frame: number;
|
|
547
|
-
moving: number;
|
|
548
|
-
settled: boolean;
|
|
549
|
-
}>;
|
|
550
|
-
issues: string[];
|
|
551
|
-
}>;
|
|
552
|
-
/**
|
|
553
|
-
* The deck as a PDF: one page per page of the talk (the page's last stop, fully built, unless a stop says `pdf: true` or `pdf: false`;
|
|
554
|
-
* `which: 'stops'` makes a page of every stop that is not `pdf: false`), each a
|
|
555
|
-
* JPEG at the canvas size. Needs `composition.stops`. A transparent background comes out black: give the movie a `background`.
|
|
556
|
-
*/
|
|
557
|
-
exportPDF(opts?: {
|
|
558
|
-
which?: 'pages' | 'stops';
|
|
559
|
-
pick?: 'last' | 'first';
|
|
560
|
-
scale?: number;
|
|
561
|
-
quality?: number;
|
|
562
|
-
title?: string;
|
|
563
|
-
motionBlur?: MotionBlurSpec;
|
|
564
|
-
onImage?: (image: StopImage) => void;
|
|
565
|
-
}): Promise<Blob>;
|
|
566
687
|
/**
|
|
567
688
|
* One picture of a movement: `count` frames from `from` to `to` drawn one over the other, each later one stronger, so a thing that
|
|
568
689
|
* moves leaves a trail (its path and its easing: even steps = constant speed, bunched = slow) and what stays still stays itself.
|
|
@@ -596,7 +717,7 @@ declare class Movie {
|
|
|
596
717
|
timelineData(): TimelineData;
|
|
597
718
|
/** The timeline as one self-contained HTML page (an inline SVG, no scripts): layers as bars on a time axis, ◆ keyframes, transition bands. Open it in a browser. */
|
|
598
719
|
timelineChart(opts?: TimelineHtmlOptions): string;
|
|
599
|
-
/** Just the chart: one `<svg>` whose geometry is in `data-*` attributes (a viewer puts a playhead on it: `pixi-effects
|
|
720
|
+
/** Just the chart: one `<svg>` whose geometry is in `data-*` attributes (a viewer puts a playhead on it: `pixi-effects view`). */
|
|
600
721
|
timelineSvg(opts?: TimelineSvgOptions): string;
|
|
601
722
|
/**
|
|
602
723
|
* The soundtrack, measured: when every audio layer plays, how loud the mix is over time, and `issues`
|
|
@@ -608,7 +729,7 @@ declare class Movie {
|
|
|
608
729
|
frame: number;
|
|
609
730
|
}>;
|
|
610
731
|
/**
|
|
611
|
-
* One call that looks at everything `pixi-effects
|
|
732
|
+
* One call that looks at everything `pixi-effects check` looks at inside the page: layout issues over the whole timeline (every
|
|
612
733
|
* scene's first and last frame and a frame every 0.25 s), fonts and the sound. See `ReviewReport`. Page warnings are in `window.__logs`. The movie is left as it was.
|
|
613
734
|
*/
|
|
614
735
|
review(opts?: ReviewOptions): Promise<ReviewReport>;
|
|
@@ -637,37 +758,24 @@ declare class Movie {
|
|
|
637
758
|
private _updateSpace;
|
|
638
759
|
/** The motion blur an operation uses: its own option when given (`false` is off), otherwise the movie's. */
|
|
639
760
|
private _blurFor;
|
|
761
|
+
private _blurCanvas;
|
|
640
762
|
/**
|
|
641
|
-
*
|
|
642
|
-
*
|
|
763
|
+
* Play and pause exactly at `seconds`: it resolves `true` when the playhead has landed on that frame, `false` when something else ended it
|
|
764
|
+
* first (a `pause()`, a seek, a newer `playUntil()`), or when there is nothing to play toward (a time at or before the playhead, which also
|
|
765
|
+
* pauses it where it is, or a movie that is not ready). A time at or past the end lands on the last frame; with no time at all it plays to
|
|
766
|
+
* the end and resolves `true` once the movie has ended (and says `ended`). An ordinary `play()` is
|
|
767
|
+
* not affected by it. It is the one primitive a presentation is built on (see `pixi-effects/present`).
|
|
643
768
|
*/
|
|
644
|
-
|
|
645
|
-
private _blurCanvas;
|
|
646
|
-
/** Which stop the playhead is on or has passed (-1 before the first). */
|
|
647
|
-
get stopIndex(): number;
|
|
648
|
-
/** The stop the playhead is on or has passed, or null. */
|
|
649
|
-
get currentStop(): Stop | null;
|
|
650
|
-
/** Which page the playhead is in (0-based), -1 before the first stop. */
|
|
651
|
-
get pageIndex(): number;
|
|
652
|
-
/** How many pages the stops make. */
|
|
653
|
-
get pageCount(): number;
|
|
654
|
-
private _cancelStop;
|
|
655
|
-
private _settleStopWaiters;
|
|
656
|
-
private _emitStop;
|
|
657
|
-
/** Land exactly on a stop's frame, pause, and say so. */
|
|
658
|
-
private _arriveAtStop;
|
|
769
|
+
playUntil(seconds?: number): Promise<boolean>;
|
|
659
770
|
/**
|
|
660
|
-
*
|
|
661
|
-
*
|
|
662
|
-
* stopped for another reason). An ordinary `play()` ignores the stops.
|
|
771
|
+
* Look around and put the movie back: pauses, runs `fn` (seek, take pictures: the seeks made inside are not reported as `seeking` / `seeked`),
|
|
772
|
+
* then puts the playhead (or the poster) back where it was, whatever `fn` did, and returns what `fn` returned.
|
|
663
773
|
*/
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
/**
|
|
668
|
-
|
|
669
|
-
/** Jump to the first stop of page `page` (0-based). */
|
|
670
|
-
goToPage(page: number): Promise<void>;
|
|
774
|
+
peek<T>(fn: () => Promise<T>): Promise<T>;
|
|
775
|
+
private _settleUntil;
|
|
776
|
+
private _cancelUntil;
|
|
777
|
+
/** The playhead reached the frame `playUntil()` was playing to: land exactly on it, pause, resolve true. */
|
|
778
|
+
private _arriveUntil;
|
|
671
779
|
play(): void;
|
|
672
780
|
pause(): void;
|
|
673
781
|
set volume(v: number);
|
|
@@ -679,4 +787,4 @@ declare class Movie {
|
|
|
679
787
|
destroy(): Promise<void>;
|
|
680
788
|
}
|
|
681
789
|
|
|
682
|
-
export { type AudioInspectOptions as A, type ContactSheetOptions as C, type FontReport as F, type InspectOptions as I, type LayerInfo as L, type
|
|
790
|
+
export { type AudioInspectOptions as A, failLoader as B, type ContactSheetOptions as C, resolveLoader as D, type FontReport as F, type InspectOptions as I, type LayerInfo as L, type MusicEvents as M, type OnionSkinOptions as O, type ProgressEvent as P, type RenderOptions as R, type SnapshotOptions as S, type TimelineData as T, type VolumeEvent as V, type AudioReport as a, type AudioSourceReport as b, type FrameEvent as c, type InspectReport as d, type IssueGroup as e, type LoadProgressState as f, type LoadStage as g, type LoaderOption as h, type MotionBlurOptions as i, type MotionBlurSpec as j, Movie as k, type MovieErrorEvent as l, type MovieOptions as m, type MusicDrumEvents as n, type MusicDrumHit as o, type MusicNote as p, type MusicSummary as q, type MusicTrackEvents as r, type ReviewOptions as s, type ReviewReport as t, type SoundMeasure as u, type TimelineHtmlOptions as v, type TimelineRow as w, type TimelineSvgOptions as x, type TimelineTransition as y, dismissLoader as z };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
3
|
+
var chunk2DXPTKQZ_cjs = require('./chunk-2DXPTKQZ.cjs');
|
|
4
|
+
require('./chunk-LYOKH7KE.cjs');
|
|
5
5
|
require('./chunk-TWZNOUM7.cjs');
|
|
6
6
|
var pixi_js = require('pixi.js');
|
|
7
7
|
|
|
@@ -68,7 +68,7 @@ function make(name, gl, gpu) {
|
|
|
68
68
|
var OWN_MODES = [...Object.keys(SEPARABLE), ...Object.keys(NONSEP)];
|
|
69
69
|
var done = false;
|
|
70
70
|
function registerBlendModes() {
|
|
71
|
-
|
|
71
|
+
chunk2DXPTKQZ_cjs.setBlendFilterFactory(createBlendFilter);
|
|
72
72
|
if (done) return;
|
|
73
73
|
done = true;
|
|
74
74
|
for (const [name, s] of Object.entries(SEPARABLE)) {
|
|
@@ -90,5 +90,5 @@ fn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { ${s.gpu} }`);
|
|
|
90
90
|
exports.OWN_MODES = OWN_MODES;
|
|
91
91
|
exports.createBlendFilter = createBlendFilter;
|
|
92
92
|
exports.registerBlendModes = registerBlendModes;
|
|
93
|
-
//# sourceMappingURL=blendModes-
|
|
94
|
-
//# sourceMappingURL=blendModes-
|
|
93
|
+
//# sourceMappingURL=blendModes-ETMYWATF.cjs.map
|
|
94
|
+
//# sourceMappingURL=blendModes-ETMYWATF.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/filters/blendModes.ts"],"names":["BlendModeFilter","ExtensionType","extensions","setBlendFilterFactory"],"mappings":"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","file":"blendModes-
|
|
1
|
+
{"version":3,"sources":["../src/filters/blendModes.ts"],"names":["BlendModeFilter","ExtensionType","extensions","setBlendFilterFactory"],"mappings":"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","file":"blendModes-ETMYWATF.cjs","sourcesContent":["import { BlendModeFilter, ExtensionType, extensions } from 'pixi.js';\nimport { setBlendFilterFactory, type BlendFilterLike } from '../core/blend';\n\n/**\n * The W3C compositing blend modes as our own `BlendModeFilter`s, registered on the SAME pixi instance the movie uses (this file imports\n * 'pixi.js' like the rest of the library; `import 'pixi.js/advanced-blend-modes'` would register on its own copy of `extensions` when\n * the page maps pixi.js to an esm.sh bundle, and then nothing is registered and the layer silently draws as `normal`). It also avoids\n * what pixi 8.22's own versions get wrong: the source colour is premultiplied (a half-transparent layer was blended with its darkened\n * colour and then faded again), the backdrop's alpha is ignored, soft-light is inverted on WebGPU (`select` arguments swapped),\n * linear-light and saturation are wrong. Loaded by `Movie.init` only when a layer uses one of these (see `usesAdvancedBlend`).\n */\ntype Sep = { gl: string; gpu: string }; // a separable blend: the body of B(b, s) for one channel\n\nconst SEPARABLE: Record<string, Sep> = {\n overlay: { gl: 'return b <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, b <= 0.5);' },\n 'hard-light': { gl: 'return s <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, s <= 0.5);' },\n 'soft-light': {\n gl: 'if (s <= 0.5) return b - (1.0 - 2.0 * s) * b * (1.0 - b); float d = b <= 0.25 ? ((16.0 * b - 12.0) * b + 4.0) * b : sqrt(b); return b + (2.0 * s - 1.0) * (d - b);',\n gpu: 'let d = select(sqrt(b), ((16.0 * b - 12.0) * b + 4.0) * b, b <= 0.25); return select(b + (2.0 * s - 1.0) * (d - b), b - (1.0 - 2.0 * s) * b * (1.0 - b), s <= 0.5);',\n },\n 'color-dodge': { gl: 'if (b <= 0.0) return 0.0; return s >= 1.0 ? 1.0 : min(1.0, b / (1.0 - s));', gpu: 'if (b <= 0.0) { return 0.0; } return select(min(1.0, b / (1.0 - s)), 1.0, s >= 1.0);' },\n 'color-burn': { gl: 'if (b >= 1.0) return 1.0; return s <= 0.0 ? 0.0 : 1.0 - min(1.0, (1.0 - b) / s);', gpu: 'if (b >= 1.0) { return 1.0; } return select(1.0 - min(1.0, (1.0 - b) / s), 0.0, s <= 0.0);' },\n darken: { gl: 'return min(b, s);', gpu: 'return min(b, s);' },\n lighten: { gl: 'return max(b, s);', gpu: 'return max(b, s);' },\n difference: { gl: 'return abs(b - s);', gpu: 'return abs(b - s);' },\n exclusion: { gl: 'return b + s - 2.0 * b * s;', gpu: 'return b + s - 2.0 * b * s;' },\n 'linear-burn': { gl: 'return max(0.0, b + s - 1.0);', gpu: 'return max(0.0, b + s - 1.0);' },\n};\n\nconst GL_NONSEP = `\nfloat lum(vec3 c) { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nvec3 clipColor(vec3 c) { float l = lum(c); float n = min(c.r, min(c.g, c.b)); float x = max(c.r, max(c.g, c.b));\n if (n < 0.0) c = l + (c - l) * l / (l - n); if (x > 1.0) c = l + (c - l) * (1.0 - l) / (x - l); return c; }\nvec3 setLum(vec3 c, float l) { return clipColor(c + (l - lum(c))); }\nfloat sat(vec3 c) { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nvec3 setSat(vec3 c, float s) { float mx = max(c.r, max(c.g, c.b)); float mn = min(c.r, min(c.g, c.b)); return mx > mn ? (c - mn) * s / (mx - mn) : vec3(0.0); }`;\nconst GPU_NONSEP = `\nfn lum(c: vec3<f32>) -> f32 { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nfn clipColor(c0: vec3<f32>) -> vec3<f32> { var c = c0; let l = lum(c); let n = min(c.r, min(c.g, c.b)); let x = max(c.r, max(c.g, c.b));\n if (n < 0.0) { c = l + (c - l) * l / (l - n); } if (x > 1.0) { c = l + (c - l) * (1.0 - l) / (x - l); } return c; }\nfn setLum(c: vec3<f32>, l: f32) -> vec3<f32> { return clipColor(c + (l - lum(c))); }\nfn sat(c: vec3<f32>) -> f32 { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nfn setSat(c: vec3<f32>, s: f32) -> vec3<f32> { let mx = max(c.r, max(c.g, c.b)); let mn = min(c.r, min(c.g, c.b)); if (mx > mn) { return (c - vec3<f32>(mn)) * s / (mx - mn); } return vec3<f32>(0.0); }`;\nconst NONSEP: Record<string, { gl: string; gpu: string }> = {\n hue: { gl: 'return setLum(setSat(cs, sat(cb)), lum(cb));', gpu: 'return setLum(setSat(cs, sat(cb)), lum(cb));' },\n saturation: { gl: 'return setLum(setSat(cb, sat(cs)), lum(cb));', gpu: 'return setLum(setSat(cb, sat(cs)), lum(cb));' },\n color: { gl: 'return setLum(cs, lum(cb));', gpu: 'return setLum(cs, lum(cb));' },\n luminosity: { gl: 'return setLum(cb, lum(cs));', gpu: 'return setLum(cb, lum(cs));' },\n};\n\nconst GL_MAIN = `\n vec3 cs = front.a > 0.0 ? front.rgb / front.a : vec3(0.0);\n vec3 cb = back.a > 0.0 ? back.rgb / back.a : vec3(0.0);\n vec3 mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n finalColor = vec4(mixed, blendedAlpha) * uBlend;`;\nconst GPU_MAIN = `\n let cs = select(vec3<f32>(0.0), front.rgb / front.a, front.a > 0.0);\n let cb = select(vec3<f32>(0.0), back.rgb / back.a, back.a > 0.0);\n let mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n out = vec4<f32>(mixed, blendedAlpha) * blendUniforms.uBlend;`;\n\nconst CLASSES = new Map<string, new () => BlendModeFilter>();\n\n/** A fresh blend filter for a layer that has filters of its own (it goes last in the chain and reads the backdrop). */\nexport function createBlendFilter(name: string): BlendFilterLike | null {\n const C = CLASSES.get(name);\n return C ? (new C() as unknown as BlendFilterLike) : null;\n}\n\nfunction make(name: string, gl: string, gpu: string): void {\n const C = class extends BlendModeFilter {\n static extension = { name, type: ExtensionType.BlendMode };\n constructor() { super({ gl: { functions: gl, main: GL_MAIN }, gpu: { functions: gpu, main: GPU_MAIN } }); }\n };\n CLASSES.set(name, C);\n extensions.add(C as never);\n}\n\nexport const OWN_MODES: readonly string[] = [...Object.keys(SEPARABLE), ...Object.keys(NONSEP)];\n\nlet done = false;\n/** Register the blends (once per page), and give `core/blend.ts` the maker for the filter chain case. */\nexport function registerBlendModes(): void {\n setBlendFilterFactory(createBlendFilter); // every call: the registration below is once per page, the maker is cheap to hand over again\n if (done) return;\n done = true;\n for (const [name, s] of Object.entries(SEPARABLE)) {\n make(name,\n `float B(float b, float s) { ${s.gl} }\\nvec3 blendRGB(vec3 cb, vec3 cs) { return vec3(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`,\n `fn B(b: f32, s: f32) -> f32 { ${s.gpu} }\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { return vec3<f32>(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`);\n }\n for (const [name, s] of Object.entries(NONSEP)) {\n make(name, `${GL_NONSEP}\\nvec3 blendRGB(vec3 cb, vec3 cs) { ${s.gl} }`, `${GPU_NONSEP}\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { ${s.gpu} }`);\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { setBlendFilterFactory } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
import { setBlendFilterFactory } from './chunk-4KB3GUEK.js';
|
|
2
|
+
import './chunk-RCVZX2JP.js';
|
|
3
3
|
import './chunk-BXOCEZ4U.js';
|
|
4
4
|
import { BlendModeFilter, ExtensionType, extensions } from 'pixi.js';
|
|
5
5
|
|
|
@@ -86,5 +86,5 @@ fn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { ${s.gpu} }`);
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
export { OWN_MODES, createBlendFilter, registerBlendModes };
|
|
89
|
-
//# sourceMappingURL=blendModes-
|
|
90
|
-
//# sourceMappingURL=blendModes-
|
|
89
|
+
//# sourceMappingURL=blendModes-RIVZXL5A.js.map
|
|
90
|
+
//# sourceMappingURL=blendModes-RIVZXL5A.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/filters/blendModes.ts"],"names":[],"mappings":"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","file":"blendModes-
|
|
1
|
+
{"version":3,"sources":["../src/filters/blendModes.ts"],"names":[],"mappings":"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","file":"blendModes-RIVZXL5A.js","sourcesContent":["import { BlendModeFilter, ExtensionType, extensions } from 'pixi.js';\nimport { setBlendFilterFactory, type BlendFilterLike } from '../core/blend';\n\n/**\n * The W3C compositing blend modes as our own `BlendModeFilter`s, registered on the SAME pixi instance the movie uses (this file imports\n * 'pixi.js' like the rest of the library; `import 'pixi.js/advanced-blend-modes'` would register on its own copy of `extensions` when\n * the page maps pixi.js to an esm.sh bundle, and then nothing is registered and the layer silently draws as `normal`). It also avoids\n * what pixi 8.22's own versions get wrong: the source colour is premultiplied (a half-transparent layer was blended with its darkened\n * colour and then faded again), the backdrop's alpha is ignored, soft-light is inverted on WebGPU (`select` arguments swapped),\n * linear-light and saturation are wrong. Loaded by `Movie.init` only when a layer uses one of these (see `usesAdvancedBlend`).\n */\ntype Sep = { gl: string; gpu: string }; // a separable blend: the body of B(b, s) for one channel\n\nconst SEPARABLE: Record<string, Sep> = {\n overlay: { gl: 'return b <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, b <= 0.5);' },\n 'hard-light': { gl: 'return s <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, s <= 0.5);' },\n 'soft-light': {\n gl: 'if (s <= 0.5) return b - (1.0 - 2.0 * s) * b * (1.0 - b); float d = b <= 0.25 ? ((16.0 * b - 12.0) * b + 4.0) * b : sqrt(b); return b + (2.0 * s - 1.0) * (d - b);',\n gpu: 'let d = select(sqrt(b), ((16.0 * b - 12.0) * b + 4.0) * b, b <= 0.25); return select(b + (2.0 * s - 1.0) * (d - b), b - (1.0 - 2.0 * s) * b * (1.0 - b), s <= 0.5);',\n },\n 'color-dodge': { gl: 'if (b <= 0.0) return 0.0; return s >= 1.0 ? 1.0 : min(1.0, b / (1.0 - s));', gpu: 'if (b <= 0.0) { return 0.0; } return select(min(1.0, b / (1.0 - s)), 1.0, s >= 1.0);' },\n 'color-burn': { gl: 'if (b >= 1.0) return 1.0; return s <= 0.0 ? 0.0 : 1.0 - min(1.0, (1.0 - b) / s);', gpu: 'if (b >= 1.0) { return 1.0; } return select(1.0 - min(1.0, (1.0 - b) / s), 0.0, s <= 0.0);' },\n darken: { gl: 'return min(b, s);', gpu: 'return min(b, s);' },\n lighten: { gl: 'return max(b, s);', gpu: 'return max(b, s);' },\n difference: { gl: 'return abs(b - s);', gpu: 'return abs(b - s);' },\n exclusion: { gl: 'return b + s - 2.0 * b * s;', gpu: 'return b + s - 2.0 * b * s;' },\n 'linear-burn': { gl: 'return max(0.0, b + s - 1.0);', gpu: 'return max(0.0, b + s - 1.0);' },\n};\n\nconst GL_NONSEP = `\nfloat lum(vec3 c) { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nvec3 clipColor(vec3 c) { float l = lum(c); float n = min(c.r, min(c.g, c.b)); float x = max(c.r, max(c.g, c.b));\n if (n < 0.0) c = l + (c - l) * l / (l - n); if (x > 1.0) c = l + (c - l) * (1.0 - l) / (x - l); return c; }\nvec3 setLum(vec3 c, float l) { return clipColor(c + (l - lum(c))); }\nfloat sat(vec3 c) { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nvec3 setSat(vec3 c, float s) { float mx = max(c.r, max(c.g, c.b)); float mn = min(c.r, min(c.g, c.b)); return mx > mn ? (c - mn) * s / (mx - mn) : vec3(0.0); }`;\nconst GPU_NONSEP = `\nfn lum(c: vec3<f32>) -> f32 { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nfn clipColor(c0: vec3<f32>) -> vec3<f32> { var c = c0; let l = lum(c); let n = min(c.r, min(c.g, c.b)); let x = max(c.r, max(c.g, c.b));\n if (n < 0.0) { c = l + (c - l) * l / (l - n); } if (x > 1.0) { c = l + (c - l) * (1.0 - l) / (x - l); } return c; }\nfn setLum(c: vec3<f32>, l: f32) -> vec3<f32> { return clipColor(c + (l - lum(c))); }\nfn sat(c: vec3<f32>) -> f32 { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nfn setSat(c: vec3<f32>, s: f32) -> vec3<f32> { let mx = max(c.r, max(c.g, c.b)); let mn = min(c.r, min(c.g, c.b)); if (mx > mn) { return (c - vec3<f32>(mn)) * s / (mx - mn); } return vec3<f32>(0.0); }`;\nconst NONSEP: Record<string, { gl: string; gpu: string }> = {\n hue: { gl: 'return setLum(setSat(cs, sat(cb)), lum(cb));', gpu: 'return setLum(setSat(cs, sat(cb)), lum(cb));' },\n saturation: { gl: 'return setLum(setSat(cb, sat(cs)), lum(cb));', gpu: 'return setLum(setSat(cb, sat(cs)), lum(cb));' },\n color: { gl: 'return setLum(cs, lum(cb));', gpu: 'return setLum(cs, lum(cb));' },\n luminosity: { gl: 'return setLum(cb, lum(cs));', gpu: 'return setLum(cb, lum(cs));' },\n};\n\nconst GL_MAIN = `\n vec3 cs = front.a > 0.0 ? front.rgb / front.a : vec3(0.0);\n vec3 cb = back.a > 0.0 ? back.rgb / back.a : vec3(0.0);\n vec3 mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n finalColor = vec4(mixed, blendedAlpha) * uBlend;`;\nconst GPU_MAIN = `\n let cs = select(vec3<f32>(0.0), front.rgb / front.a, front.a > 0.0);\n let cb = select(vec3<f32>(0.0), back.rgb / back.a, back.a > 0.0);\n let mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n out = vec4<f32>(mixed, blendedAlpha) * blendUniforms.uBlend;`;\n\nconst CLASSES = new Map<string, new () => BlendModeFilter>();\n\n/** A fresh blend filter for a layer that has filters of its own (it goes last in the chain and reads the backdrop). */\nexport function createBlendFilter(name: string): BlendFilterLike | null {\n const C = CLASSES.get(name);\n return C ? (new C() as unknown as BlendFilterLike) : null;\n}\n\nfunction make(name: string, gl: string, gpu: string): void {\n const C = class extends BlendModeFilter {\n static extension = { name, type: ExtensionType.BlendMode };\n constructor() { super({ gl: { functions: gl, main: GL_MAIN }, gpu: { functions: gpu, main: GPU_MAIN } }); }\n };\n CLASSES.set(name, C);\n extensions.add(C as never);\n}\n\nexport const OWN_MODES: readonly string[] = [...Object.keys(SEPARABLE), ...Object.keys(NONSEP)];\n\nlet done = false;\n/** Register the blends (once per page), and give `core/blend.ts` the maker for the filter chain case. */\nexport function registerBlendModes(): void {\n setBlendFilterFactory(createBlendFilter); // every call: the registration below is once per page, the maker is cheap to hand over again\n if (done) return;\n done = true;\n for (const [name, s] of Object.entries(SEPARABLE)) {\n make(name,\n `float B(float b, float s) { ${s.gl} }\\nvec3 blendRGB(vec3 cb, vec3 cs) { return vec3(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`,\n `fn B(b: f32, s: f32) -> f32 { ${s.gpu} }\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { return vec3<f32>(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`);\n }\n for (const [name, s] of Object.entries(NONSEP)) {\n make(name, `${GL_NONSEP}\\nvec3 blendRGB(vec3 cb, vec3 cs) { ${s.gl} }`, `${GPU_NONSEP}\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { ${s.gpu} }`);\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkLYOKH7KE_cjs = require('./chunk-LYOKH7KE.cjs');
|
|
4
4
|
var chunkTWZNOUM7_cjs = require('./chunk-TWZNOUM7.cjs');
|
|
5
5
|
|
|
6
6
|
// src/core/blend.ts
|
|
@@ -36,11 +36,11 @@ function usesAdvancedBlend(spec) {
|
|
|
36
36
|
if (!n || typeof n !== "object") return false;
|
|
37
37
|
if (Array.isArray(n)) return n.some(visit);
|
|
38
38
|
const o = n;
|
|
39
|
-
return isAdvancedBlend(o.blendMode) || visit(o.sequences) || visit(o.mask);
|
|
39
|
+
return isAdvancedBlend(o.blendMode) || visit(o.sequences) || visit(o.mask) || visit(o.layer);
|
|
40
40
|
};
|
|
41
41
|
return visit(spec);
|
|
42
42
|
}
|
|
43
|
-
var sayNow = (message, spec) => console.warn(`pixi-effects: ${
|
|
43
|
+
var sayNow = (message, spec) => console.warn(`pixi-effects: ${chunkLYOKH7KE_cjs.describeLayer(spec)}: ${message}`);
|
|
44
44
|
function blendUnavailableMessage(mode) {
|
|
45
45
|
return `blendMode "${mode}" could not be set up (the blend filters are not registered); the layer is drawn normal`;
|
|
46
46
|
}
|
|
@@ -85,7 +85,7 @@ function blendFilterFor(mode) {
|
|
|
85
85
|
}
|
|
86
86
|
async function enableAdvancedBlend(renderer) {
|
|
87
87
|
try {
|
|
88
|
-
const { registerBlendModes } = await import('./blendModes-
|
|
88
|
+
const { registerBlendModes } = await import('./blendModes-ETMYWATF.cjs');
|
|
89
89
|
registerBlendModes();
|
|
90
90
|
} catch (e) {
|
|
91
91
|
const why = e instanceof Error ? e.message : String(e);
|
|
@@ -137,5 +137,5 @@ exports.isAdvancedBlend = isAdvancedBlend;
|
|
|
137
137
|
exports.maxConcurrentAdvanced = maxConcurrentAdvanced;
|
|
138
138
|
exports.setBlendFilterFactory = setBlendFilterFactory;
|
|
139
139
|
exports.usesAdvancedBlend = usesAdvancedBlend;
|
|
140
|
-
//# sourceMappingURL=chunk-
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
140
|
+
//# sourceMappingURL=chunk-2DXPTKQZ.cjs.map
|
|
141
|
+
//# sourceMappingURL=chunk-2DXPTKQZ.cjs.map
|