@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.
Files changed (82) hide show
  1. package/dist/lib/av/EncodedAsset.cjs +561 -0
  2. package/dist/lib/av/{EncodedAsset.mjs → EncodedAsset.js} +18 -13
  3. package/dist/lib/av/MP4File.cjs +182 -0
  4. package/dist/lib/av/{MP4File.mjs → MP4File.js} +15 -10
  5. package/dist/lib/av/msToTimeCode.cjs +15 -0
  6. package/dist/lib/util/awaitMicrotask.cjs +8 -0
  7. package/dist/lib/util/memoize.cjs +14 -0
  8. package/dist/packages/elements/src/EF_FRAMEGEN.cjs +197 -0
  9. package/dist/packages/elements/src/EF_FRAMEGEN.d.ts +45 -0
  10. package/dist/packages/elements/src/{EF_FRAMEGEN.mjs → EF_FRAMEGEN.js} +21 -7
  11. package/dist/packages/elements/src/EF_INTERACTIVE.cjs +4 -0
  12. package/dist/packages/elements/src/EF_INTERACTIVE.d.ts +1 -0
  13. package/dist/packages/elements/src/elements/CrossUpdateController.cjs +16 -0
  14. package/dist/packages/elements/src/elements/CrossUpdateController.d.ts +9 -0
  15. package/dist/packages/elements/src/elements/EFAudio.cjs +53 -0
  16. package/dist/packages/elements/src/elements/EFAudio.d.ts +10 -0
  17. package/dist/packages/elements/src/elements/{EFAudio.mjs → EFAudio.js} +1 -1
  18. package/dist/packages/elements/src/elements/EFCaptions.cjs +171 -0
  19. package/dist/packages/elements/src/elements/EFCaptions.d.ts +39 -0
  20. package/dist/packages/elements/src/elements/{EFCaptions.mjs → EFCaptions.js} +13 -13
  21. package/dist/packages/elements/src/elements/EFImage.cjs +79 -0
  22. package/dist/packages/elements/src/elements/EFImage.d.ts +14 -0
  23. package/dist/packages/elements/src/elements/{EFImage.mjs → EFImage.js} +6 -4
  24. package/dist/packages/elements/src/elements/EFMedia.cjs +334 -0
  25. package/dist/packages/elements/src/elements/EFMedia.d.ts +61 -0
  26. package/dist/packages/elements/src/elements/{EFMedia.mjs → EFMedia.js} +29 -18
  27. package/dist/packages/elements/src/elements/EFSourceMixin.cjs +55 -0
  28. package/dist/packages/elements/src/elements/EFSourceMixin.d.ts +12 -0
  29. package/dist/packages/elements/src/elements/{EFSourceMixin.mjs → EFSourceMixin.js} +1 -1
  30. package/dist/packages/elements/src/elements/EFTemporal.cjs +198 -0
  31. package/dist/packages/elements/src/elements/EFTemporal.d.ts +36 -0
  32. package/dist/packages/elements/src/elements/{EFTemporal.mjs → EFTemporal.js} +4 -7
  33. package/dist/packages/elements/src/elements/EFTimegroup.browsertest.d.ts +12 -0
  34. package/dist/packages/elements/src/elements/EFTimegroup.cjs +343 -0
  35. package/dist/packages/elements/src/elements/EFTimegroup.d.ts +39 -0
  36. package/dist/packages/elements/src/elements/{EFTimegroup.mjs → EFTimegroup.js} +23 -22
  37. package/dist/packages/elements/src/elements/EFTimeline.cjs +15 -0
  38. package/dist/packages/elements/src/elements/EFTimeline.d.ts +3 -0
  39. package/dist/packages/elements/src/elements/{EFTimeline.mjs → EFTimeline.js} +5 -2
  40. package/dist/packages/elements/src/elements/EFVideo.cjs +110 -0
  41. package/dist/packages/elements/src/elements/EFVideo.d.ts +14 -0
  42. package/dist/packages/elements/src/elements/{EFVideo.mjs → EFVideo.js} +2 -2
  43. package/dist/packages/elements/src/elements/EFWaveform.cjs +235 -0
  44. package/dist/packages/elements/src/elements/EFWaveform.d.ts +28 -0
  45. package/dist/packages/elements/src/elements/{EFWaveform.mjs → EFWaveform.js} +14 -14
  46. package/dist/packages/elements/src/elements/FetchMixin.cjs +28 -0
  47. package/dist/packages/elements/src/elements/FetchMixin.d.ts +8 -0
  48. package/dist/packages/elements/src/elements/{FetchMixin.mjs → FetchMixin.js} +1 -1
  49. package/dist/packages/elements/src/elements/TimegroupController.cjs +20 -0
  50. package/dist/packages/elements/src/elements/TimegroupController.d.ts +14 -0
  51. package/dist/packages/elements/src/elements/durationConverter.cjs +8 -0
  52. package/dist/packages/elements/src/elements/durationConverter.d.ts +4 -0
  53. package/dist/packages/elements/src/elements/{durationConverter.mjs → durationConverter.js} +1 -1
  54. package/dist/packages/elements/src/elements/parseTimeToMs.cjs +12 -0
  55. package/dist/packages/elements/src/elements/parseTimeToMs.d.ts +1 -0
  56. package/dist/packages/elements/src/elements/parseTimeToMs.js +12 -0
  57. package/dist/packages/elements/src/elements/util.cjs +11 -0
  58. package/dist/packages/elements/src/elements/util.d.ts +4 -0
  59. package/dist/packages/elements/src/elements/{util.mjs → util.js} +1 -1
  60. package/dist/packages/elements/src/gui/EFFilmstrip.cjs +675 -0
  61. package/dist/packages/elements/src/gui/EFFilmstrip.d.ts +138 -0
  62. package/dist/packages/elements/src/gui/{EFFilmstrip.mjs → EFFilmstrip.js} +48 -34
  63. package/dist/packages/elements/src/gui/EFWorkbench.cjs +199 -0
  64. package/dist/packages/elements/src/gui/EFWorkbench.d.ts +44 -0
  65. package/dist/packages/elements/src/gui/{EFWorkbench.mjs → EFWorkbench.js} +26 -27
  66. package/dist/packages/elements/src/gui/TWMixin.cjs +28 -0
  67. package/dist/packages/elements/src/gui/TWMixin.css.cjs +3 -0
  68. package/dist/packages/elements/src/gui/TWMixin.d.ts +3 -0
  69. package/dist/packages/elements/src/gui/{TWMixin.mjs → TWMixin.js} +4 -3
  70. package/dist/packages/elements/src/index.cjs +47 -0
  71. package/dist/packages/elements/src/index.d.ts +10 -0
  72. package/dist/packages/elements/src/index.js +23 -0
  73. package/package.json +17 -3
  74. package/dist/packages/elements/src/elements/parseTimeToMs.mjs +0 -13
  75. package/dist/packages/elements/src/elements.mjs +0 -12
  76. /package/dist/lib/av/{msToTimeCode.mjs → msToTimeCode.js} +0 -0
  77. /package/dist/lib/util/{awaitMicrotask.mjs → awaitMicrotask.js} +0 -0
  78. /package/dist/lib/util/{memoize.mjs → memoize.js} +0 -0
  79. /package/dist/packages/elements/src/{EF_INTERACTIVE.mjs → EF_INTERACTIVE.js} +0 -0
  80. /package/dist/packages/elements/src/elements/{CrossUpdateController.mjs → CrossUpdateController.js} +0 -0
  81. /package/dist/packages/elements/src/elements/{TimegroupController.mjs → TimegroupController.js} +0 -0
  82. /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.mjs";
