@editframe/elements 0.7.0-beta.8 → 0.7.0-beta.9

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.
Files changed (86) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.json +1 -1
  3. package/postcss.config.cjs +12 -0
  4. package/{dist/packages/elements/src/EF_FRAMEGEN.js → src/EF_FRAMEGEN.ts} +113 -32
  5. package/src/EF_INTERACTIVE.ts +2 -0
  6. package/src/elements.css +22 -0
  7. package/src/index.ts +33 -0
  8. package/tailwind.config.ts +10 -0
  9. package/tsconfig.json +4 -0
  10. package/vite.config.ts +8 -0
  11. package/dist/lib/av/EncodedAsset.cjs +0 -577
  12. package/dist/lib/av/EncodedAsset.js +0 -560
  13. package/dist/lib/av/MP4File.cjs +0 -187
  14. package/dist/lib/av/MP4File.js +0 -170
  15. package/dist/lib/av/msToTimeCode.cjs +0 -15
  16. package/dist/lib/av/msToTimeCode.js +0 -15
  17. package/dist/lib/util/awaitMicrotask.cjs +0 -4
  18. package/dist/lib/util/awaitMicrotask.js +0 -4
  19. package/dist/lib/util/memoize.cjs +0 -14
  20. package/dist/lib/util/memoize.js +0 -14
  21. package/dist/packages/elements/src/EF_FRAMEGEN.cjs +0 -197
  22. package/dist/packages/elements/src/EF_FRAMEGEN.d.ts +0 -44
  23. package/dist/packages/elements/src/EF_INTERACTIVE.cjs +0 -4
  24. package/dist/packages/elements/src/EF_INTERACTIVE.d.ts +0 -1
  25. package/dist/packages/elements/src/EF_INTERACTIVE.js +0 -4
  26. package/dist/packages/elements/src/elements/CrossUpdateController.cjs +0 -16
  27. package/dist/packages/elements/src/elements/CrossUpdateController.d.ts +0 -9
  28. package/dist/packages/elements/src/elements/CrossUpdateController.js +0 -16
  29. package/dist/packages/elements/src/elements/EFAudio.cjs +0 -53
  30. package/dist/packages/elements/src/elements/EFAudio.d.ts +0 -10
  31. package/dist/packages/elements/src/elements/EFAudio.js +0 -54
  32. package/dist/packages/elements/src/elements/EFCaptions.cjs +0 -164
  33. package/dist/packages/elements/src/elements/EFCaptions.d.ts +0 -38
  34. package/dist/packages/elements/src/elements/EFCaptions.js +0 -166
  35. package/dist/packages/elements/src/elements/EFImage.cjs +0 -79
  36. package/dist/packages/elements/src/elements/EFImage.d.ts +0 -14
  37. package/dist/packages/elements/src/elements/EFImage.js +0 -80
  38. package/dist/packages/elements/src/elements/EFMedia.cjs +0 -336
  39. package/dist/packages/elements/src/elements/EFMedia.d.ts +0 -61
  40. package/dist/packages/elements/src/elements/EFMedia.js +0 -336
  41. package/dist/packages/elements/src/elements/EFSourceMixin.cjs +0 -55
  42. package/dist/packages/elements/src/elements/EFSourceMixin.d.ts +0 -12
  43. package/dist/packages/elements/src/elements/EFSourceMixin.js +0 -55
  44. package/dist/packages/elements/src/elements/EFTemporal.cjs +0 -199
  45. package/dist/packages/elements/src/elements/EFTemporal.d.ts +0 -38
  46. package/dist/packages/elements/src/elements/EFTemporal.js +0 -199
  47. package/dist/packages/elements/src/elements/EFTimegroup.browsertest.d.ts +0 -12
  48. package/dist/packages/elements/src/elements/EFTimegroup.cjs +0 -352
  49. package/dist/packages/elements/src/elements/EFTimegroup.d.ts +0 -39
  50. package/dist/packages/elements/src/elements/EFTimegroup.js +0 -353
  51. package/dist/packages/elements/src/elements/EFVideo.cjs +0 -109
  52. package/dist/packages/elements/src/elements/EFVideo.d.ts +0 -14
  53. package/dist/packages/elements/src/elements/EFVideo.js +0 -110
  54. package/dist/packages/elements/src/elements/EFWaveform.cjs +0 -242
  55. package/dist/packages/elements/src/elements/EFWaveform.d.ts +0 -30
  56. package/dist/packages/elements/src/elements/EFWaveform.js +0 -226
  57. package/dist/packages/elements/src/elements/FetchMixin.cjs +0 -28
  58. package/dist/packages/elements/src/elements/FetchMixin.d.ts +0 -8
  59. package/dist/packages/elements/src/elements/FetchMixin.js +0 -28
  60. package/dist/packages/elements/src/elements/TimegroupController.cjs +0 -20
  61. package/dist/packages/elements/src/elements/TimegroupController.d.ts +0 -14
  62. package/dist/packages/elements/src/elements/TimegroupController.js +0 -20
  63. package/dist/packages/elements/src/elements/durationConverter.cjs +0 -8
  64. package/dist/packages/elements/src/elements/durationConverter.d.ts +0 -4
  65. package/dist/packages/elements/src/elements/durationConverter.js +0 -8
  66. package/dist/packages/elements/src/elements/parseTimeToMs.cjs +0 -12
  67. package/dist/packages/elements/src/elements/parseTimeToMs.d.ts +0 -1
  68. package/dist/packages/elements/src/elements/parseTimeToMs.js +0 -12
  69. package/dist/packages/elements/src/elements/util.cjs +0 -11
  70. package/dist/packages/elements/src/elements/util.d.ts +0 -4
  71. package/dist/packages/elements/src/elements/util.js +0 -11
  72. package/dist/packages/elements/src/gui/EFFilmstrip.cjs +0 -825
  73. package/dist/packages/elements/src/gui/EFFilmstrip.d.ts +0 -147
  74. package/dist/packages/elements/src/gui/EFFilmstrip.js +0 -833
  75. package/dist/packages/elements/src/gui/EFWorkbench.cjs +0 -214
  76. package/dist/packages/elements/src/gui/EFWorkbench.d.ts +0 -45
  77. package/dist/packages/elements/src/gui/EFWorkbench.js +0 -215
  78. package/dist/packages/elements/src/gui/TWMixin.cjs +0 -28
  79. package/dist/packages/elements/src/gui/TWMixin.css.cjs +0 -3
  80. package/dist/packages/elements/src/gui/TWMixin.css.js +0 -4
  81. package/dist/packages/elements/src/gui/TWMixin.d.ts +0 -3
  82. package/dist/packages/elements/src/gui/TWMixin.js +0 -28
  83. package/dist/packages/elements/src/index.cjs +0 -50
  84. package/dist/packages/elements/src/index.d.ts +0 -10
  85. package/dist/packages/elements/src/index.js +0 -23
  86. package/dist/style.css +0 -791
