@editframe/elements 0.5.0-beta.9 → 0.6.0-beta.10
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/dist/lib/av/EncodedAsset.cjs +561 -0
- package/dist/lib/av/{EncodedAsset.mjs → EncodedAsset.js} +18 -13
- package/dist/lib/av/MP4File.cjs +182 -0
- package/dist/lib/av/{MP4File.mjs → MP4File.js} +15 -10
- package/dist/lib/av/msToTimeCode.cjs +15 -0
- package/dist/lib/util/awaitMicrotask.cjs +8 -0
- package/dist/lib/util/memoize.cjs +14 -0
- package/dist/packages/elements/src/EF_FRAMEGEN.cjs +197 -0
- package/dist/packages/elements/src/EF_FRAMEGEN.d.ts +45 -0
- package/dist/packages/elements/src/{EF_FRAMEGEN.mjs → EF_FRAMEGEN.js} +21 -7
- package/dist/packages/elements/src/EF_INTERACTIVE.cjs +4 -0
- package/dist/packages/elements/src/EF_INTERACTIVE.d.ts +1 -0
- package/dist/packages/elements/src/elements/CrossUpdateController.cjs +16 -0
- package/dist/packages/elements/src/elements/CrossUpdateController.d.ts +9 -0
- package/dist/packages/elements/src/elements/EFAudio.cjs +53 -0
- package/dist/packages/elements/src/elements/EFAudio.d.ts +10 -0
- package/dist/packages/elements/src/elements/{EFAudio.mjs → EFAudio.js} +1 -1
- package/dist/packages/elements/src/elements/EFCaptions.cjs +171 -0
- package/dist/packages/elements/src/elements/EFCaptions.d.ts +39 -0
- package/dist/packages/elements/src/elements/{EFCaptions.mjs → EFCaptions.js} +13 -13
- package/dist/packages/elements/src/elements/EFImage.cjs +79 -0
- package/dist/packages/elements/src/elements/EFImage.d.ts +14 -0
- package/dist/packages/elements/src/elements/{EFImage.mjs → EFImage.js} +6 -4
- package/dist/packages/elements/src/elements/EFMedia.cjs +334 -0
- package/dist/packages/elements/src/elements/EFMedia.d.ts +61 -0
- package/dist/packages/elements/src/elements/{EFMedia.mjs → EFMedia.js} +29 -18
- package/dist/packages/elements/src/elements/EFSourceMixin.cjs +55 -0
- package/dist/packages/elements/src/elements/EFSourceMixin.d.ts +12 -0
- package/dist/packages/elements/src/elements/{EFSourceMixin.mjs → EFSourceMixin.js} +1 -1
- package/dist/packages/elements/src/elements/EFTemporal.cjs +198 -0
- package/dist/packages/elements/src/elements/EFTemporal.d.ts +36 -0
- package/dist/packages/elements/src/elements/{EFTemporal.mjs → EFTemporal.js} +4 -7
- package/dist/packages/elements/src/elements/EFTimegroup.browsertest.d.ts +12 -0
- package/dist/packages/elements/src/elements/EFTimegroup.cjs +343 -0
- package/dist/packages/elements/src/elements/EFTimegroup.d.ts +39 -0
- package/dist/packages/elements/src/elements/{EFTimegroup.mjs → EFTimegroup.js} +23 -22
- package/dist/packages/elements/src/elements/EFTimeline.cjs +15 -0
- package/dist/packages/elements/src/elements/EFTimeline.d.ts +3 -0
- package/dist/packages/elements/src/elements/{EFTimeline.mjs → EFTimeline.js} +5 -2
- package/dist/packages/elements/src/elements/EFVideo.cjs +110 -0
- package/dist/packages/elements/src/elements/EFVideo.d.ts +14 -0
- package/dist/packages/elements/src/elements/{EFVideo.mjs → EFVideo.js} +2 -2
- package/dist/packages/elements/src/elements/EFWaveform.cjs +235 -0
- package/dist/packages/elements/src/elements/EFWaveform.d.ts +28 -0
- package/dist/packages/elements/src/elements/{EFWaveform.mjs → EFWaveform.js} +14 -14
- package/dist/packages/elements/src/elements/FetchMixin.cjs +28 -0
- package/dist/packages/elements/src/elements/FetchMixin.d.ts +8 -0
- package/dist/packages/elements/src/elements/{FetchMixin.mjs → FetchMixin.js} +1 -1
- package/dist/packages/elements/src/elements/TimegroupController.cjs +20 -0
- package/dist/packages/elements/src/elements/TimegroupController.d.ts +14 -0
- package/dist/packages/elements/src/elements/durationConverter.cjs +8 -0
- package/dist/packages/elements/src/elements/durationConverter.d.ts +4 -0
- package/dist/packages/elements/src/elements/{durationConverter.mjs → durationConverter.js} +1 -1
- package/dist/packages/elements/src/elements/parseTimeToMs.cjs +12 -0
- package/dist/packages/elements/src/elements/parseTimeToMs.d.ts +1 -0
- package/dist/packages/elements/src/elements/parseTimeToMs.js +12 -0
- package/dist/packages/elements/src/elements/util.cjs +11 -0
- package/dist/packages/elements/src/elements/util.d.ts +4 -0
- package/dist/packages/elements/src/elements/{util.mjs → util.js} +1 -1
- package/dist/packages/elements/src/gui/EFFilmstrip.cjs +675 -0
- package/dist/packages/elements/src/gui/EFFilmstrip.d.ts +138 -0
- package/dist/packages/elements/src/gui/{EFFilmstrip.mjs → EFFilmstrip.js} +48 -34
- package/dist/packages/elements/src/gui/EFWorkbench.cjs +199 -0
- package/dist/packages/elements/src/gui/EFWorkbench.d.ts +44 -0
- package/dist/packages/elements/src/gui/{EFWorkbench.mjs → EFWorkbench.js} +26 -27
- package/dist/packages/elements/src/gui/TWMixin.cjs +28 -0
- package/dist/packages/elements/src/gui/TWMixin.css.cjs +3 -0
- package/dist/packages/elements/src/gui/TWMixin.d.ts +3 -0
- package/dist/packages/elements/src/gui/{TWMixin.mjs → TWMixin.js} +4 -3
- package/dist/packages/elements/src/index.cjs +47 -0
- package/dist/packages/elements/src/index.d.ts +10 -0
- package/dist/packages/elements/src/index.js +23 -0
- package/package.json +17 -3
- package/dist/packages/elements/src/elements/parseTimeToMs.mjs +0 -13
- package/dist/packages/elements/src/elements.mjs +0 -12
- /package/dist/lib/av/{msToTimeCode.mjs → msToTimeCode.js} +0 -0
- /package/dist/lib/util/{awaitMicrotask.mjs → awaitMicrotask.js} +0 -0
- /package/dist/lib/util/{memoize.mjs → memoize.js} +0 -0
- /package/dist/packages/elements/src/{EF_INTERACTIVE.mjs → EF_INTERACTIVE.js} +0 -0
- /package/dist/packages/elements/src/elements/{CrossUpdateController.mjs → CrossUpdateController.js} +0 -0
- /package/dist/packages/elements/src/elements/{TimegroupController.mjs → TimegroupController.js} +0 -0
- /package/dist/packages/elements/src/gui/{TWMixin.css.mjs → TWMixin.css.js} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { html, css, LitElement } from "lit";
|
|
2
2
|
import { provide } from "@lit/context";
|
|
3
3
|
import { property, customElement } from "lit/decorators.js";
|
|
4
|
-
import { EFTemporal, shallowGetTemporalElements, isEFTemporal, timegroupContext } from "./EFTemporal.
|
|
5
|
-
import { TimegroupController } from "./TimegroupController.
|
|
6
|
-
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.
|
|
7
|
-
import { deepGetMediaElements } from "./EFMedia.
|
|
4
|
+
import { EFTemporal, shallowGetTemporalElements, isEFTemporal, timegroupContext } from "./EFTemporal.js";
|
|
5
|
+
import { TimegroupController } from "./TimegroupController.js";
|
|
6
|
+
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
7
|
+
import { deepGetMediaElements } from "./EFMedia.js";
|
|
8
8
|
import { Task } from "@lit/task";
|
|
9
9
|
var __defProp = Object.defineProperty;
|
|
10
10
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -44,7 +44,7 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
44
44
|
this.frameTask = new Task(this, {
|
|
45
45
|
autoRun: EF_INTERACTIVE,
|
|
46
46
|
args: () => [this.ownCurrentTimeMs, this.currentTimeMs],
|
|
47
|
-
task: async ([], { signal }) => {
|
|
47
|
+
task: async ([], { signal: _signal }) => {
|
|
48
48
|
let fullyUpdated = await this.updateComplete;
|
|
49
49
|
while (!fullyUpdated) {
|
|
50
50
|
fullyUpdated = await this.updateComplete;
|
|
@@ -79,7 +79,7 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
79
79
|
maybeLoadTimeFromLocalStorage() {
|
|
80
80
|
if (this.id) {
|
|
81
81
|
try {
|
|
82
|
-
return parseFloat(localStorage.getItem(this.storageKey) || "0");
|
|
82
|
+
return Number.parseFloat(localStorage.getItem(this.storageKey) || "0");
|
|
83
83
|
} catch (error) {
|
|
84
84
|
console.warn("Failed to load time from localStorage", error);
|
|
85
85
|
}
|
|
@@ -122,20 +122,22 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
122
122
|
switch (this.mode) {
|
|
123
123
|
case "fixed":
|
|
124
124
|
return super.durationMs || 0;
|
|
125
|
-
case "sequence":
|
|
125
|
+
case "sequence": {
|
|
126
126
|
let duration = 0;
|
|
127
|
-
this.childTemporals
|
|
127
|
+
for (const node of this.childTemporals) {
|
|
128
128
|
duration += node.durationMs;
|
|
129
|
-
}
|
|
129
|
+
}
|
|
130
130
|
return duration;
|
|
131
|
-
|
|
131
|
+
}
|
|
132
|
+
case "contain": {
|
|
132
133
|
let maxDuration = 0;
|
|
133
|
-
this.childTemporals
|
|
134
|
+
for (const node of this.childTemporals) {
|
|
134
135
|
if (node.hasOwnDuration) {
|
|
135
136
|
maxDuration = Math.max(maxDuration, node.durationMs);
|
|
136
137
|
}
|
|
137
|
-
}
|
|
138
|
+
}
|
|
138
139
|
return maxDuration;
|
|
140
|
+
}
|
|
139
141
|
default:
|
|
140
142
|
throw new Error(`Invalid time mode: ${this.mode}`);
|
|
141
143
|
}
|
|
@@ -164,7 +166,7 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
164
166
|
"--ef-duration",
|
|
165
167
|
`${this.durationMs + this.crossoverEndMs + this.crossoverStartMs}ms`
|
|
166
168
|
);
|
|
167
|
-
|
|
169
|
+
for (const animation of animations) {
|
|
168
170
|
if (animation.playState === "running") {
|
|
169
171
|
animation.pause();
|
|
170
172
|
}
|
|
@@ -206,7 +208,7 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
206
208
|
}
|
|
207
209
|
animation.currentTime = newTime;
|
|
208
210
|
}
|
|
209
|
-
}
|
|
211
|
+
}
|
|
210
212
|
}
|
|
211
213
|
}
|
|
212
214
|
shouldWrapWithWorkbench() {
|
|
@@ -277,13 +279,13 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
277
279
|
async loadMd5Sums() {
|
|
278
280
|
const efElements = this.efElements;
|
|
279
281
|
const loaderTasks = [];
|
|
280
|
-
|
|
282
|
+
for (const el of efElements) {
|
|
281
283
|
const md5SumLoader = el.md5SumLoader;
|
|
282
284
|
if (md5SumLoader instanceof Task) {
|
|
283
285
|
md5SumLoader.run();
|
|
284
286
|
loaderTasks.push(md5SumLoader.taskComplete);
|
|
285
287
|
}
|
|
286
|
-
}
|
|
288
|
+
}
|
|
287
289
|
await Promise.all(loaderTasks);
|
|
288
290
|
efElements.map((el) => {
|
|
289
291
|
if ("productionSrc" in el && el.productionSrc instanceof Function) {
|
|
@@ -320,15 +322,14 @@ __decorateClass([
|
|
|
320
322
|
converter: {
|
|
321
323
|
fromAttribute: (value) => {
|
|
322
324
|
if (value.endsWith("ms")) {
|
|
323
|
-
return parseFloat(value);
|
|
325
|
+
return Number.parseFloat(value);
|
|
324
326
|
}
|
|
325
327
|
if (value.endsWith("s")) {
|
|
326
|
-
return parseFloat(value) * 1e3;
|
|
327
|
-
} else {
|
|
328
|
-
throw new Error(
|
|
329
|
-
"`crossover` MUST be in milliseconds or seconds (10s, 10000ms)"
|
|
330
|
-
);
|
|
328
|
+
return Number.parseFloat(value) * 1e3;
|
|
331
329
|
}
|
|
330
|
+
throw new Error(
|
|
331
|
+
"`crossover` MUST be in milliseconds or seconds (10s, 10000ms)"
|
|
332
|
+
);
|
|
332
333
|
},
|
|
333
334
|
toAttribute: (value) => `${value}ms`
|
|
334
335
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
class EFTimeline extends HTMLElement {
|
|
4
|
+
get durationMs() {
|
|
5
|
+
let duration = 0;
|
|
6
|
+
for (const node of this.childNodes) {
|
|
7
|
+
if ("durationMs" in node && typeof node.durationMs === "number") {
|
|
8
|
+
duration += node.durationMs;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return duration;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
window.customElements.define("ef-timeline", EFTimeline);
|
|
15
|
+
exports.EFTimeline = EFTimeline;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
class EFTimeline extends HTMLElement {
|
|
2
2
|
get durationMs() {
|
|
3
3
|
let duration = 0;
|
|
4
|
-
this.childNodes
|
|
4
|
+
for (const node of this.childNodes) {
|
|
5
5
|
if ("durationMs" in node && typeof node.durationMs === "number") {
|
|
6
6
|
duration += node.durationMs;
|
|
7
7
|
}
|
|
8
|
-
}
|
|
8
|
+
}
|
|
9
9
|
return duration;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
window.customElements.define("ef-timeline", EFTimeline);
|
|
13
|
+
export {
|
|
14
|
+
EFTimeline
|
|
15
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const lit = require("lit");
|
|
4
|
+
const task = require("@lit/task");
|
|
5
|
+
const ref_js = require("lit/directives/ref.js");
|
|
6
|
+
const decorators_js = require("lit/decorators.js");
|
|
7
|
+
const EFMedia = require("./EFMedia.cjs");
|
|
8
|
+
const TWMixin = require("../gui/TWMixin.cjs");
|
|
9
|
+
var __defProp = Object.defineProperty;
|
|
10
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
|
+
var __typeError = (msg) => {
|
|
12
|
+
throw TypeError(msg);
|
|
13
|
+
};
|
|
14
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
15
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
16
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
17
|
+
if (decorator = decorators[i])
|
|
18
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
19
|
+
if (kind && result) __defProp(target, key, result);
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
23
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), member.get(obj));
|
|
24
|
+
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);
|
|
25
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
26
|
+
var _decoderLock;
|
|
27
|
+
exports.EFVideo = class EFVideo extends TWMixin.TWMixin(EFMedia.EFMedia) {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(...arguments);
|
|
30
|
+
this.canvasRef = ref_js.createRef();
|
|
31
|
+
__privateAdd(this, _decoderLock, false);
|
|
32
|
+
this.frameTask = new task.Task(this, {
|
|
33
|
+
args: () => [
|
|
34
|
+
this.trackFragmentIndexLoader.status,
|
|
35
|
+
this.initSegmentsLoader.status,
|
|
36
|
+
this.seekTask.status,
|
|
37
|
+
this.fetchSeekTask.status,
|
|
38
|
+
this.videoAssetTask.status,
|
|
39
|
+
this.paintTask.status
|
|
40
|
+
],
|
|
41
|
+
task: async () => {
|
|
42
|
+
await this.trackFragmentIndexLoader.taskComplete;
|
|
43
|
+
await this.initSegmentsLoader.taskComplete;
|
|
44
|
+
await this.seekTask.taskComplete;
|
|
45
|
+
await this.fetchSeekTask.taskComplete;
|
|
46
|
+
await this.videoAssetTask.taskComplete;
|
|
47
|
+
await this.paintTask.taskComplete;
|
|
48
|
+
this.rootTimegroup?.requestUpdate();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
this.paintTask = new task.Task(this, {
|
|
52
|
+
args: () => [this.videoAssetTask.value, this.desiredSeekTimeMs],
|
|
53
|
+
task: async ([videoAsset, seekToMs], {
|
|
54
|
+
signal: _signal
|
|
55
|
+
}) => {
|
|
56
|
+
if (!videoAsset) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (__privateGet(this, _decoderLock)) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
__privateSet(this, _decoderLock, true);
|
|
64
|
+
const frame = await videoAsset.seekToTime(seekToMs / 1e3);
|
|
65
|
+
if (!this.canvasElement) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const ctx = this.canvasElement.getContext("2d");
|
|
69
|
+
if (!(frame && ctx)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this.canvasElement.width = frame?.codedWidth;
|
|
73
|
+
this.canvasElement.height = frame?.codedHeight;
|
|
74
|
+
ctx.drawImage(
|
|
75
|
+
frame,
|
|
76
|
+
0,
|
|
77
|
+
0,
|
|
78
|
+
this.canvasElement.width,
|
|
79
|
+
this.canvasElement.height
|
|
80
|
+
);
|
|
81
|
+
return seekToMs;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.trace("Unexpected error while seeking video", error);
|
|
84
|
+
} finally {
|
|
85
|
+
__privateSet(this, _decoderLock, false);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
render() {
|
|
91
|
+
return lit.html` <canvas
|
|
92
|
+
class="h-full w-full object-fill"
|
|
93
|
+
${ref_js.ref(this.canvasRef)}
|
|
94
|
+
></canvas>`;
|
|
95
|
+
}
|
|
96
|
+
get canvasElement() {
|
|
97
|
+
return this.canvasRef.value;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
_decoderLock = /* @__PURE__ */ new WeakMap();
|
|
101
|
+
exports.EFVideo.styles = [
|
|
102
|
+
lit.css`
|
|
103
|
+
:host {
|
|
104
|
+
display: block;
|
|
105
|
+
}
|
|
106
|
+
`
|
|
107
|
+
];
|
|
108
|
+
exports.EFVideo = __decorateClass([
|
|
109
|
+
decorators_js.customElement("ef-video")
|
|
110
|
+
], exports.EFVideo);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Task } from '@lit/task';
|
|
2
|
+
import { EFMedia } from './EFMedia';
|
|
3
|
+
|
|
4
|
+
declare const EFVideo_base: typeof EFMedia;
|
|
5
|
+
export declare class EFVideo extends EFVideo_base {
|
|
6
|
+
#private;
|
|
7
|
+
static styles: import('lit').CSSResult[];
|
|
8
|
+
canvasRef: import('lit-html/directives/ref').Ref<HTMLCanvasElement>;
|
|
9
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
10
|
+
get canvasElement(): HTMLCanvasElement | undefined;
|
|
11
|
+
frameTask: Task<readonly [import('@lit/task').TaskStatus, import('@lit/task').TaskStatus, import('@lit/task').TaskStatus, import('@lit/task').TaskStatus, import('@lit/task').TaskStatus, import('@lit/task').TaskStatus], void>;
|
|
12
|
+
paintTask: Task<readonly [import('../../../../lib/av/EncodedAsset').VideoAsset | undefined, number], number | undefined>;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -2,8 +2,8 @@ import { css, html } from "lit";
|
|
|
2
2
|
import { Task } from "@lit/task";
|
|
3
3
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
4
4
|
import { customElement } from "lit/decorators.js";
|
|
5
|
-
import { EFMedia } from "./EFMedia.
|
|
6
|
-
import { TWMixin } from "../gui/TWMixin.
|
|
5
|
+
import { EFMedia } from "./EFMedia.js";
|
|
6
|
+
import { TWMixin } from "../gui/TWMixin.js";
|
|
7
7
|
var __defProp = Object.defineProperty;
|
|
8
8
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
9
|
var __typeError = (msg) => {
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const EFAudio = require("./EFAudio.cjs");
|
|
4
|
+
const lit = require("lit");
|
|
5
|
+
const decorators_js = require("lit/decorators.js");
|
|
6
|
+
const EFVideo = require("./EFVideo.cjs");
|
|
7
|
+
const EFTemporal = require("./EFTemporal.cjs");
|
|
8
|
+
const CrossUpdateController = require("./CrossUpdateController.cjs");
|
|
9
|
+
const TWMixin = require("../gui/TWMixin.cjs");
|
|
10
|
+
const task = require("@lit/task");
|
|
11
|
+
const d3 = require("d3");
|
|
12
|
+
const ref_js = require("lit/directives/ref.js");
|
|
13
|
+
const EF_INTERACTIVE = require("../EF_INTERACTIVE.cjs");
|
|
14
|
+
function _interopNamespaceDefault(e) {
|
|
15
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
16
|
+
if (e) {
|
|
17
|
+
for (const k in e) {
|
|
18
|
+
if (k !== "default") {
|
|
19
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
20
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: () => e[k]
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
n.default = e;
|
|
28
|
+
return Object.freeze(n);
|
|
29
|
+
}
|
|
30
|
+
const d3__namespace = /* @__PURE__ */ _interopNamespaceDefault(d3);
|
|
31
|
+
var __defProp = Object.defineProperty;
|
|
32
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
33
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
34
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
35
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
36
|
+
if (decorator = decorators[i])
|
|
37
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
38
|
+
if (kind && result) __defProp(target, key, result);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
exports.EFWaveform = class EFWaveform extends EFTemporal.EFTemporal(TWMixin.TWMixin(lit.LitElement)) {
|
|
42
|
+
constructor() {
|
|
43
|
+
super(...arguments);
|
|
44
|
+
this.svgRef = ref_js.createRef();
|
|
45
|
+
this.mode = "bars";
|
|
46
|
+
this.color = "currentColor";
|
|
47
|
+
this.frameTask = new task.Task(this, {
|
|
48
|
+
autoRun: EF_INTERACTIVE.EF_INTERACTIVE,
|
|
49
|
+
args: () => [this.target.audioBufferTask.status],
|
|
50
|
+
task: async () => {
|
|
51
|
+
await this.target.audioBufferTask.taskComplete;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
createRenderRoot() {
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
render() {
|
|
59
|
+
return lit.html` <svg ${ref_js.ref(this.svgRef)} class="h-full w-full" store></svg> `;
|
|
60
|
+
}
|
|
61
|
+
connectedCallback() {
|
|
62
|
+
super.connectedCallback();
|
|
63
|
+
if (this.target) {
|
|
64
|
+
new CrossUpdateController.CrossUpdateController(this.target, this);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
drawBars(svg, frequencyData) {
|
|
68
|
+
const waveWidth = svg.clientWidth * devicePixelRatio;
|
|
69
|
+
const waveHeight = svg.clientHeight;
|
|
70
|
+
const waveLeft = 0;
|
|
71
|
+
const waveRight = waveWidth;
|
|
72
|
+
const barX = d3__namespace.scaleBand().paddingInner(0.5).paddingOuter(0.01).domain(d3__namespace.range(frequencyData.length).map((n) => String(n))).rangeRound([waveLeft, waveRight]);
|
|
73
|
+
const height = d3__namespace.scaleLinear().domain([0, 255]).range([0, waveHeight / 2]);
|
|
74
|
+
const baseline = waveHeight / 2;
|
|
75
|
+
const bars = d3__namespace.select(svg).selectAll("rect").data(frequencyData);
|
|
76
|
+
const minBarHeight = 2;
|
|
77
|
+
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i)) || 0).attr("y", (value) => baseline - height(value)).attr("width", barX.bandwidth() / 1.2).attr("height", (value) => Math.max(height(value) * 2, minBarHeight));
|
|
78
|
+
bars.exit().remove();
|
|
79
|
+
}
|
|
80
|
+
drawBricks(svg, frequencyData) {
|
|
81
|
+
const waveWidth = svg.clientWidth * devicePixelRatio;
|
|
82
|
+
const waveHeight = svg.clientHeight * devicePixelRatio;
|
|
83
|
+
const brickWidth = waveWidth / frequencyData.length;
|
|
84
|
+
const brickHeightFactor = waveHeight / 255 / 2;
|
|
85
|
+
const brickPadding = 2;
|
|
86
|
+
const midHeight = waveHeight / 2;
|
|
87
|
+
d3__namespace.select(svg).selectAll("line.brickBaseLine").data([0]).join("line").attr("class", "brickBaseLine").attr("x1", 0).attr("x2", waveWidth).attr("y1", midHeight).attr("y2", midHeight).attr("stroke", "currentColor").attr("stroke-width", 4).attr("stroke-dasharray", "2");
|
|
88
|
+
d3__namespace.select(svg).selectAll("rect.brick").data(frequencyData).join("rect").attr("class", "brick").attr("x", (_d, i) => i * brickWidth).attr("y", (d) => midHeight - d * brickHeightFactor).attr("width", brickWidth - brickPadding).attr("height", (d) => d * brickHeightFactor * 2);
|
|
89
|
+
}
|
|
90
|
+
drawLine(svg, frequencyData) {
|
|
91
|
+
const waveWidth = svg.clientWidth * devicePixelRatio;
|
|
92
|
+
const waveHeight = svg.clientHeight * devicePixelRatio;
|
|
93
|
+
const xScale = d3__namespace.scaleLinear().domain([0, frequencyData.length - 1]).range([0, waveWidth]);
|
|
94
|
+
const yScale = d3__namespace.scaleLinear().domain([0, 255]).range([waveHeight, 0]);
|
|
95
|
+
const lineGenerator = d3__namespace.line().x((_, i) => xScale(i)).y((d) => yScale(d));
|
|
96
|
+
const pathData = lineGenerator(frequencyData);
|
|
97
|
+
d3__namespace.select(svg).selectAll("path.line").data([frequencyData]).join("path").attr("class", "line").attr("d", pathData).attr("fill", "none").attr("stroke", "currentColor").attr("stroke-width", 4);
|
|
98
|
+
}
|
|
99
|
+
drawRoundBars(svg, frequencyData) {
|
|
100
|
+
const waveWidth = svg.clientWidth * devicePixelRatio;
|
|
101
|
+
const waveHeight = svg.clientHeight;
|
|
102
|
+
const waveLeft = 0;
|
|
103
|
+
const waveRight = waveWidth;
|
|
104
|
+
const barX = d3__namespace.scaleBand().paddingInner(0.5).paddingOuter(0.01).domain(d3__namespace.range(frequencyData.length).map((n) => String(n))).rangeRound([waveLeft, waveRight]);
|
|
105
|
+
const height = d3__namespace.scaleLinear().domain([0, 255]).range([0, waveHeight / 2]);
|
|
106
|
+
const baseline = waveHeight / 2;
|
|
107
|
+
const bars = d3__namespace.select(svg).selectAll("rect").data(frequencyData);
|
|
108
|
+
const minBarHeight = 2;
|
|
109
|
+
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i)) || 0).attr("y", (value) => baseline - height(value)).attr("width", barX.bandwidth() / 1.2).attr("height", (value) => Math.max(height(value) * 2, minBarHeight)).attr("rx", barX.bandwidth()).attr("ry", barX.bandwidth());
|
|
110
|
+
bars.exit().remove();
|
|
111
|
+
}
|
|
112
|
+
drawEqualizer(svg, frequencyData) {
|
|
113
|
+
const waveWidth = svg.clientWidth * devicePixelRatio;
|
|
114
|
+
const waveHeight = svg.clientHeight * devicePixelRatio;
|
|
115
|
+
const barWidth = waveWidth / frequencyData.length;
|
|
116
|
+
const barPadding = 1;
|
|
117
|
+
const minHeight = 1;
|
|
118
|
+
const heightScale = d3__namespace.scaleLinear().domain([0, 255]).range([0, waveHeight / 2]);
|
|
119
|
+
d3__namespace.select(svg).selectAll("line.equalizerBaseLine").data([0]).join("line").attr("class", "equalizerBaseLine").attr("x1", 0).attr("x2", waveWidth).attr("y1", waveHeight / 2).attr("y2", waveHeight / 2).attr("stroke-width", 2);
|
|
120
|
+
d3__namespace.select(svg).selectAll("rect.equalizerBar").data(frequencyData).join("rect").attr("class", "equalizerBar").attr("x", (_d, i) => i * barWidth + barPadding / 2).attr(
|
|
121
|
+
"y",
|
|
122
|
+
(d) => waveHeight / 2 - Math.max(heightScale(d) / 2, minHeight)
|
|
123
|
+
).attr("width", barWidth - barPadding).attr("height", (d) => Math.max(heightScale(d), minHeight));
|
|
124
|
+
d3__namespace.select(svg).selectAll("rect.equalizerBar").transition().duration(100).attr(
|
|
125
|
+
"y",
|
|
126
|
+
(d) => waveHeight / 2 - Math.max(heightScale(Number(d)) / 2, minHeight)
|
|
127
|
+
).attr("height", (d) => Math.max(heightScale(Number(d)), minHeight));
|
|
128
|
+
}
|
|
129
|
+
drawCurve(svg, frequencyData) {
|
|
130
|
+
const waveWidth = svg.clientWidth * devicePixelRatio;
|
|
131
|
+
const waveHeight = svg.clientHeight * devicePixelRatio;
|
|
132
|
+
const xScale = d3__namespace.scaleLinear().domain([0, frequencyData.length]).range([0, waveWidth]);
|
|
133
|
+
const yScale = d3__namespace.scaleLinear().domain([0, 255]).range([waveHeight, 0]);
|
|
134
|
+
const curveGenerator = d3__namespace.line().x((_, i) => xScale(i)).y((d) => yScale(d)).curve(d3__namespace.curveNatural);
|
|
135
|
+
const pathData = curveGenerator(frequencyData);
|
|
136
|
+
d3__namespace.select(svg).selectAll("path.curve").data([frequencyData]).join("path").attr("class", "curve").attr("d", pathData).attr("fill", "none").attr("stroke", "currentColor").attr("stroke-width", 4);
|
|
137
|
+
}
|
|
138
|
+
drawPixel(svg, frequencyData) {
|
|
139
|
+
const waveWidth = svg.clientWidth * devicePixelRatio;
|
|
140
|
+
const waveHeight = svg.clientHeight;
|
|
141
|
+
const baseline = waveHeight / 2;
|
|
142
|
+
const barX = d3__namespace.scaleBand().domain(d3__namespace.range(frequencyData.length).map(String)).rangeRound([0, waveWidth]).paddingInner(0.03).paddingOuter(0.02);
|
|
143
|
+
const height = d3__namespace.scaleLinear().domain([0, 255]).range([0, baseline]);
|
|
144
|
+
const bars = d3__namespace.select(svg).selectAll("rect").data(frequencyData);
|
|
145
|
+
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i)) || 0).attr("y", (value) => baseline - height(value)).attr("width", barX.bandwidth()).attr("height", (value) => height(value) * 2);
|
|
146
|
+
bars.exit().remove();
|
|
147
|
+
}
|
|
148
|
+
drawWave(svg, frequencyData) {
|
|
149
|
+
const waveWidth = svg.clientWidth * devicePixelRatio;
|
|
150
|
+
const waveHeight = svg.clientHeight;
|
|
151
|
+
const barX = d3__namespace.scaleBand().domain(d3__namespace.range(frequencyData.length).map(String)).rangeRound([0, waveWidth]).paddingInner(0.03).paddingOuter(0.02);
|
|
152
|
+
const height = d3__namespace.scaleLinear().domain([0, 255]).range([0, waveHeight / 2]);
|
|
153
|
+
d3__namespace.select(svg).selectAll("line.baseline").data([0]).join("line").attr("class", "baseline").attr("x1", (_, i) => barX(String(i)) || 0).attr("x2", waveWidth).attr("y1", waveHeight / 2).attr("y2", waveHeight / 2).attr("stroke", "currentColor").attr("stroke-width", 2);
|
|
154
|
+
const bars = d3__namespace.select(svg).selectAll("rect").data(frequencyData);
|
|
155
|
+
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i)) || 0).attr("y", (value) => waveHeight / 2 - height(value)).attr("width", barX.bandwidth()).attr("height", (value) => height(value) * 2);
|
|
156
|
+
bars.exit().remove();
|
|
157
|
+
}
|
|
158
|
+
async updated() {
|
|
159
|
+
const svg = this.svgRef.value;
|
|
160
|
+
if (!svg) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (!this.target.audioBufferTask.value) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (this.target.ownCurrentTimeMs > 0) {
|
|
167
|
+
const audioContext = new OfflineAudioContext(2, 48e3 / 25, 48e3);
|
|
168
|
+
const audioBufferSource = audioContext.createBufferSource();
|
|
169
|
+
audioBufferSource.buffer = this.target.audioBufferTask.value.buffer;
|
|
170
|
+
const analyser = audioContext.createAnalyser();
|
|
171
|
+
analyser.fftSize = 256;
|
|
172
|
+
audioBufferSource.connect(analyser);
|
|
173
|
+
audioBufferSource.start(
|
|
174
|
+
0,
|
|
175
|
+
Math.max(
|
|
176
|
+
0,
|
|
177
|
+
(this.target.ownCurrentTimeMs - this.target.audioBufferTask.value.startOffsetMs) / 1e3
|
|
178
|
+
),
|
|
179
|
+
48e3 / 1e3
|
|
180
|
+
);
|
|
181
|
+
await audioContext.startRendering();
|
|
182
|
+
const frequencyData = new Uint8Array(analyser.frequencyBinCount);
|
|
183
|
+
analyser.getByteFrequencyData(frequencyData);
|
|
184
|
+
const rect = this.getBoundingClientRect();
|
|
185
|
+
svg.setAttribute("width", (rect.width * devicePixelRatio).toString());
|
|
186
|
+
svg.setAttribute("height", (rect.height * devicePixelRatio).toString());
|
|
187
|
+
switch (this.mode) {
|
|
188
|
+
case "bars":
|
|
189
|
+
this.drawBars(svg, frequencyData);
|
|
190
|
+
break;
|
|
191
|
+
case "bricks":
|
|
192
|
+
this.drawBricks(svg, frequencyData);
|
|
193
|
+
break;
|
|
194
|
+
case "curve":
|
|
195
|
+
this.drawCurve(svg, frequencyData);
|
|
196
|
+
break;
|
|
197
|
+
case "line":
|
|
198
|
+
this.drawLine(svg, frequencyData);
|
|
199
|
+
break;
|
|
200
|
+
case "pixel":
|
|
201
|
+
this.drawPixel(svg, frequencyData);
|
|
202
|
+
break;
|
|
203
|
+
case "wave":
|
|
204
|
+
this.drawWave(svg, frequencyData);
|
|
205
|
+
break;
|
|
206
|
+
case "roundBars":
|
|
207
|
+
this.drawRoundBars(svg, frequencyData);
|
|
208
|
+
break;
|
|
209
|
+
case "equalizer":
|
|
210
|
+
this.drawEqualizer(svg, frequencyData);
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
get target() {
|
|
216
|
+
const target = document.querySelector(this.getAttribute("target") ?? "");
|
|
217
|
+
if (target instanceof EFAudio.EFAudio || target instanceof EFVideo.EFVideo) {
|
|
218
|
+
return target;
|
|
219
|
+
}
|
|
220
|
+
throw new Error("Invalid target, must be an EFAudio element");
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
exports.EFWaveform.styles = [];
|
|
224
|
+
__decorateClass([
|
|
225
|
+
decorators_js.property({
|
|
226
|
+
type: String,
|
|
227
|
+
attribute: "mode"
|
|
228
|
+
})
|
|
229
|
+
], exports.EFWaveform.prototype, "mode", 2);
|
|
230
|
+
__decorateClass([
|
|
231
|
+
decorators_js.property({ type: String })
|
|
232
|
+
], exports.EFWaveform.prototype, "color", 2);
|
|
233
|
+
exports.EFWaveform = __decorateClass([
|
|
234
|
+
decorators_js.customElement("ef-waveform")
|
|
235
|
+
], exports.EFWaveform);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { EFAudio } from './EFAudio';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
import { EFVideo } from './EFVideo';
|
|
4
|
+
import { Task } from '@lit/task';
|
|
5
|
+
import { Ref } from 'lit/directives/ref.js';
|
|
6
|
+
|
|
7
|
+
declare const EFWaveform_base: (new (...args: any[]) => import('./EFTemporal').TemporalMixinInterface) & typeof LitElement;
|
|
8
|
+
export declare class EFWaveform extends EFWaveform_base {
|
|
9
|
+
static styles: never[];
|
|
10
|
+
svgRef: Ref<SVGElement>;
|
|
11
|
+
createRenderRoot(): this;
|
|
12
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
13
|
+
mode: "roundBars" | "bars" | "bricks" | "equalizer" | "curve" | "line" | "pixel" | "wave";
|
|
14
|
+
color: string;
|
|
15
|
+
connectedCallback(): void;
|
|
16
|
+
protected drawBars(svg: SVGElement, frequencyData: Uint8Array): void;
|
|
17
|
+
protected drawBricks(svg: SVGElement, frequencyData: Uint8Array): void;
|
|
18
|
+
protected drawLine(svg: SVGElement, frequencyData: Uint8Array): void;
|
|
19
|
+
protected drawRoundBars(svg: SVGElement, frequencyData: Uint8Array): void;
|
|
20
|
+
protected drawEqualizer(svg: SVGElement, frequencyData: Uint8Array): void;
|
|
21
|
+
protected drawCurve(svg: SVGElement, frequencyData: Uint8Array): void;
|
|
22
|
+
protected drawPixel(svg: SVGElement, frequencyData: Uint8Array): void;
|
|
23
|
+
protected drawWave(svg: SVGElement, frequencyData: Uint8Array): void;
|
|
24
|
+
frameTask: Task<readonly [import('@lit/task').TaskStatus], void>;
|
|
25
|
+
protected updated(): Promise<void>;
|
|
26
|
+
get target(): EFAudio | EFVideo;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { EFAudio } from "./EFAudio.
|
|
1
|
+
import { EFAudio } from "./EFAudio.js";
|
|
2
2
|
import { html, LitElement } from "lit";
|
|
3
3
|
import { property, customElement } from "lit/decorators.js";
|
|
4
|
-
import { EFVideo } from "./EFVideo.
|
|
5
|
-
import { EFTemporal } from "./EFTemporal.
|
|
6
|
-
import { CrossUpdateController } from "./CrossUpdateController.
|
|
7
|
-
import { TWMixin } from "../gui/TWMixin.
|
|
4
|
+
import { EFVideo } from "./EFVideo.js";
|
|
5
|
+
import { EFTemporal } from "./EFTemporal.js";
|
|
6
|
+
import { CrossUpdateController } from "./CrossUpdateController.js";
|
|
7
|
+
import { TWMixin } from "../gui/TWMixin.js";
|
|
8
8
|
import { Task } from "@lit/task";
|
|
9
9
|
import * as d3 from "d3";
|
|
10
10
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
11
|
-
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.
|
|
11
|
+
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
12
12
|
var __defProp = Object.defineProperty;
|
|
13
13
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
14
14
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -55,7 +55,7 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
55
55
|
const baseline = waveHeight / 2;
|
|
56
56
|
const bars = d3.select(svg).selectAll("rect").data(frequencyData);
|
|
57
57
|
const minBarHeight = 2;
|
|
58
|
-
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i))).attr("y", (value) => baseline - height(value)).attr("width", barX.bandwidth() / 1.2).attr("height", (value) => Math.max(height(value) * 2, minBarHeight));
|
|
58
|
+
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i)) || 0).attr("y", (value) => baseline - height(value)).attr("width", barX.bandwidth() / 1.2).attr("height", (value) => Math.max(height(value) * 2, minBarHeight));
|
|
59
59
|
bars.exit().remove();
|
|
60
60
|
}
|
|
61
61
|
drawBricks(svg, frequencyData) {
|
|
@@ -87,7 +87,7 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
87
87
|
const baseline = waveHeight / 2;
|
|
88
88
|
const bars = d3.select(svg).selectAll("rect").data(frequencyData);
|
|
89
89
|
const minBarHeight = 2;
|
|
90
|
-
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i))).attr("y", (value) => baseline - height(value)).attr("width", barX.bandwidth() / 1.2).attr("height", (value) => Math.max(height(value) * 2, minBarHeight)).attr("rx", barX.bandwidth()).attr("ry", barX.bandwidth());
|
|
90
|
+
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i)) || 0).attr("y", (value) => baseline - height(value)).attr("width", barX.bandwidth() / 1.2).attr("height", (value) => Math.max(height(value) * 2, minBarHeight)).attr("rx", barX.bandwidth()).attr("ry", barX.bandwidth());
|
|
91
91
|
bars.exit().remove();
|
|
92
92
|
}
|
|
93
93
|
drawEqualizer(svg, frequencyData) {
|
|
@@ -98,14 +98,14 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
98
98
|
const minHeight = 1;
|
|
99
99
|
const heightScale = d3.scaleLinear().domain([0, 255]).range([0, waveHeight / 2]);
|
|
100
100
|
d3.select(svg).selectAll("line.equalizerBaseLine").data([0]).join("line").attr("class", "equalizerBaseLine").attr("x1", 0).attr("x2", waveWidth).attr("y1", waveHeight / 2).attr("y2", waveHeight / 2).attr("stroke-width", 2);
|
|
101
|
-
d3.select(svg).selectAll("rect.equalizerBar").data(frequencyData).join("rect").attr("class", "equalizerBar").attr("x", (
|
|
101
|
+
d3.select(svg).selectAll("rect.equalizerBar").data(frequencyData).join("rect").attr("class", "equalizerBar").attr("x", (_d, i) => i * barWidth + barPadding / 2).attr(
|
|
102
102
|
"y",
|
|
103
103
|
(d) => waveHeight / 2 - Math.max(heightScale(d) / 2, minHeight)
|
|
104
104
|
).attr("width", barWidth - barPadding).attr("height", (d) => Math.max(heightScale(d), minHeight));
|
|
105
105
|
d3.select(svg).selectAll("rect.equalizerBar").transition().duration(100).attr(
|
|
106
106
|
"y",
|
|
107
|
-
(d) => waveHeight / 2 - Math.max(heightScale(d) / 2, minHeight)
|
|
108
|
-
).attr("height", (d) => Math.max(heightScale(d), minHeight));
|
|
107
|
+
(d) => waveHeight / 2 - Math.max(heightScale(Number(d)) / 2, minHeight)
|
|
108
|
+
).attr("height", (d) => Math.max(heightScale(Number(d)), minHeight));
|
|
109
109
|
}
|
|
110
110
|
drawCurve(svg, frequencyData) {
|
|
111
111
|
const waveWidth = svg.clientWidth * devicePixelRatio;
|
|
@@ -123,7 +123,7 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
123
123
|
const barX = d3.scaleBand().domain(d3.range(frequencyData.length).map(String)).rangeRound([0, waveWidth]).paddingInner(0.03).paddingOuter(0.02);
|
|
124
124
|
const height = d3.scaleLinear().domain([0, 255]).range([0, baseline]);
|
|
125
125
|
const bars = d3.select(svg).selectAll("rect").data(frequencyData);
|
|
126
|
-
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i))).attr("y", (value) => baseline - height(value)).attr("width", barX.bandwidth()).attr("height", (value) => height(value) * 2);
|
|
126
|
+
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i)) || 0).attr("y", (value) => baseline - height(value)).attr("width", barX.bandwidth()).attr("height", (value) => height(value) * 2);
|
|
127
127
|
bars.exit().remove();
|
|
128
128
|
}
|
|
129
129
|
drawWave(svg, frequencyData) {
|
|
@@ -131,9 +131,9 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
131
131
|
const waveHeight = svg.clientHeight;
|
|
132
132
|
const barX = d3.scaleBand().domain(d3.range(frequencyData.length).map(String)).rangeRound([0, waveWidth]).paddingInner(0.03).paddingOuter(0.02);
|
|
133
133
|
const height = d3.scaleLinear().domain([0, 255]).range([0, waveHeight / 2]);
|
|
134
|
-
d3.select(svg).selectAll("line.baseline").data([0]).join("line").attr("class", "baseline").attr("x1", (_, i) => barX(String(i))).attr("x2", waveWidth).attr("y1", waveHeight / 2).attr("y2", waveHeight / 2).attr("stroke", "currentColor").attr("stroke-width", 2);
|
|
134
|
+
d3.select(svg).selectAll("line.baseline").data([0]).join("line").attr("class", "baseline").attr("x1", (_, i) => barX(String(i)) || 0).attr("x2", waveWidth).attr("y1", waveHeight / 2).attr("y2", waveHeight / 2).attr("stroke", "currentColor").attr("stroke-width", 2);
|
|
135
135
|
const bars = d3.select(svg).selectAll("rect").data(frequencyData);
|
|
136
|
-
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i))).attr("y", (value) => waveHeight / 2 - height(value)).attr("width", barX.bandwidth()).attr("height", (value) => height(value) * 2);
|
|
136
|
+
bars.enter().append("rect").merge(bars).attr("x", (_, i) => barX(String(i)) || 0).attr("y", (value) => waveHeight / 2 - height(value)).attr("width", barX.bandwidth()).attr("height", (value) => height(value) * 2);
|
|
137
137
|
bars.exit().remove();
|
|
138
138
|
}
|
|
139
139
|
async updated() {
|