@editframe/elements 0.6.0-beta.17 → 0.6.0-beta.19
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/package.json +2 -2
- package/src/elements/EFMedia.ts +1 -1
- package/src/elements/EFTimegroup.ts +14 -6
- package/src/gui/EFFilmstrip.ts +144 -30
- package/dist/lib/av/EncodedAsset.cjs +0 -567
- package/dist/lib/av/EncodedAsset.js +0 -550
- package/dist/lib/av/MP4File.cjs +0 -182
- package/dist/lib/av/MP4File.js +0 -165
- package/dist/lib/av/msToTimeCode.cjs +0 -15
- package/dist/lib/av/msToTimeCode.js +0 -15
- package/dist/lib/util/awaitMicrotask.cjs +0 -4
- package/dist/lib/util/awaitMicrotask.js +0 -4
- package/dist/lib/util/memoize.cjs +0 -14
- package/dist/lib/util/memoize.js +0 -14
- package/dist/packages/elements/src/EF_FRAMEGEN.cjs +0 -200
- package/dist/packages/elements/src/EF_FRAMEGEN.d.ts +0 -45
- package/dist/packages/elements/src/EF_FRAMEGEN.js +0 -200
- package/dist/packages/elements/src/EF_INTERACTIVE.cjs +0 -4
- package/dist/packages/elements/src/EF_INTERACTIVE.d.ts +0 -1
- package/dist/packages/elements/src/EF_INTERACTIVE.js +0 -4
- package/dist/packages/elements/src/elements/CrossUpdateController.cjs +0 -16
- package/dist/packages/elements/src/elements/CrossUpdateController.d.ts +0 -9
- package/dist/packages/elements/src/elements/CrossUpdateController.js +0 -16
- package/dist/packages/elements/src/elements/EFAudio.cjs +0 -53
- package/dist/packages/elements/src/elements/EFAudio.d.ts +0 -10
- package/dist/packages/elements/src/elements/EFAudio.js +0 -54
- package/dist/packages/elements/src/elements/EFCaptions.cjs +0 -164
- package/dist/packages/elements/src/elements/EFCaptions.d.ts +0 -38
- package/dist/packages/elements/src/elements/EFCaptions.js +0 -166
- package/dist/packages/elements/src/elements/EFImage.cjs +0 -79
- package/dist/packages/elements/src/elements/EFImage.d.ts +0 -14
- package/dist/packages/elements/src/elements/EFImage.js +0 -80
- package/dist/packages/elements/src/elements/EFMedia.cjs +0 -334
- package/dist/packages/elements/src/elements/EFMedia.d.ts +0 -61
- package/dist/packages/elements/src/elements/EFMedia.js +0 -334
- package/dist/packages/elements/src/elements/EFSourceMixin.cjs +0 -55
- package/dist/packages/elements/src/elements/EFSourceMixin.d.ts +0 -12
- package/dist/packages/elements/src/elements/EFSourceMixin.js +0 -55
- package/dist/packages/elements/src/elements/EFTemporal.cjs +0 -198
- package/dist/packages/elements/src/elements/EFTemporal.d.ts +0 -36
- package/dist/packages/elements/src/elements/EFTemporal.js +0 -198
- package/dist/packages/elements/src/elements/EFTimegroup.browsertest.d.ts +0 -12
- package/dist/packages/elements/src/elements/EFTimegroup.cjs +0 -343
- package/dist/packages/elements/src/elements/EFTimegroup.d.ts +0 -39
- package/dist/packages/elements/src/elements/EFTimegroup.js +0 -344
- package/dist/packages/elements/src/elements/EFTimeline.cjs +0 -15
- package/dist/packages/elements/src/elements/EFTimeline.d.ts +0 -3
- package/dist/packages/elements/src/elements/EFTimeline.js +0 -15
- package/dist/packages/elements/src/elements/EFVideo.cjs +0 -109
- package/dist/packages/elements/src/elements/EFVideo.d.ts +0 -14
- package/dist/packages/elements/src/elements/EFVideo.js +0 -110
- package/dist/packages/elements/src/elements/EFWaveform.cjs +0 -235
- package/dist/packages/elements/src/elements/EFWaveform.d.ts +0 -28
- package/dist/packages/elements/src/elements/EFWaveform.js +0 -219
- package/dist/packages/elements/src/elements/FetchMixin.cjs +0 -28
- package/dist/packages/elements/src/elements/FetchMixin.d.ts +0 -8
- package/dist/packages/elements/src/elements/FetchMixin.js +0 -28
- package/dist/packages/elements/src/elements/TimegroupController.cjs +0 -20
- package/dist/packages/elements/src/elements/TimegroupController.d.ts +0 -14
- package/dist/packages/elements/src/elements/TimegroupController.js +0 -20
- package/dist/packages/elements/src/elements/durationConverter.cjs +0 -8
- package/dist/packages/elements/src/elements/durationConverter.d.ts +0 -4
- package/dist/packages/elements/src/elements/durationConverter.js +0 -8
- package/dist/packages/elements/src/elements/parseTimeToMs.cjs +0 -12
- package/dist/packages/elements/src/elements/parseTimeToMs.d.ts +0 -1
- package/dist/packages/elements/src/elements/parseTimeToMs.js +0 -12
- package/dist/packages/elements/src/elements/util.cjs +0 -11
- package/dist/packages/elements/src/elements/util.d.ts +0 -4
- package/dist/packages/elements/src/elements/util.js +0 -11
- package/dist/packages/elements/src/gui/EFFilmstrip.cjs +0 -719
- package/dist/packages/elements/src/gui/EFFilmstrip.d.ts +0 -143
- package/dist/packages/elements/src/gui/EFFilmstrip.js +0 -727
- package/dist/packages/elements/src/gui/EFWorkbench.cjs +0 -213
- package/dist/packages/elements/src/gui/EFWorkbench.d.ts +0 -45
- package/dist/packages/elements/src/gui/EFWorkbench.js +0 -214
- package/dist/packages/elements/src/gui/TWMixin.cjs +0 -28
- package/dist/packages/elements/src/gui/TWMixin.css.cjs +0 -3
- package/dist/packages/elements/src/gui/TWMixin.css.js +0 -4
- package/dist/packages/elements/src/gui/TWMixin.d.ts +0 -3
- package/dist/packages/elements/src/gui/TWMixin.js +0 -28
- package/dist/packages/elements/src/index.cjs +0 -47
- package/dist/packages/elements/src/index.d.ts +0 -10
- package/dist/packages/elements/src/index.js +0 -23
- package/dist/style.css +0 -769
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/elements",
|
|
3
|
-
"version": "0.6.0-beta.
|
|
3
|
+
"version": "0.6.0-beta.19",
|
|
4
4
|
"description": "",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"author": "",
|
|
20
20
|
"license": "UNLICENSED",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@editframe/assets": "0.6.0-beta.
|
|
22
|
+
"@editframe/assets": "0.6.0-beta.19",
|
|
23
23
|
"@lit/context": "^1.1.1",
|
|
24
24
|
"@lit/task": "^1.0.0",
|
|
25
25
|
"d3": "^7.9.0",
|
package/src/elements/EFMedia.ts
CHANGED
|
@@ -52,7 +52,7 @@ export class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
52
52
|
if (this.src.startsWith("editframe://") || this.src.startsWith("http")) {
|
|
53
53
|
return `${this.src}/index`;
|
|
54
54
|
}
|
|
55
|
-
return `/@ef-track-fragment-index/${this.
|
|
55
|
+
return `/@ef-track-fragment-index/${this.src ?? ""}`;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
fragmentTrackPath(trackId: string) {
|
|
@@ -292,15 +292,14 @@ export class EFTimegroup extends EFTemporal(LitElement) {
|
|
|
292
292
|
);
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
async
|
|
295
|
+
async #addAudioToContext(
|
|
296
|
+
audioContext: AudioContext | OfflineAudioContext,
|
|
297
|
+
fromMs: number,
|
|
298
|
+
toMs: number,
|
|
299
|
+
) {
|
|
296
300
|
await this.waitForMediaDurations();
|
|
297
301
|
|
|
298
302
|
const durationMs = toMs - fromMs;
|
|
299
|
-
const audioContext = new OfflineAudioContext(
|
|
300
|
-
2,
|
|
301
|
-
Math.round((48000 * durationMs) / 1000),
|
|
302
|
-
48000,
|
|
303
|
-
);
|
|
304
303
|
|
|
305
304
|
await Promise.all(
|
|
306
305
|
deepGetMediaElements(this).map(async (mediaElement) => {
|
|
@@ -338,7 +337,16 @@ export class EFTimegroup extends EFTemporal(LitElement) {
|
|
|
338
337
|
);
|
|
339
338
|
}),
|
|
340
339
|
);
|
|
340
|
+
}
|
|
341
341
|
|
|
342
|
+
async renderAudio(fromMs: number, toMs: number) {
|
|
343
|
+
const durationMs = toMs - fromMs;
|
|
344
|
+
const audioContext = new OfflineAudioContext(
|
|
345
|
+
2,
|
|
346
|
+
Math.round((48000 * durationMs) / 1000),
|
|
347
|
+
48000,
|
|
348
|
+
);
|
|
349
|
+
await this.#addAudioToContext(audioContext, fromMs, toMs);
|
|
342
350
|
return await audioContext.startRendering();
|
|
343
351
|
}
|
|
344
352
|
|
package/src/gui/EFFilmstrip.ts
CHANGED
|
@@ -103,7 +103,7 @@ class FilmstripItem extends TWMixin(LitElement) {
|
|
|
103
103
|
}
|
|
104
104
|
}}
|
|
105
105
|
?data-focused=${this.isFocused}
|
|
106
|
-
class="border-outset relative mb-[1px] block h-[1.
|
|
106
|
+
class="border-outset relative mb-[1px] block h-[1.1rem] text-nowrap border border-slate-500 bg-blue-200 text-sm data-[focused]:bg-slate-400"
|
|
107
107
|
>
|
|
108
108
|
${this.animations()}
|
|
109
109
|
</div>
|
|
@@ -112,7 +112,7 @@ class FilmstripItem extends TWMixin(LitElement) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
renderChildren(): Array<TemplateResult<1> | typeof nothing> | typeof nothing {
|
|
115
|
-
return
|
|
115
|
+
return renderFilmstripChildren(
|
|
116
116
|
Array.from(this.element.children),
|
|
117
117
|
this.pixelsPerMs,
|
|
118
118
|
);
|
|
@@ -228,7 +228,7 @@ export class EFTimegroupFilmstrip extends FilmstripItem {
|
|
|
228
228
|
contents() {
|
|
229
229
|
return html`
|
|
230
230
|
<span>TIME GROUP</span>
|
|
231
|
-
${
|
|
231
|
+
${renderFilmstripChildren(
|
|
232
232
|
Array.from(this.element.children || []),
|
|
233
233
|
this.pixelsPerMs,
|
|
234
234
|
)}
|
|
@@ -242,7 +242,7 @@ export class EFHTMLFilmstrip extends FilmstripItem {
|
|
|
242
242
|
contents() {
|
|
243
243
|
return html`
|
|
244
244
|
<span>${this.element.tagName}</span>
|
|
245
|
-
${
|
|
245
|
+
${renderFilmstripChildren(
|
|
246
246
|
Array.from(this.element.children || []),
|
|
247
247
|
this.pixelsPerMs,
|
|
248
248
|
)}
|
|
@@ -282,8 +282,8 @@ class EFHierarchyItem<
|
|
|
282
282
|
<div
|
|
283
283
|
?data-focused=${this.isFocused}
|
|
284
284
|
class="peer
|
|
285
|
-
flex h-[1.
|
|
286
|
-
bg-slate-200 pl-2 text-
|
|
285
|
+
flex h-[1.1rem] items-center overflow-hidden text-nowrap border border-slate-500
|
|
286
|
+
bg-slate-200 pl-2 text-xs font-mono hover:bg-slate-400 data-[focused]:bg-slate-400"
|
|
287
287
|
@mouseenter=${() => {
|
|
288
288
|
if (this.focusContext) {
|
|
289
289
|
this.focusContext.focusedElement = this.element;
|
|
@@ -328,7 +328,7 @@ class EFAudioHierarchyItem extends EFHierarchyItem {
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
displayLabel() {
|
|
331
|
-
return this.element.
|
|
331
|
+
return this.element.src ?? "(no src)";
|
|
332
332
|
}
|
|
333
333
|
}
|
|
334
334
|
|
|
@@ -339,7 +339,7 @@ class EFVideoHierarchyItem extends EFHierarchyItem {
|
|
|
339
339
|
}
|
|
340
340
|
|
|
341
341
|
displayLabel() {
|
|
342
|
-
return this.element.
|
|
342
|
+
return this.element.src ?? "(no src)";
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
345
|
|
|
@@ -375,7 +375,7 @@ class EFImageHierarchyItem extends EFHierarchyItem {
|
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
displayLabel() {
|
|
378
|
-
return this.element.
|
|
378
|
+
return this.element.src ?? "(no src)";
|
|
379
379
|
}
|
|
380
380
|
}
|
|
381
381
|
|
|
@@ -431,7 +431,7 @@ const renderHierarchyChildren = (
|
|
|
431
431
|
});
|
|
432
432
|
};
|
|
433
433
|
|
|
434
|
-
const
|
|
434
|
+
const renderFilmstripChildren = (
|
|
435
435
|
children: Element[],
|
|
436
436
|
pixelsPerMs: number,
|
|
437
437
|
): Array<TemplateResult<1> | typeof nothing> => {
|
|
@@ -481,14 +481,14 @@ const renderFilmStripChildren = (
|
|
|
481
481
|
};
|
|
482
482
|
|
|
483
483
|
@customElement("ef-filmstrip")
|
|
484
|
-
export class
|
|
484
|
+
export class EFFilmstrip extends TWMixin(LitElement) {
|
|
485
485
|
@property({ type: Number })
|
|
486
486
|
pixelsPerMs = 0.04;
|
|
487
487
|
|
|
488
488
|
@property({ type: Number })
|
|
489
489
|
currentTimeMs = 0;
|
|
490
490
|
|
|
491
|
-
@property({ type: String, attribute: "target" })
|
|
491
|
+
@property({ type: String, attribute: "target", reflect: true })
|
|
492
492
|
targetSelector = "";
|
|
493
493
|
|
|
494
494
|
@state()
|
|
@@ -504,15 +504,41 @@ export class EFFilmStrip extends TWMixin(LitElement) {
|
|
|
504
504
|
|
|
505
505
|
connectedCallback(): void {
|
|
506
506
|
super.connectedCallback();
|
|
507
|
-
const target = this.
|
|
507
|
+
const target = this.targetTimegroup;
|
|
508
508
|
if (target) {
|
|
509
509
|
this.timegroupController = new TimegroupController(target, this);
|
|
510
510
|
// Set the current time to the last saved time to avoid a cycle
|
|
511
511
|
// where the filmstrip clobbers the time loaded from localStorage
|
|
512
512
|
this.currentTimeMs = target.currentTimeMs;
|
|
513
513
|
}
|
|
514
|
+
|
|
515
|
+
window.addEventListener("keypress", this.#handleKeyPress);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
disconnectedCallback(): void {
|
|
519
|
+
super.disconnectedCallback();
|
|
520
|
+
window.removeEventListener("keypress", this.#handleKeyPress);
|
|
514
521
|
}
|
|
515
522
|
|
|
523
|
+
#handleKeyPress = (event: KeyboardEvent) => {
|
|
524
|
+
// On spacebar, toggle playback
|
|
525
|
+
if (event.key === " ") {
|
|
526
|
+
// CSS selector to match all interactive elements
|
|
527
|
+
const interactiveSelector =
|
|
528
|
+
"input, textarea, button, select, a, [contenteditable]";
|
|
529
|
+
|
|
530
|
+
// Check if the event target or its ancestor matches an interactive element
|
|
531
|
+
const closestInteractive = (event.target as HTMLElement | null)?.closest(
|
|
532
|
+
interactiveSelector,
|
|
533
|
+
);
|
|
534
|
+
if (closestInteractive) {
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
event.preventDefault();
|
|
538
|
+
this.playing = !this.playing;
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
|
|
516
542
|
@eventOptions({ passive: false })
|
|
517
543
|
syncGutterScroll() {
|
|
518
544
|
if (this.gutter && this.hierarchyRef.value) {
|
|
@@ -531,10 +557,96 @@ export class EFFilmStrip extends TWMixin(LitElement) {
|
|
|
531
557
|
|
|
532
558
|
#lastTick?: DOMHighResTimeStamp;
|
|
533
559
|
|
|
560
|
+
#playbackAudioContext: AudioContext | null = null;
|
|
561
|
+
#playbackAnimationFrameRequest: number | null = null;
|
|
562
|
+
#AUDIO_PLAYBACK_SLICE_MS = 1000;
|
|
563
|
+
|
|
564
|
+
#syncPlayheadToAudioContext(target: EFTimegroup, startMs: number) {
|
|
565
|
+
target.currentTimeMs =
|
|
566
|
+
startMs + (this.#playbackAudioContext?.currentTime ?? 0) * 1000;
|
|
567
|
+
this.#playbackAnimationFrameRequest = requestAnimationFrame(() => {
|
|
568
|
+
this.#syncPlayheadToAudioContext(target, startMs);
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
async #stopPlayback() {
|
|
573
|
+
if (this.#playbackAudioContext) {
|
|
574
|
+
if (this.#playbackAudioContext.state !== "closed") {
|
|
575
|
+
await this.#playbackAudioContext.close();
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
if (this.#playbackAnimationFrameRequest) {
|
|
579
|
+
cancelAnimationFrame(this.#playbackAnimationFrameRequest);
|
|
580
|
+
}
|
|
581
|
+
this.#playbackAudioContext = null;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
async #startPlayback() {
|
|
585
|
+
await this.#stopPlayback();
|
|
586
|
+
const timegroup = this.targetTimegroup;
|
|
587
|
+
if (!timegroup) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
let currentMs = timegroup.currentTimeMs;
|
|
592
|
+
let bufferCount = 0;
|
|
593
|
+
this.#playbackAudioContext = new AudioContext({
|
|
594
|
+
latencyHint: "playback",
|
|
595
|
+
});
|
|
596
|
+
if (this.#playbackAnimationFrameRequest) {
|
|
597
|
+
cancelAnimationFrame(this.#playbackAnimationFrameRequest);
|
|
598
|
+
}
|
|
599
|
+
this.#syncPlayheadToAudioContext(timegroup, currentMs);
|
|
600
|
+
const playbackContext = this.#playbackAudioContext;
|
|
601
|
+
await playbackContext.suspend();
|
|
602
|
+
|
|
603
|
+
const fillBuffer = async () => {
|
|
604
|
+
if (bufferCount > 1) {
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
const canFillBuffer = await queueBufferSource();
|
|
608
|
+
if (canFillBuffer) {
|
|
609
|
+
fillBuffer();
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
const fromMs = currentMs;
|
|
614
|
+
const toMs = timegroup.endTimeMs;
|
|
615
|
+
|
|
616
|
+
const queueBufferSource = async () => {
|
|
617
|
+
if (currentMs >= toMs) {
|
|
618
|
+
return false;
|
|
619
|
+
}
|
|
620
|
+
const startMs = currentMs;
|
|
621
|
+
const endMs = currentMs + this.#AUDIO_PLAYBACK_SLICE_MS;
|
|
622
|
+
currentMs += this.#AUDIO_PLAYBACK_SLICE_MS;
|
|
623
|
+
const audioBuffer = await timegroup.renderAudio(startMs, endMs);
|
|
624
|
+
bufferCount++;
|
|
625
|
+
const source = playbackContext.createBufferSource();
|
|
626
|
+
source.buffer = audioBuffer;
|
|
627
|
+
source.connect(playbackContext.destination);
|
|
628
|
+
source.start((startMs - fromMs) / 1000);
|
|
629
|
+
source.onended = () => {
|
|
630
|
+
bufferCount--;
|
|
631
|
+
if (endMs >= toMs) {
|
|
632
|
+
this.playing = false;
|
|
633
|
+
} else {
|
|
634
|
+
fillBuffer();
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
return true;
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
await fillBuffer();
|
|
641
|
+
await playbackContext.resume();
|
|
642
|
+
}
|
|
643
|
+
|
|
534
644
|
advancePlayhead = (tick?: DOMHighResTimeStamp) => {
|
|
535
|
-
if (this.#lastTick && tick && this.
|
|
536
|
-
this.
|
|
537
|
-
if (
|
|
645
|
+
if (this.#lastTick && tick && this.targetTimegroup) {
|
|
646
|
+
this.targetTimegroup.currentTimeMs += tick - this.#lastTick;
|
|
647
|
+
if (
|
|
648
|
+
this.targetTimegroup.currentTimeMs >= this.targetTimegroup.durationMs
|
|
649
|
+
) {
|
|
538
650
|
this.playing = false;
|
|
539
651
|
}
|
|
540
652
|
}
|
|
@@ -558,9 +670,9 @@ export class EFFilmStrip extends TWMixin(LitElement) {
|
|
|
558
670
|
return;
|
|
559
671
|
}
|
|
560
672
|
const rect = gutter.getBoundingClientRect();
|
|
561
|
-
if (this.
|
|
673
|
+
if (this.targetTimegroup) {
|
|
562
674
|
const layerX = e.pageX - rect.left + gutter.scrollLeft;
|
|
563
|
-
this.
|
|
675
|
+
this.targetTimegroup.currentTimeMs = layerX / this.pixelsPerMs;
|
|
564
676
|
}
|
|
565
677
|
}
|
|
566
678
|
|
|
@@ -576,9 +688,9 @@ export class EFFilmStrip extends TWMixin(LitElement) {
|
|
|
576
688
|
return;
|
|
577
689
|
}
|
|
578
690
|
const rect = gutter.getBoundingClientRect();
|
|
579
|
-
if (this.
|
|
691
|
+
if (this.targetTimegroup) {
|
|
580
692
|
const layerX = e.pageX - rect.left + gutter.scrollLeft;
|
|
581
|
-
this.
|
|
693
|
+
this.targetTimegroup.currentTimeMs = layerX / this.pixelsPerMs;
|
|
582
694
|
}
|
|
583
695
|
});
|
|
584
696
|
addEventListener(
|
|
@@ -592,7 +704,7 @@ export class EFFilmStrip extends TWMixin(LitElement) {
|
|
|
592
704
|
|
|
593
705
|
@eventOptions({ passive: false })
|
|
594
706
|
scrollScrub(e: WheelEvent) {
|
|
595
|
-
if (this.
|
|
707
|
+
if (this.targetTimegroup && this.gutter && !this.playing) {
|
|
596
708
|
e.preventDefault();
|
|
597
709
|
// Avoid over-scrolling to the left
|
|
598
710
|
if (
|
|
@@ -616,7 +728,7 @@ export class EFFilmStrip extends TWMixin(LitElement) {
|
|
|
616
728
|
|
|
617
729
|
if (this) {
|
|
618
730
|
this.gutter.scrollBy(e.deltaX, e.deltaY);
|
|
619
|
-
this.
|
|
731
|
+
this.targetTimegroup.currentTimeMs += e.deltaX / this.pixelsPerMs;
|
|
620
732
|
}
|
|
621
733
|
}
|
|
622
734
|
}
|
|
@@ -630,7 +742,7 @@ export class EFFilmStrip extends TWMixin(LitElement) {
|
|
|
630
742
|
}
|
|
631
743
|
|
|
632
744
|
render() {
|
|
633
|
-
const target = this.
|
|
745
|
+
const target = this.targetTimegroup;
|
|
634
746
|
|
|
635
747
|
return html` <div
|
|
636
748
|
class="grid h-full bg-slate-100"
|
|
@@ -702,7 +814,7 @@ export class EFFilmStrip extends TWMixin(LitElement) {
|
|
|
702
814
|
${ref(this.playheadRef)}
|
|
703
815
|
></div>
|
|
704
816
|
|
|
705
|
-
${
|
|
817
|
+
${renderFilmstripChildren(
|
|
706
818
|
Array.from(target?.children || []),
|
|
707
819
|
this.pixelsPerMs,
|
|
708
820
|
)}
|
|
@@ -714,24 +826,26 @@ export class EFFilmStrip extends TWMixin(LitElement) {
|
|
|
714
826
|
update(changedProperties: Map<string | number | symbol, unknown>) {
|
|
715
827
|
if (changedProperties.has("playing")) {
|
|
716
828
|
if (this.playing) {
|
|
717
|
-
this
|
|
829
|
+
this.#startPlayback();
|
|
830
|
+
} else {
|
|
831
|
+
this.#stopPlayback();
|
|
718
832
|
}
|
|
719
833
|
}
|
|
720
834
|
super.update(changedProperties);
|
|
721
835
|
}
|
|
722
836
|
|
|
723
837
|
updated(changes: PropertyValueMap<any> | Map<PropertyKey, unknown>) {
|
|
724
|
-
if (!this.
|
|
838
|
+
if (!this.targetTimegroup) {
|
|
725
839
|
return;
|
|
726
840
|
}
|
|
727
841
|
if (changes.has("currentTimeMs")) {
|
|
728
|
-
if (this.
|
|
729
|
-
this.
|
|
842
|
+
if (this.targetTimegroup.currentTimeMs !== this.currentTimeMs) {
|
|
843
|
+
this.targetTimegroup.currentTimeMs = this.currentTimeMs;
|
|
730
844
|
}
|
|
731
845
|
}
|
|
732
846
|
}
|
|
733
847
|
|
|
734
|
-
get
|
|
848
|
+
get targetTimegroup() {
|
|
735
849
|
if (this.getAttribute("target")) {
|
|
736
850
|
const target = document.querySelector(this.getAttribute("target") ?? "");
|
|
737
851
|
if (target instanceof EFTimegroup) {
|
|
@@ -746,7 +860,7 @@ export class EFFilmStrip extends TWMixin(LitElement) {
|
|
|
746
860
|
|
|
747
861
|
declare global {
|
|
748
862
|
interface HTMLElementTagNameMap {
|
|
749
|
-
"ef-filmstrip":
|
|
863
|
+
"ef-filmstrip": EFFilmstrip;
|
|
750
864
|
"ef-timegroup-hierarchy-item": EFTimegroupHierarchyItem;
|
|
751
865
|
"ef-audio-hierarchy-item": EFAudioHierarchyItem;
|
|
752
866
|
"ef-video-hierarchy-item": EFVideoHierarchyItem;
|