@@ -1,825 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const EFTimegroup = require("../elements/EFTimegroup.cjs");
4
- const lit = require("lit");
5
- const decorators_js = require("lit/decorators.js");
6
- const styleMap_js = require("lit/directives/style-map.js");
7
- const ref_js = require("lit/directives/ref.js");
8
- const EFImage = require("../elements/EFImage.cjs");
9
- const EFAudio = require("../elements/EFAudio.cjs");
10
- const EFVideo = require("../elements/EFVideo.cjs");
11
- const EFCaptions = require("../elements/EFCaptions.cjs");
12
- const EFWaveform = require("../elements/EFWaveform.cjs");
13
- const TimegroupController = require("../elements/TimegroupController.cjs");
14
- const context = require("@lit/context");
15
- const EFWorkbench = require("./EFWorkbench.cjs");
16
- const TWMixin = require("./TWMixin.cjs");
17
- const msToTimeCode = require("../../../../lib/av/msToTimeCode.cjs");
18
- var __defProp = Object.defineProperty;
19
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
20
- var __typeError = (msg) => {
21
- throw TypeError(msg);
22
- };
23
- var __decorateClass = (decorators, target, key, kind) => {
24
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
25
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
26
- if (decorator = decorators[i])
27
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
28
- if (kind && result) __defProp(target, key, result);
29
- return result;
30
- };
31
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
32
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), member.get(obj));
33
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
34
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
35
- var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
36
- var _EFFilmstrip_instances, bindToTargetTimegroup_fn, _handleKeyPress, _lastTick, _playbackAudioContext, _playbackAnimationFrameRequest, _AUDIO_PLAYBACK_SLICE_MS, syncPlayheadToAudioContext_fn, stopPlayback_fn, startPlayback_fn;
37
- class ElementFilmstripController {
38
- constructor(host, filmstrip) {
39
- this.host = host;
40
- this.filmstrip = filmstrip;
41
- this.host.addController(this);
42
- }
43
- remove() {
44
- this.host.removeController(this);
45
- }
46
- hostDisconnected() {
47
- this.host.removeController(this);
48
- }
49
- hostUpdated() {
50
- this.filmstrip.requestUpdate();
51
- }
52
- }
53
- const CommonEffectKeys = /* @__PURE__ */ new Set([
54
- "offset",
55
- "easing",
56
- "composite",
57
- "computedOffset"
58
- ]);
59
- class FilmstripItem extends TWMixin.TWMixin(lit.LitElement) {
60
- constructor() {
61
- super(...arguments);
62
- this.element = new EFTimegroup.EFTimegroup();
63
- this.pixelsPerMs = 0.04;
64
- }
65
- static {
66
- this.styles = [
67
- lit.css`
68
- :host {
69
- display: block;
70
- }
71
- `
72
- ];
73
- }
74
- get isFocused() {
75
- return this.element && this.focusContext?.focusedElement === this.element;
76
- }
77
- get styles() {
78
- return {
79
- position: "relative",
80
- left: `${this.pixelsPerMs * this.element.startTimeWithinParentMs}px`,
81
- width: `${this.pixelsPerMs * this.element.durationMs}px`
82
- };
83
- }
84
- render() {
85
- return lit.html` <div class="" style=${styleMap_js.styleMap(this.styles)}>
86
- <div
87
- class="border-outset relative mb-[1px] block h-[1.1rem] text-nowrap border border-slate-500 bg-blue-200 hover:bg-blue-400 text-sm data-[focused]:bg-slate-400"
88
- ?data-focused=${this.isFocused}
89
- @mouseenter=${() => {
90
- if (this.focusContext) {
91
- this.focusContext.focusedElement = this.element;
92
- }
93
- }}
94
- @mouseleave=${() => {
95
- if (this.focusContext) {
96
- this.focusContext.focusedElement = null;
97
- }
98
- }}
99
- >
100
- ${this.animations()}
101
- </div>
102
- ${this.renderChildren()}
103
- </div>`;
104
- }
105
- renderChildren() {
106
- return renderFilmstripChildren(
107
- Array.from(this.element.children),
108
- this.pixelsPerMs
109
- );
110
- }
111
- contents() {
112
- return lit.html``;
113
- }
114
- animations() {
115
- const animations = this.element.getAnimations();
116
- return animations.map((animation) => {
117
- const effect = animation.effect;
118
- if (!(effect instanceof KeyframeEffect)) {
119
- return lit.nothing;
120
- }
121
- const start = effect.getTiming().delay ?? 0;
122
- const duration = effect.getTiming().duration;
123
- if (duration === null) {
124
- return lit.nothing;
125
- }
126
- const keyframes = effect.getKeyframes();
127
- const firstKeyframe = keyframes[0];
128
- if (!firstKeyframe) {
129
- return lit.nothing;
130
- }
131
- const properties = new Set(Object.keys(firstKeyframe));
132
- for (const key of CommonEffectKeys) {
133
- properties.delete(key);
134
- }
135
- return lit.html`<div
136
- class="relative h-[5px] bg-blue-500 opacity-50"
137
- label="animation"
138
- style=${styleMap_js.styleMap({
139
- left: `${this.pixelsPerMs * start}px`,
140
- width: `${this.pixelsPerMs * Number(duration)}px`
141
- })}
142
- >
143
- <!-- <div class="text-nowrap">${Array.from(properties).join(" ")}</div> -->
144
- ${effect.getKeyframes().map((keyframe) => {
145
- return lit.html`<div
146
- class="absolute top-0 h-full w-1 bg-red-500"
147
- style=${styleMap_js.styleMap({
148
- left: `${this.pixelsPerMs * keyframe.computedOffset * Number(duration)}px`
149
- })}
150
- ></div>`;
151
- })}
152
- </div>`;
153
- });
154
- }
155
- update(changedProperties) {
156
- if (changedProperties.has("element") && this.element instanceof lit.LitElement) {
157
- this.filmstripController?.remove();
158
- this.filmstripController = new ElementFilmstripController(
159
- this.element,
160
- this
161
- );
162
- }
163
- super.update(changedProperties);
164
- }
165
- }
166
- __decorateClass([
167
- context.consume({ context: EFWorkbench.focusContext, subscribe: true })
168
- ], FilmstripItem.prototype, "focusContext", 2);
169
- __decorateClass([
170
- context.consume({ context: EFWorkbench.focusedElement, subscribe: true })
171
- ], FilmstripItem.prototype, "focusedElement", 2);
172
- __decorateClass([
173
- decorators_js.property({ type: HTMLElement, attribute: false })
174
- ], FilmstripItem.prototype, "element", 2);
175
- __decorateClass([
176
- decorators_js.property({ type: Number })
177
- ], FilmstripItem.prototype, "pixelsPerMs", 2);
178
- exports.EFAudioFilmstrip = class EFAudioFilmstrip extends FilmstripItem {
179
- contents() {
180
- return lit.html``;
181
- }
182
- };
183
- exports.EFAudioFilmstrip = __decorateClass([
184
- decorators_js.customElement("ef-audio-filmstrip")
185
- ], exports.EFAudioFilmstrip);
186
- exports.EFVideoFilmstrip = class EFVideoFilmstrip extends FilmstripItem {
187
- contents() {
188
- return lit.html` 📼 `;
189
- }
190
- };
191
- exports.EFVideoFilmstrip = __decorateClass([
192
- decorators_js.customElement("ef-video-filmstrip")
193
- ], exports.EFVideoFilmstrip);
194
- exports.EFCaptionsFilmstrip = class EFCaptionsFilmstrip extends FilmstripItem {
195
- contents() {
196
- return lit.html` 📝 `;
197
- }
198
- };
199
- exports.EFCaptionsFilmstrip = __decorateClass([
200
- decorators_js.customElement("ef-captions-filmstrip")
201
- ], exports.EFCaptionsFilmstrip);
202
- exports.EFWaveformFilmstrip = class EFWaveformFilmstrip extends FilmstripItem {
203
- contents() {
204
- return lit.html` 🌊 `;
205
- }
206
- renderChildren() {
207
- return lit.nothing;
208
- }
209
- };
210
- exports.EFWaveformFilmstrip = __decorateClass([
211
- decorators_js.customElement("ef-waveform-filmstrip")
212
- ], exports.EFWaveformFilmstrip);
213
- exports.EFImageFilmstrip = class EFImageFilmstrip extends FilmstripItem {
214
- contents() {
215
- return lit.html` 🖼️ `;
216
- }
217
- };
218
- exports.EFImageFilmstrip = __decorateClass([
219
- decorators_js.customElement("ef-image-filmstrip")
220
- ], exports.EFImageFilmstrip);
221
- exports.EFTimegroupFilmstrip = class EFTimegroupFilmstrip extends FilmstripItem {
222
- contents() {
223
- return lit.html`
224
- <span>TIME GROUP</span>
225
- ${renderFilmstripChildren(
226
- Array.from(this.element.children || []),
227
- this.pixelsPerMs
228
- )}
229
- </div>
230
- `;
231
- }
232
- };
233
- exports.EFTimegroupFilmstrip = __decorateClass([
234
- decorators_js.customElement("ef-timegroup-filmstrip")
235
- ], exports.EFTimegroupFilmstrip);
236
- exports.EFHTMLFilmstrip = class EFHTMLFilmstrip extends FilmstripItem {
237
- contents() {
238
- return lit.html`
239
- <span>${this.element.tagName}</span>
240
- ${renderFilmstripChildren(
241
- Array.from(this.element.children || []),
242
- this.pixelsPerMs
243
- )}
244
- `;
245
- }
246
- };
247
- exports.EFHTMLFilmstrip = __decorateClass([
248
- decorators_js.customElement("ef-html-filmstrip")
249
- ], exports.EFHTMLFilmstrip);
250
- let EFHierarchyItem = class extends TWMixin.TWMixin(lit.LitElement) {
251
- constructor() {
252
- super(...arguments);
253
- this.element = new EFTimegroup.EFTimegroup();
254
- }
255
- get icon() {
256
- return "📼";
257
- }
258
- get isFocused() {
259
- return this.element && this.focusContext?.focusedElement === this.element;
260
- }
261
- displayLabel() {
262
- return lit.nothing;
263
- }
264
- render() {
265
- return lit.html`
266
- <div>
267
- <div
268
- class="peer
269
- flex h-[1.1rem] items-center overflow-hidden text-nowrap border border-slate-500
270
- bg-slate-200 pl-2 text-xs font-mono hover:bg-slate-400 data-[focused]:bg-slate-400"
271
- ?data-focused=${this.isFocused}
272
- @mouseenter=${() => {
273
- if (this.focusContext) {
274
- this.focusContext.focusedElement = this.element;
275
- }
276
- }}
277
- @mouseleave=${() => {
278
- if (this.focusContext) {
279
- this.focusContext.focusedElement = null;
280
- }
281
- }}
282
- >
283
- ${this.icon} ${this.displayLabel()}
284
- </div>
285
- <div
286
- class="p-[1px] pb-0 pl-2 pr-0 peer-hover:bg-slate-300 peer-data-[focused]:bg-slate-300 peer-hover:border-slate-400 peer-data-[focused]:border-slate-400""
287
- >
288
- ${this.renderChildren()}
289
- </div>
290
- </div>`;
291
- }
292
- renderChildren() {
293
- return renderHierarchyChildren(Array.from(this.element.children));
294
- }
295
- };
296
- __decorateClass([
297
- decorators_js.property({ type: HTMLElement, attribute: false })
298
- ], EFHierarchyItem.prototype, "element", 2);
299
- __decorateClass([
300
- context.consume({ context: EFWorkbench.focusContext })
301
- ], EFHierarchyItem.prototype, "focusContext", 2);
302
- __decorateClass([
303
- context.consume({ context: EFWorkbench.focusedElement, subscribe: true })
304
- ], EFHierarchyItem.prototype, "focusedElement", 2);
305
- EFHierarchyItem = __decorateClass([
306
- decorators_js.customElement("ef-hierarchy-item")
307
- ], EFHierarchyItem);
308
- let EFTimegroupHierarchyItem = class extends EFHierarchyItem {
309
- get icon() {
310
- return "🕒";
311
- }
312
- displayLabel() {
313
- return this.element.mode ?? "(no mode)";
314
- }
315
- };
316
- EFTimegroupHierarchyItem = __decorateClass([
317
- decorators_js.customElement("ef-timegroup-hierarchy-item")
318
- ], EFTimegroupHierarchyItem);
319
- let EFAudioHierarchyItem = class extends EFHierarchyItem {
320
- get icon() {
321
- return "🔊";
322
- }
323
- displayLabel() {
324
- return this.element.src ?? "(no src)";
325
- }
326
- };
327
- EFAudioHierarchyItem = __decorateClass([
328
- decorators_js.customElement("ef-audio-hierarchy-item")
329
- ], EFAudioHierarchyItem);
330
- let EFVideoHierarchyItem = class extends EFHierarchyItem {
331
- get icon() {
332
- return "📼";
333
- }
334
- displayLabel() {
335
- return this.element.src ?? "(no src)";
336
- }
337
- };
338
- EFVideoHierarchyItem = __decorateClass([
339
- decorators_js.customElement("ef-video-hierarchy-item")
340
- ], EFVideoHierarchyItem);
341
- let EFCaptionsHierarchyItem = class extends EFHierarchyItem {
342
- get icon() {
343
- return "📝 Captions";
344
- }
345
- };
346
- EFCaptionsHierarchyItem = __decorateClass([
347
- decorators_js.customElement("ef-captions-hierarchy-item")
348
- ], EFCaptionsHierarchyItem);
349
- let EFCaptionsActiveWordHierarchyItem = class extends EFHierarchyItem {
350
- get icon() {
351
- return "🗣️ Active Word";
352
- }
353
- };
354
- EFCaptionsActiveWordHierarchyItem = __decorateClass([
355
- decorators_js.customElement("ef-captions-active-word-hierarchy-item")
356
- ], EFCaptionsActiveWordHierarchyItem);
357
- let EFWaveformHierarchyItem = class extends EFHierarchyItem {
358
- get icon() {
359
- return "🌊";
360
- }
361
- renderChildren() {
362
- return lit.nothing;
363
- }
364
- };
365
- EFWaveformHierarchyItem = __decorateClass([
366
- decorators_js.customElement("ef-waveform-hierarchy-item")
367
- ], EFWaveformHierarchyItem);
368
- let EFImageHierarchyItem = class extends EFHierarchyItem {
369
- get icon() {
370
- return "🖼️";
371
- }
372
- displayLabel() {
373
- return this.element.src ?? "(no src)";
374
- }
375
- };
376
- EFImageHierarchyItem = __decorateClass([
377
- decorators_js.customElement("ef-image-hierarchy-item")
378
- ], EFImageHierarchyItem);
379
- let EFHTMLHierarchyItem = class extends EFHierarchyItem {
380
- get icon() {
381
- return lit.html`<code>${`<${this.element.tagName.toLowerCase()}>`}</code>`;
382
- }
383
- };
384
- EFHTMLHierarchyItem = __decorateClass([
385
- decorators_js.customElement("ef-html-hierarchy-item")
386
- ], EFHTMLHierarchyItem);
387
- const renderHierarchyChildren = (children) => {
388
- return children.map((child) => {
389
- if (child instanceof EFTimegroup.EFTimegroup) {
390
- return lit.html`<ef-timegroup-hierarchy-item
391
- .element=${child}
392
- ></ef-timegroup-hierarchy-item>`;
393
- }
394
- if (child instanceof EFImage.EFImage) {
395
- return lit.html`<ef-image-hierarchy-item
396
- .element=${child}
397
- ></ef-image-hierarchy-item>`;
398
- }
399
- if (child instanceof EFAudio.EFAudio) {
400
- return lit.html`<ef-audio-hierarchy-item
401
- .element=${child}
402
- ></ef-audio-hierarchy-item>`;
403
- }
404
- if (child instanceof EFVideo.EFVideo) {
405
- return lit.html`<ef-video-hierarchy-item
406
- .element=${child}
407
- ></ef-video-hierarchy-item>`;
408
- }
409
- if (child instanceof EFCaptions.EFCaptions) {
410
- return lit.html`<ef-captions-hierarchy-item
411
- .element=${child}
412
- ></ef-captions-hierarchy-item>`;
413
- }
414
- if (child instanceof EFCaptions.EFCaptionsActiveWord) {
415
- return lit.html`<ef-captions-active-word-hierarchy-item
416
- .element=${child}
417
- ></ef-captions-active-word-hierarchy-item>`;
418
- }
419
- if (child instanceof EFWaveform.EFWaveform) {
420
- return lit.html`<ef-waveform-hierarchy-item
421
- .element=${child}
422
- ></ef-waveform-hierarchy-item>`;
423
- }
424
- return lit.html`<ef-html-hierarchy-item
425
- .element=${child}
426
- ></ef-html-hierarchy-item>`;
427
- });
428
- };
429
- const renderFilmstripChildren = (children, pixelsPerMs) => {
430
- return children.map((child) => {
431
- if (child instanceof EFTimegroup.EFTimegroup) {
432
- return lit.html`<ef-timegroup-filmstrip
433
- .element=${child}
434
- .pixelsPerMs=${pixelsPerMs}
435
- >
436
- </ef-timegroup-filmstrip>`;
437
- }
438
- if (child instanceof EFImage.EFImage) {
439
- return lit.html`<ef-image-filmstrip
440
- .element=${child}
441
- .pixelsPerMs=${pixelsPerMs}
442
- ></ef-image-filmstrip>`;
443
- }
444
- if (child instanceof EFAudio.EFAudio) {
445
- return lit.html`<ef-audio-filmstrip
446
- .element=${child}
447
- .pixelsPerMs=${pixelsPerMs}
448
- ></ef-audio-filmstrip>`;
449
- }
450
- if (child instanceof EFVideo.EFVideo) {
451
- return lit.html`<ef-video-filmstrip
452
- .element=${child}
453
- .pixelsPerMs=${pixelsPerMs}
454
- ></ef-video-filmstrip>`;
455
- }
456
- if (child instanceof EFCaptions.EFCaptions) {
457
- return lit.html`<ef-captions-filmstrip
458
- .element=${child}
459
- .pixelsPerMs=${pixelsPerMs}
460
- ></ef-captions-filmstrip>`;
461
- }
462
- if (child instanceof EFWaveform.EFWaveform) {
463
- return lit.html`<ef-waveform-filmstrip
464
- .element=${child}
465
- .pixelsPerMs=${pixelsPerMs}
466
- ></ef-waveform-filmstrip>`;
467
- }
468
- return lit.html`<ef-html-filmstrip
469
- .element=${child}
470
- .pixelsPerMs=${pixelsPerMs}
471
- ></ef-html-filmstrip>`;
472
- });
473
- };
474
- exports.EFFilmstrip = class EFFilmstrip extends TWMixin.TWMixin(lit.LitElement) {
475
- constructor() {
476
- super(...arguments);
477
- __privateAdd(this, _EFFilmstrip_instances);
478
- this.pixelsPerMs = 0.04;
479
- this.currentTimeMs = 0;
480
- this.targetSelector = "";
481
- this.scrubbing = false;
482
- this.playing = false;
483
- this.timelineScrolltop = 0;
484
- __privateAdd(this, _handleKeyPress, (event) => {
485
- if (event.key === " ") {
486
- const interactiveSelector = "input, textarea, button, select, a, [contenteditable]";
487
- const closestInteractive = event.target?.closest(
488
- interactiveSelector
489
- );
490
- if (closestInteractive) {
491
- return;
492
- }
493
- event.preventDefault();
494
- this.playing = !this.playing;
495
- }
496
- });
497
- __privateAdd(this, _lastTick);
498
- __privateAdd(this, _playbackAudioContext, null);
499
- __privateAdd(this, _playbackAnimationFrameRequest, null);
500
- __privateAdd(this, _AUDIO_PLAYBACK_SLICE_MS, 1e3);
501
- this.advancePlayhead = (tick) => {
502
- if (__privateGet(this, _lastTick) && tick && this.targetTimegroup) {
503
- this.targetTimegroup.currentTimeMs += tick - __privateGet(this, _lastTick);
504
- if (this.targetTimegroup.currentTimeMs >= this.targetTimegroup.durationMs) {
505
- this.playing = false;
506
- }
507
- }
508
- __privateSet(this, _lastTick, tick);
509
- if (this.playing) {
510
- requestAnimationFrame(this.advancePlayhead);
511
- }
512
- };
513
- this.gutterRef = ref_js.createRef();
514
- this.hierarchyRef = ref_js.createRef();
515
- this.playheadRef = ref_js.createRef();
516
- }
517
- connectedCallback() {
518
- super.connectedCallback();
519
- __privateMethod(this, _EFFilmstrip_instances, bindToTargetTimegroup_fn).call(this);
520
- window.addEventListener("keypress", __privateGet(this, _handleKeyPress));
521
- }
522
- disconnectedCallback() {
523
- super.disconnectedCallback();
524
- window.removeEventListener("keypress", __privateGet(this, _handleKeyPress));
525
- }
526
- syncGutterScroll() {
527
- if (this.gutter && this.hierarchyRef.value) {
528
- this.hierarchyRef.value.scrollTop = this.gutter.scrollTop;
529
- this.timelineScrolltop = this.gutter.scrollTop;
530
- }
531
- }
532
- syncHierarchyScroll() {
533
- if (this.gutter && this.hierarchyRef.value) {
534
- this.gutter.scrollTop = this.hierarchyRef.value.scrollTop;
535
- this.timelineScrolltop = this.hierarchyRef.value.scrollTop;
536
- }
537
- }
538
- scrub(e) {
539
- if (this.playing) {
540
- return;
541
- }
542
- if (!this.scrubbing) {
543
- return;
544
- }
545
- const gutter = this.shadowRoot?.querySelector("#gutter");
546
- if (!gutter) {
547
- return;
548
- }
549
- const rect = gutter.getBoundingClientRect();
550
- if (this.targetTimegroup) {
551
- const layerX = e.pageX - rect.left + gutter.scrollLeft;
552
- this.targetTimegroup.currentTimeMs = layerX / this.pixelsPerMs;
553
- }
554
- }
555
- startScrub(e) {
556
- e.preventDefault();
557
- this.scrubbing = true;
558
- queueMicrotask(() => {
559
- const gutter = this.shadowRoot?.querySelector("#gutter");
560
- if (!gutter) {
561
- return;
562
- }
563
- const rect = gutter.getBoundingClientRect();
564
- if (this.targetTimegroup) {
565
- const layerX = e.pageX - rect.left + gutter.scrollLeft;
566
- this.targetTimegroup.currentTimeMs = layerX / this.pixelsPerMs;
567
- }
568
- });
569
- addEventListener(
570
- "mouseup",
571
- () => {
572
- this.scrubbing = false;
573
- },
574
- { once: true }
575
- );
576
- }
577
- scrollScrub(e) {
578
- if (this.targetTimegroup && this.gutter && !this.playing) {
579
- e.preventDefault();
580
- if (this.gutterRef.value && this.gutterRef.value.scrollLeft === 0 && e.deltaX < 0) {
581
- this.gutter.scrollBy(0, e.deltaY);
582
- return;
583
- }
584
- if (this.gutter.scrollWidth - this.gutter.scrollLeft === this.gutter.clientWidth && e.deltaX > 0) {
585
- this.gutter.scrollBy(0, e.deltaY);
586
- return;
587
- }
588
- if (this) {
589
- this.gutter.scrollBy(e.deltaX, e.deltaY);
590
- this.targetTimegroup.currentTimeMs += e.deltaX / this.pixelsPerMs;
591
- }
592
- }
593
- }
594
- get gutter() {
595
- return this.gutterRef.value;
596
- }
597
- render() {
598
- const target = this.targetTimegroup;
599
- return lit.html` <div
600
- class="grid h-full bg-slate-100"
601
- style=${styleMap_js.styleMap({
602
- gridTemplateColumns: "200px 1fr",
603
- gridTemplateRows: "1.5rem 1fr"
604
- })}
605
- >
606
- <div
607
- class="z-20 col-span-2 border-b-slate-600 bg-slate-100 shadow shadow-slate-300"
608
- >
609
- <input
610
- type="range"
611
- .value=${this.pixelsPerMs}
612
- min="0.01"
613
- max="0.1"
614
- step="0.001"
615
- @input=${(e) => {
616
- const target2 = e.target;
617
- this.pixelsPerMs = Number.parseFloat(target2.value);
618
- }}
619
- />
620
- <code>${msToTimeCode.msToTimeCode(this.currentTimeMs, true)} </code> /
621
- <code>${msToTimeCode.msToTimeCode(target?.durationMs ?? 0, true)}</code>
622
- ${this.playing ? lit.html`<button
623
- @click=${() => {
624
- this.playing = false;
625
- }}
626
- >
627
- ⏸️
628
- </button>` : lit.html`<button
629
- @click=${() => {
630
- this.playing = true;
631
- }}
632
- >
633
- ▶️
634
- </button>`}
635
- </div>
636
- <div
637
- class="z-10 pl-1 pr-1 pt-2 shadow shadow-slate-600 overflow-auto"
638
- ${ref_js.ref(this.hierarchyRef)}
639
- @scroll=${this.syncHierarchyScroll}
640
- >
641
- ${renderHierarchyChildren(target ? [target] : [])}
642
- </div>
643
- <div
644
- class="h-full w-full cursor-crosshair overflow-auto bg-slate-200 pt-2"
645
- id="gutter"
646
- ${ref_js.ref(this.gutterRef)}
647
- @scroll=${this.syncGutterScroll}
648
- @wheel=${this.scrollScrub}
649
- >
650
- <div
651
- class="relative h-full w-full"
652
- style="width: ${this.pixelsPerMs * (target?.durationMs ?? 0)}px;"
653
- @mousemove=${this.scrub}
654
- @mousedown=${this.startScrub}
655
- >
656
- <div
657
- class="border-red pointer-events-none absolute z-10 h-full w-[2px] border-r-2 border-red-700"
658
- style=${styleMap_js.styleMap({
659
- left: `${this.pixelsPerMs * this.currentTimeMs}px`,
660
- top: `${this.timelineScrolltop}px`
661
- })}
662
- ${ref_js.ref(this.playheadRef)}
663
- ></div>
664
-
665
- ${renderFilmstripChildren(target ? [target] : [], this.pixelsPerMs)}
666
- </div>
667
- </div>
668
- </div>`;
669
- }
670
- update(changedProperties) {
671
- if (changedProperties.has("playing")) {
672
- if (this.playing) {
673
- __privateMethod(this, _EFFilmstrip_instances, startPlayback_fn).call(this);
674
- } else {
675
- __privateMethod(this, _EFFilmstrip_instances, stopPlayback_fn).call(this);
676
- }
677
- }
678
- super.update(changedProperties);
679
- }
680
- updated(changes) {
681
- if (!this.targetTimegroup) {
682
- return;
683
- }
684
- if (changes.has("currentTimeMs")) {
685
- if (this.targetTimegroup.currentTimeMs !== this.currentTimeMs) {
686
- this.targetTimegroup.currentTimeMs = this.currentTimeMs;
687
- }
688
- }
689
- if (changes.has("target")) {
690
- __privateMethod(this, _EFFilmstrip_instances, bindToTargetTimegroup_fn).call(this);
691
- }
692
- }
693
- get targetTimegroup() {
694
- if (this.getAttribute("target")) {
695
- const target = document.getElementById(this.getAttribute("target") ?? "");
696
- if (target instanceof EFTimegroup.EFTimegroup) {
697
- return target;
698
- }
699
- }
700
- return void 0;
701
- }
702
- };
703
- _EFFilmstrip_instances = /* @__PURE__ */ new WeakSet();
704
- bindToTargetTimegroup_fn = function() {
705
- if (this.timegroupController) {
706
- this.timegroupController.remove();
707
- }
708
- const target = this.targetTimegroup;
709
- if (target) {
710
- this.timegroupController = new TimegroupController.TimegroupController(target, this);
711
- this.currentTimeMs = target.currentTimeMs;
712
- }
713
- };
714
- _handleKeyPress = /* @__PURE__ */ new WeakMap();
715
- _lastTick = /* @__PURE__ */ new WeakMap();
716
- _playbackAudioContext = /* @__PURE__ */ new WeakMap();
717
- _playbackAnimationFrameRequest = /* @__PURE__ */ new WeakMap();
718
- _AUDIO_PLAYBACK_SLICE_MS = /* @__PURE__ */ new WeakMap();
719
- syncPlayheadToAudioContext_fn = function(target, startMs) {
720
- target.currentTimeMs = startMs + (__privateGet(this, _playbackAudioContext)?.currentTime ?? 0) * 1e3;
721
- __privateSet(this, _playbackAnimationFrameRequest, requestAnimationFrame(() => {
722
- __privateMethod(this, _EFFilmstrip_instances, syncPlayheadToAudioContext_fn).call(this, target, startMs);
723
- }));
724
- };
725
- stopPlayback_fn = async function() {
726
- if (__privateGet(this, _playbackAudioContext)) {
727
- if (__privateGet(this, _playbackAudioContext).state !== "closed") {
728
- await __privateGet(this, _playbackAudioContext).close();
729
- }
730
- }
731
- if (__privateGet(this, _playbackAnimationFrameRequest)) {
732
- cancelAnimationFrame(__privateGet(this, _playbackAnimationFrameRequest));
733
- }
734
- __privateSet(this, _playbackAudioContext, null);
735
- };
736
- startPlayback_fn = async function() {
737
- await __privateMethod(this, _EFFilmstrip_instances, stopPlayback_fn).call(this);
738
- const timegroup = this.targetTimegroup;
739
- if (!timegroup) {
740
- return;
741
- }
742
- let currentMs = timegroup.currentTimeMs;
743
- let bufferCount = 0;
744
- __privateSet(this, _playbackAudioContext, new AudioContext({
745
- latencyHint: "playback"
746
- }));
747
- if (__privateGet(this, _playbackAnimationFrameRequest)) {
748
- cancelAnimationFrame(__privateGet(this, _playbackAnimationFrameRequest));
749
- }
750
- __privateMethod(this, _EFFilmstrip_instances, syncPlayheadToAudioContext_fn).call(this, timegroup, currentMs);
751
- const playbackContext = __privateGet(this, _playbackAudioContext);
752
- await playbackContext.suspend();
753
- const fillBuffer = async () => {
754
- if (bufferCount > 1) {
755
- return;
756
- }
757
- const canFillBuffer = await queueBufferSource();
758
- if (canFillBuffer) {
759
- fillBuffer();
760
- }
761
- };
762
- const fromMs = currentMs;
763
- const toMs = timegroup.endTimeMs;
764
- const queueBufferSource = async () => {
765
- if (currentMs >= toMs) {
766
- return false;
767
- }
768
- const startMs = currentMs;
769
- const endMs = currentMs + __privateGet(this, _AUDIO_PLAYBACK_SLICE_MS);
770
- currentMs += __privateGet(this, _AUDIO_PLAYBACK_SLICE_MS);
771
- const audioBuffer = await timegroup.renderAudio(startMs, endMs);
772
- bufferCount++;
773
- const source = playbackContext.createBufferSource();
774
- source.buffer = audioBuffer;
775
- source.connect(playbackContext.destination);
776
- source.start((startMs - fromMs) / 1e3);
777
- source.onended = () => {
778
- bufferCount--;
779
- if (endMs >= toMs) {
780
- this.playing = false;
781
- } else {
782
- fillBuffer();
783
- }
784
- };
785
- return true;
786
- };
787
- await fillBuffer();
788
- await playbackContext.resume();
789
- };
790
- __decorateClass([
791
- decorators_js.property({ type: Number })
792
- ], exports.EFFilmstrip.prototype, "pixelsPerMs", 2);
793
- __decorateClass([
794
- decorators_js.property({ type: Number })
795
- ], exports.EFFilmstrip.prototype, "currentTimeMs", 2);
796
- __decorateClass([
797
- decorators_js.property({ type: String, attribute: "target", reflect: true })
798
- ], exports.EFFilmstrip.prototype, "targetSelector", 2);
799
- __decorateClass([
800
- decorators_js.state()
801
- ], exports.EFFilmstrip.prototype, "scrubbing", 2);
802
- __decorateClass([
803
- decorators_js.state()
804
- ], exports.EFFilmstrip.prototype, "playing", 2);
805
- __decorateClass([
806
- decorators_js.state()
807
- ], exports.EFFilmstrip.prototype, "timelineScrolltop", 2);
808
- __decorateClass([
809
- decorators_js.eventOptions({ passive: false })
810
- ], exports.EFFilmstrip.prototype, "syncGutterScroll", 1);
811
- __decorateClass([
812
- decorators_js.eventOptions({ passive: false })
813
- ], exports.EFFilmstrip.prototype, "syncHierarchyScroll", 1);
814
- __decorateClass([
815
- decorators_js.eventOptions({ capture: false })
816
- ], exports.EFFilmstrip.prototype, "scrub", 1);
817
- __decorateClass([
818
- decorators_js.eventOptions({ capture: false })
819
- ], exports.EFFilmstrip.prototype, "startScrub", 1);
820
- __decorateClass([
821
- decorators_js.eventOptions({ passive: false })
822
- ], exports.EFFilmstrip.prototype, "scrollScrub", 1);
823
- exports.EFFilmstrip = __decorateClass([
824
- decorators_js.customElement("ef-filmstrip")
825
- ], exports.EFFilmstrip);