5
- import { TimegroupController } from "./TimegroupController.mjs";
6
- import { EF_INTERACTIVE } from "../EF_INTERACTIVE.mjs";
7
- import { deepGetMediaElements } from "./EFMedia.mjs";
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.forEach((node) => {
127
+ for (const node of this.childTemporals) {
128
128
  duration += node.durationMs;
129
- });
129
+ }
130
130
  return duration;
131
- case "contain":
131
+ }
132
+ case "contain": {
132
133
  let maxDuration = 0;
133
- this.childTemporals.forEach((node) => {
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
- animations.forEach((animation) => {
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
- efElements.forEach((el) => {
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;
@@ -0,0 +1,3 @@
1
+ export declare class EFTimeline extends HTMLElement {
2
+ get durationMs(): number;
3
+ }
@@ -1,12 +1,15 @@
1
1
  class EFTimeline extends HTMLElement {
2
2
  get durationMs() {
3
3
  let duration = 0;
4
- this.childNodes.forEach((node) => {
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.mjs";
6
- import { TWMixin } from "../gui/TWMixin.mjs";
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.mjs";
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.mjs";
5
- import { EFTemporal } from "./EFTemporal.mjs";
6
- import { CrossUpdateController } from "./CrossUpdateController.mjs";
7
- import { TWMixin } from "../gui/TWMixin.mjs";
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.mjs";
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", (d, i) => i * barWidth + barPadding / 2).attr(
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() {