pixi-effects 0.6.0 → 0.8.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 +29 -0
- package/README.md +18 -11
- package/ai/SKILL.md +1 -1
- package/ai/reference/cheatsheet.md +9 -1
- package/ai/template.html +4 -3
- package/ai/tools/check.mjs +14 -5
- package/ai/tools/render.mjs +202 -0
- package/ai/tools/view.mjs +269 -0
- package/dist/{Base-4vNLl4tH.d.cts → Base-CSIulyIq.d.cts} +1 -1
- package/dist/{Base-CD4AoT5-.d.ts → Base-DVgwyIUj.d.ts} +1 -1
- package/dist/Composition-CM62XJKT.cjs +14 -0
- package/dist/{Composition-Y5VZSDDP.cjs.map → Composition-CM62XJKT.cjs.map} +1 -1
- package/dist/Composition-RJDSQYTV.js +5 -0
- package/dist/{Composition-7SO5WYHU.js.map → Composition-RJDSQYTV.js.map} +1 -1
- package/dist/Controller.cjs +122 -20
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.d.cts +45 -3
- package/dist/Controller.d.ts +45 -3
- package/dist/Controller.js +122 -21
- package/dist/Controller.js.map +1 -1
- package/dist/{Movie-Ch2SUI1h.d.ts → Movie-CQOhUmko.d.cts} +75 -2
- package/dist/{Movie-CADDBfpl.d.cts → Movie-HF3pSGjQ.d.ts} +75 -2
- package/dist/{chunk-KQM2ZZMK.cjs → chunk-AGMNSJJH.cjs} +175 -29
- package/dist/chunk-AGMNSJJH.cjs.map +1 -0
- package/dist/{chunk-7IJHJXDI.js → chunk-FNKSXBKB.js} +136 -10
- package/dist/chunk-FNKSXBKB.js.map +1 -0
- package/dist/{chunk-B2FTJLNB.js → chunk-O4AJYUPK.js} +3 -3
- package/dist/{chunk-B2FTJLNB.js.map → chunk-O4AJYUPK.js.map} +1 -1
- package/dist/{chunk-4AGJF5RK.cjs → chunk-PDBDDGG5.cjs} +21 -21
- package/dist/{chunk-4AGJF5RK.cjs.map → chunk-PDBDDGG5.cjs.map} +1 -1
- package/dist/index.cjs +255 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +248 -18
- package/dist/index.js.map +1 -1
- package/dist/three.cjs +6 -5
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +2 -1
- package/dist/three.js.map +1 -1
- package/dist/{types-DrW9QeKU.d.ts → types-oJijbn-K.d.cts} +14 -1
- package/dist/{types-DrW9QeKU.d.cts → types-oJijbn-K.d.ts} +14 -1
- package/docs/api.md +57 -0
- package/docs/dsl.md +60 -1
- package/llms-full.txt +127 -3
- package/package.json +7 -4
- package/dist/Composition-7SO5WYHU.js +0 -4
- package/dist/Composition-Y5VZSDDP.cjs +0 -13
- package/dist/chunk-7IJHJXDI.js.map +0 -1
- package/dist/chunk-KQM2ZZMK.cjs.map +0 -1
package/dist/Controller.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { warnUnknownOptions } from './chunk-DKGG7WD4.js';
|
|
2
|
+
|
|
1
3
|
// src/Controller.ts
|
|
2
4
|
var ICONS = {
|
|
3
5
|
play: '<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M3 2 L13 8 L3 14 Z"/></svg>',
|
|
@@ -9,12 +11,12 @@ var ICONS = {
|
|
|
9
11
|
fullscreenExit: '<svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"><path d="M6 2 V6 H2 M10 2 V6 H14 M6 14 V10 H2 M10 14 V10 H14"/></svg>'
|
|
10
12
|
};
|
|
11
13
|
var STYLE_ATTR = "data-movie-controller";
|
|
12
|
-
var
|
|
14
|
+
var CONTROLLER_CSS = `
|
|
13
15
|
.movie-controller-wrap { position: relative; display: inline-block; line-height: 0; }
|
|
14
16
|
.movie-controller {
|
|
15
17
|
position: absolute;
|
|
16
18
|
pointer-events: none;
|
|
17
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
19
|
+
font-family: var(--mc-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
|
|
18
20
|
display: flex;
|
|
19
21
|
flex-direction: column;
|
|
20
22
|
justify-content: flex-end;
|
|
@@ -34,31 +36,31 @@ var STYLE_CSS = `
|
|
|
34
36
|
outline: none;
|
|
35
37
|
}
|
|
36
38
|
.mc-progress:focus-visible {
|
|
37
|
-
outline: 2px solid #007AFF;
|
|
39
|
+
outline: 2px solid var(--mc-accent, #007AFF);
|
|
38
40
|
outline-offset: 2px;
|
|
39
41
|
}
|
|
40
42
|
.mc-progress::before {
|
|
41
43
|
content: ""; position: absolute; left: 12px; right: 12px;
|
|
42
|
-
height: 3px; background: rgba(255,255,255,0.25);
|
|
44
|
+
height: var(--mc-track-height, 3px); background: var(--mc-track, rgba(255,255,255,0.25));
|
|
43
45
|
transition: height 120ms ease;
|
|
44
46
|
}
|
|
45
|
-
.mc-progress:hover::before, .mc-progress.mc-scrubbing::before { height:
|
|
47
|
+
.mc-progress:hover::before, .mc-progress.mc-scrubbing::before { height: calc(var(--mc-track-height, 3px) + 2px); }
|
|
46
48
|
.mc-progress-fill {
|
|
47
49
|
position: absolute; left: 12px; top: 50%;
|
|
48
|
-
height: 3px;
|
|
50
|
+
height: var(--mc-track-height, 3px);
|
|
49
51
|
width: calc((100% - 24px) * var(--mc-fill, 0));
|
|
50
|
-
background: #007AFF;
|
|
52
|
+
background: var(--mc-accent, #007AFF);
|
|
51
53
|
transform: translateY(-50%);
|
|
52
54
|
transition: height 120ms ease;
|
|
53
55
|
pointer-events: none;
|
|
54
56
|
}
|
|
55
57
|
.mc-progress:hover .mc-progress-fill,
|
|
56
|
-
.mc-progress.mc-scrubbing .mc-progress-fill { height:
|
|
58
|
+
.mc-progress.mc-scrubbing .mc-progress-fill { height: calc(var(--mc-track-height, 3px) + 2px); }
|
|
57
59
|
.mc-progress-thumb {
|
|
58
60
|
position: absolute; top: 50%;
|
|
59
61
|
left: calc(12px + (100% - 24px) * var(--mc-fill, 0));
|
|
60
62
|
width: 12px; height: 12px; border-radius: 50%;
|
|
61
|
-
background: #007AFF;
|
|
63
|
+
background: var(--mc-accent, #007AFF);
|
|
62
64
|
transform: translate(-50%, -50%) scale(0);
|
|
63
65
|
transition: transform 120ms ease;
|
|
64
66
|
pointer-events: none;
|
|
@@ -72,22 +74,22 @@ var STYLE_CSS = `
|
|
|
72
74
|
align-items: center;
|
|
73
75
|
gap: 12px;
|
|
74
76
|
padding: 6px 12px 8px 12px;
|
|
75
|
-
background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0) 100%);
|
|
76
|
-
color: #fff;
|
|
77
|
+
background: var(--mc-bar-bg, linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0) 100%));
|
|
78
|
+
color: var(--mc-fg, #fff);
|
|
77
79
|
line-height: 1;
|
|
78
80
|
}
|
|
79
81
|
.mc-btn {
|
|
80
82
|
background: none; border: 0; padding: 0; margin: 0;
|
|
81
83
|
width: 28px; height: 28px;
|
|
82
84
|
display: inline-flex; align-items: center; justify-content: center;
|
|
83
|
-
color: #fff; opacity: 0.85; cursor: pointer;
|
|
85
|
+
color: var(--mc-fg, #fff); opacity: 0.85; cursor: pointer;
|
|
84
86
|
transition: opacity 120ms ease;
|
|
85
87
|
}
|
|
86
88
|
.mc-btn:hover { opacity: 1; }
|
|
87
89
|
.mc-btn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
88
90
|
.mc-time {
|
|
89
91
|
font-size: 12px; font-family: Menlo, Monaco, monospace;
|
|
90
|
-
color: #fff; opacity: 0.85;
|
|
92
|
+
color: var(--mc-fg, #fff); opacity: 0.85;
|
|
91
93
|
min-width: 90px;
|
|
92
94
|
}
|
|
93
95
|
.mc-spacer { flex: 1; }
|
|
@@ -111,16 +113,16 @@ var STYLE_CSS = `
|
|
|
111
113
|
width: 70px;
|
|
112
114
|
margin-left: 6px;
|
|
113
115
|
}
|
|
114
|
-
.mc-vol-slider:focus-visible { outline: 2px solid #007AFF; outline-offset: 2px; }
|
|
116
|
+
.mc-vol-slider:focus-visible { outline: 2px solid var(--mc-accent, #007AFF); outline-offset: 2px; }
|
|
115
117
|
.mc-vol-slider::before {
|
|
116
118
|
content: ""; position: absolute; left: 4px; right: 4px;
|
|
117
|
-
height: 3px; background: rgba(255,255,255,0.25); border-radius: 2px;
|
|
119
|
+
height: 3px; background: var(--mc-track, rgba(255,255,255,0.25)); border-radius: 2px;
|
|
118
120
|
}
|
|
119
121
|
.mc-vol-fill {
|
|
120
122
|
position: absolute; left: 4px; top: 50%;
|
|
121
123
|
height: 3px;
|
|
122
124
|
width: calc((100% - 8px) * var(--mc-volume, 1));
|
|
123
|
-
background: #fff;
|
|
125
|
+
background: var(--mc-fg, #fff);
|
|
124
126
|
transform: translateY(-50%);
|
|
125
127
|
border-radius: 2px;
|
|
126
128
|
pointer-events: none;
|
|
@@ -129,7 +131,7 @@ var STYLE_CSS = `
|
|
|
129
131
|
position: absolute; top: 50%;
|
|
130
132
|
left: calc(4px + (100% - 8px) * var(--mc-volume, 1));
|
|
131
133
|
width: 10px; height: 10px; border-radius: 50%;
|
|
132
|
-
background: #fff;
|
|
134
|
+
background: var(--mc-fg, #fff);
|
|
133
135
|
transform: translate(-50%, -50%);
|
|
134
136
|
pointer-events: none;
|
|
135
137
|
}
|
|
@@ -183,7 +185,7 @@ var STYLE_CSS = `
|
|
|
183
185
|
.mc-export-confirm {
|
|
184
186
|
margin-top: 4px;
|
|
185
187
|
width: 100%;
|
|
186
|
-
background: #007AFF;
|
|
188
|
+
background: var(--mc-accent, #007AFF);
|
|
187
189
|
color: #fff;
|
|
188
190
|
border: 0;
|
|
189
191
|
border-radius: 4px;
|
|
@@ -216,7 +218,7 @@ var STYLE_CSS = `
|
|
|
216
218
|
}
|
|
217
219
|
.mc-export-fill {
|
|
218
220
|
height: 100%; width: 0%;
|
|
219
|
-
background: linear-gradient(90deg, #007AFF, #0056CC);
|
|
221
|
+
background: linear-gradient(90deg, var(--mc-accent, #007AFF), var(--mc-accent, #0056CC));
|
|
220
222
|
transition: width 0.3s ease; border-radius: 3px;
|
|
221
223
|
}
|
|
222
224
|
.mc-export-text {
|
|
@@ -229,7 +231,7 @@ function installStyles() {
|
|
|
229
231
|
if (styleRefCount === 0) {
|
|
230
232
|
const el = document.createElement("style");
|
|
231
233
|
el.setAttribute(STYLE_ATTR, "");
|
|
232
|
-
el.textContent =
|
|
234
|
+
el.textContent = CONTROLLER_CSS;
|
|
233
235
|
document.head.appendChild(el);
|
|
234
236
|
}
|
|
235
237
|
styleRefCount++;
|
|
@@ -271,12 +273,25 @@ function extensionForMimeType(mime) {
|
|
|
271
273
|
if (t.includes("matroska") || t.includes("mkv")) return "mkv";
|
|
272
274
|
return "mp4";
|
|
273
275
|
}
|
|
276
|
+
var THEME_PROPERTIES = {
|
|
277
|
+
accent: "--mc-accent",
|
|
278
|
+
foreground: "--mc-fg",
|
|
279
|
+
track: "--mc-track",
|
|
280
|
+
barBackground: "--mc-bar-bg",
|
|
281
|
+
trackHeight: "--mc-track-height",
|
|
282
|
+
font: "--mc-font"
|
|
283
|
+
};
|
|
274
284
|
var Controller = class _Controller {
|
|
275
285
|
movie;
|
|
276
286
|
options;
|
|
277
287
|
root;
|
|
278
288
|
wrapper;
|
|
279
289
|
wrappedHere = false;
|
|
290
|
+
/** The canvas's own inline width / height, as the page wrote them (we override them while the wrapper is fitted). */
|
|
291
|
+
canvasInlineWidth = "";
|
|
292
|
+
canvasInlineHeight = "";
|
|
293
|
+
fitWrapHandler = null;
|
|
294
|
+
fitObserver = null;
|
|
280
295
|
destroyed = false;
|
|
281
296
|
progressEl;
|
|
282
297
|
progressFillEl;
|
|
@@ -338,6 +353,8 @@ var Controller = class _Controller {
|
|
|
338
353
|
this.root.className = this.options.className;
|
|
339
354
|
this.wrapper.appendChild(this.root);
|
|
340
355
|
this.buildBar();
|
|
356
|
+
this.setTheme(options.theme ?? {});
|
|
357
|
+
this.bindFitWrap();
|
|
341
358
|
this.syncRootToCanvas();
|
|
342
359
|
if (typeof ResizeObserver !== "undefined") {
|
|
343
360
|
this.resizeObserver = new ResizeObserver(() => this.syncRootToCanvas());
|
|
@@ -416,6 +433,17 @@ var Controller = class _Controller {
|
|
|
416
433
|
if (this.settingsFormatSelect) this.settingsFormatSelect.value = this.exportFormat;
|
|
417
434
|
if (this.settingsQualitySelect) this.settingsQualitySelect.value = this.exportQuality;
|
|
418
435
|
}
|
|
436
|
+
/** Change the look of the bar (see {@link ControllerTheme}): only the keys you give change, `null` restores the default. */
|
|
437
|
+
setTheme(theme) {
|
|
438
|
+
warnUnknownOptions("Controller theme", theme, Object.keys(THEME_PROPERTIES));
|
|
439
|
+
for (const key of Object.keys(THEME_PROPERTIES)) {
|
|
440
|
+
if (!(key in theme)) continue;
|
|
441
|
+
const value = theme[key];
|
|
442
|
+
const prop = THEME_PROPERTIES[key];
|
|
443
|
+
if (value === null || value === void 0 || value === "") this.root.style.removeProperty(prop);
|
|
444
|
+
else this.root.style.setProperty(prop, typeof value === "number" ? `${value}px` : String(value));
|
|
445
|
+
}
|
|
446
|
+
}
|
|
419
447
|
ensurePositioningContext(canvas) {
|
|
420
448
|
const parent = canvas.parentElement;
|
|
421
449
|
if (!parent) {
|
|
@@ -435,8 +463,56 @@ var Controller = class _Controller {
|
|
|
435
463
|
parent.insertBefore(wrap, canvas);
|
|
436
464
|
wrap.appendChild(canvas);
|
|
437
465
|
this.wrappedHere = true;
|
|
466
|
+
this.canvasInlineWidth = canvas.style.width;
|
|
467
|
+
this.canvasInlineHeight = canvas.style.height;
|
|
438
468
|
return wrap;
|
|
439
469
|
}
|
|
470
|
+
/**
|
|
471
|
+
* Make the wrapper exactly as wide as the canvas. A shrink-to-fit wrapper around a canvas that is sized in percent (the usual
|
|
472
|
+
* `canvas { width: min(960px, 100%) }`) is as wide as the canvas's width ATTRIBUTE (1280), so the picture sat at its left edge
|
|
473
|
+
* with an empty strip beside it. We measure the canvas as the page styled it (the wrapper made transparent to layout), give
|
|
474
|
+
* the wrapper that width, and let the canvas fill the wrapper. Re-measured when the window or the page's box changes.
|
|
475
|
+
*/
|
|
476
|
+
fitWrap() {
|
|
477
|
+
if (!this.wrappedHere) return;
|
|
478
|
+
const wrap = this.wrapper, canvas = this.options.canvas;
|
|
479
|
+
if (document.fullscreenElement === wrap) {
|
|
480
|
+
wrap.style.width = "";
|
|
481
|
+
canvas.style.width = this.canvasInlineWidth;
|
|
482
|
+
canvas.style.height = this.canvasInlineHeight;
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
canvas.style.width = this.canvasInlineWidth;
|
|
486
|
+
canvas.style.height = this.canvasInlineHeight;
|
|
487
|
+
const display = wrap.style.display;
|
|
488
|
+
wrap.style.display = "contents";
|
|
489
|
+
wrap.style.width = "";
|
|
490
|
+
const w = canvas.getBoundingClientRect().width;
|
|
491
|
+
wrap.style.display = display;
|
|
492
|
+
if (!(w > 0)) return;
|
|
493
|
+
wrap.style.width = `${w}px`;
|
|
494
|
+
canvas.style.width = "100%";
|
|
495
|
+
canvas.style.height = "auto";
|
|
496
|
+
}
|
|
497
|
+
bindFitWrap() {
|
|
498
|
+
if (!this.wrappedHere) return;
|
|
499
|
+
this.fitWrap();
|
|
500
|
+
let queued = false;
|
|
501
|
+
this.fitWrapHandler = () => {
|
|
502
|
+
if (queued) return;
|
|
503
|
+
queued = true;
|
|
504
|
+
requestAnimationFrame(() => {
|
|
505
|
+
queued = false;
|
|
506
|
+
this.fitWrap();
|
|
507
|
+
});
|
|
508
|
+
};
|
|
509
|
+
window.addEventListener("resize", this.fitWrapHandler);
|
|
510
|
+
const parent = this.wrapper.parentElement;
|
|
511
|
+
if (parent && typeof ResizeObserver !== "undefined") {
|
|
512
|
+
this.fitObserver = new ResizeObserver(this.fitWrapHandler);
|
|
513
|
+
this.fitObserver.observe(parent);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
440
516
|
bindMovieEvents() {
|
|
441
517
|
this.onReady = () => {
|
|
442
518
|
this.progressEl.setAttribute("aria-valuemax", String(this.movie.totalFrames));
|
|
@@ -549,12 +625,25 @@ var Controller = class _Controller {
|
|
|
549
625
|
};
|
|
550
626
|
container.addEventListener("wheel", this.wheelHandler, { passive: false });
|
|
551
627
|
}
|
|
628
|
+
/**
|
|
629
|
+
* Does this browser have the Fullscreen API for an element? iPhone Safari does not (it can only put a <video> in fullscreen),
|
|
630
|
+
* and a button that does nothing is worse than none.
|
|
631
|
+
*/
|
|
632
|
+
supportsFullscreen() {
|
|
633
|
+
return typeof this.wrapper.requestFullscreen === "function" && document.fullscreenEnabled !== false;
|
|
634
|
+
}
|
|
552
635
|
bindFullscreen() {
|
|
553
636
|
if (!this.fullscreenBtn) return;
|
|
637
|
+
if (!this.supportsFullscreen()) {
|
|
638
|
+
this.fullscreenBtn.remove();
|
|
639
|
+
this.fullscreenBtn = null;
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
554
642
|
this.fullscreenBtn.addEventListener("click", () => {
|
|
555
643
|
void this.toggleFullscreen();
|
|
556
644
|
});
|
|
557
645
|
this.fullscreenChangeHandler = () => {
|
|
646
|
+
this.fitWrap();
|
|
558
647
|
this.refreshFullscreenIcon();
|
|
559
648
|
this.syncRootToCanvas();
|
|
560
649
|
};
|
|
@@ -912,6 +1001,18 @@ var Controller = class _Controller {
|
|
|
912
1001
|
this.resizeObserver.disconnect();
|
|
913
1002
|
this.resizeObserver = null;
|
|
914
1003
|
}
|
|
1004
|
+
if (this.fitObserver) {
|
|
1005
|
+
this.fitObserver.disconnect();
|
|
1006
|
+
this.fitObserver = null;
|
|
1007
|
+
}
|
|
1008
|
+
if (this.fitWrapHandler) {
|
|
1009
|
+
window.removeEventListener("resize", this.fitWrapHandler);
|
|
1010
|
+
this.fitWrapHandler = null;
|
|
1011
|
+
}
|
|
1012
|
+
if (this.wrappedHere) {
|
|
1013
|
+
this.options.canvas.style.width = this.canvasInlineWidth;
|
|
1014
|
+
this.options.canvas.style.height = this.canvasInlineHeight;
|
|
1015
|
+
}
|
|
915
1016
|
this.root.remove();
|
|
916
1017
|
if (this.wrappedHere) {
|
|
917
1018
|
const parent = this.wrapper.parentElement;
|
|
@@ -960,6 +1061,6 @@ var Controller = class _Controller {
|
|
|
960
1061
|
}
|
|
961
1062
|
};
|
|
962
1063
|
|
|
963
|
-
export { Controller, extensionForMimeType, formatTime, frameToPercent, pxToFraction, pxToFrame };
|
|
1064
|
+
export { CONTROLLER_CSS, Controller, extensionForMimeType, formatTime, frameToPercent, pxToFraction, pxToFrame };
|
|
964
1065
|
//# sourceMappingURL=Controller.js.map
|
|
965
1066
|
//# sourceMappingURL=Controller.js.map
|