@editframe/elements 0.14.0-beta.3 → 0.15.0-beta.3

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.
@@ -1,13 +1,14 @@
1
- import { EFAudio } from "./EFAudio.js";
1
+ import { CSSStyleObserver } from "@bramus/style-observer";
2
2
  import { Task } from "@lit/task";
3
3
  import { html, css, LitElement } from "lit";
4
- import { property, customElement } from "lit/decorators.js";
4
+ import { property, state, customElement } from "lit/decorators.js";
5
5
  import { createRef, ref } from "lit/directives/ref.js";
6
6
  import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
7
+ import { EF_RENDERING } from "../EF_RENDERING.js";
7
8
  import { TWMixin } from "../gui/TWMixin.js";
8
9
  import { CrossUpdateController } from "./CrossUpdateController.js";
9
10
  import { EFTemporal } from "./EFTemporal.js";
10
- import { EFVideo } from "./EFVideo.js";
11
+ import { TargetController } from "./TargetController.js";
11
12
  var __defProp = Object.defineProperty;
12
13
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
14
  var __decorateClass = (decorators, target, key, kind) => {
@@ -23,83 +24,76 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
23
24
  super(...arguments);
24
25
  this.canvasRef = createRef();
25
26
  this.ctx = null;
27
+ this.styleObserver = null;
26
28
  this.mode = "bars";
27
29
  this.color = "currentColor";
28
- this.targetSelector = "";
30
+ this.target = "";
31
+ this.targetElement = null;
32
+ this.lineWidth = 4;
33
+ this.targetController = new TargetController(this);
29
34
  this.frameTask = new Task(this, {
30
35
  autoRun: EF_INTERACTIVE,
31
- args: () => [this.targetElement.audioBufferTask.status],
36
+ args: () => {
37
+ return [
38
+ this.targetElement,
39
+ this.targetElement?.frequencyDataTask.value
40
+ ];
41
+ },
32
42
  task: async () => {
33
- await this.targetElement.audioBufferTask.taskComplete;
43
+ if (!this.targetElement) return;
44
+ await this.targetElement.frequencyDataTask.taskComplete;
34
45
  this.ctx ||= this.initCanvas();
35
46
  const ctx = this.ctx;
36
47
  if (!ctx) return;
37
- if (!this.targetElement.audioBufferTask.value) return;
38
- if (this.targetElement.trimAdjustedOwnCurrentTimeMs > 0) {
39
- const FRAME_DURATION_MS = 48e3 / 1e3;
40
- const FRAME_SMEAR_MS = FRAME_DURATION_MS * 1;
41
- const FRAME_SMEAR_S = FRAME_SMEAR_MS / 1e3;
42
- const audioContext = new OfflineAudioContext(2, 48e3 / 25, 48e3);
43
- const audioBufferSource = audioContext.createBufferSource();
44
- audioBufferSource.buffer = this.targetElement.audioBufferTask.value.buffer;
45
- const analyser = audioContext.createAnalyser();
46
- analyser.fftSize = 128 * 8;
47
- audioBufferSource.connect(analyser);
48
- const startTime = Math.max(
49
- 0,
50
- (this.targetElement.trimAdjustedOwnCurrentTimeMs - this.targetElement.audioBufferTask.value.startOffsetMs) / 1e3
51
- );
52
- audioBufferSource.start(0, startTime, FRAME_SMEAR_S);
53
- await audioContext.startRendering();
54
- const frameData = new Uint8Array(analyser.frequencyBinCount);
55
- analyser.getByteFrequencyData(frameData);
56
- const smoothedData = frameData.slice(0, frameData.length / 2);
57
- if (this.color === "currentColor") {
58
- const computedStyle = getComputedStyle(this);
59
- const currentColor = computedStyle.color;
60
- ctx.strokeStyle = currentColor;
61
- ctx.fillStyle = currentColor;
62
- }
63
- switch (this.mode) {
64
- case "bars":
65
- this.drawBars(ctx, smoothedData);
66
- break;
67
- case "bricks":
68
- this.drawBricks(ctx, smoothedData);
69
- break;
70
- case "curve":
71
- this.drawCurve(ctx, smoothedData);
72
- break;
73
- case "line":
74
- this.drawLine(ctx, smoothedData);
75
- break;
76
- case "pixel":
77
- this.drawPixel(ctx, smoothedData);
78
- break;
79
- case "wave":
80
- this.drawWave(ctx, smoothedData);
81
- break;
82
- case "roundBars":
83
- this.drawRoundBars(ctx, smoothedData);
84
- break;
85
- case "equalizer":
86
- this.drawEqualizer(ctx, smoothedData);
87
- break;
88
- }
48
+ const frequencyData = this.targetElement.frequencyDataTask.value;
49
+ if (!frequencyData) return;
50
+ ctx.save();
51
+ if (this.color === "currentColor") {
52
+ const computedStyle = getComputedStyle(this);
53
+ const currentColor = computedStyle.color;
54
+ ctx.strokeStyle = currentColor;
55
+ ctx.fillStyle = currentColor;
56
+ } else {
57
+ ctx.strokeStyle = this.color;
58
+ ctx.fillStyle = this.color;
89
59
  }
60
+ switch (this.mode) {
61
+ case "bars":
62
+ this.drawBars(ctx, frequencyData);
63
+ break;
64
+ case "bricks":
65
+ this.drawBricks(ctx, frequencyData);
66
+ break;
67
+ case "line":
68
+ this.drawLine(ctx, frequencyData);
69
+ break;
70
+ case "pixel":
71
+ this.drawPixel(ctx, frequencyData);
72
+ break;
73
+ case "wave":
74
+ this.drawWave(ctx, frequencyData);
75
+ break;
76
+ case "spikes":
77
+ this.drawSpikes(ctx, frequencyData);
78
+ break;
79
+ case "roundBars":
80
+ this.drawRoundBars(ctx, frequencyData);
81
+ break;
82
+ }
83
+ ctx.restore();
90
84
  }
91
85
  });
92
86
  }
93
87
  render() {
94
88
  return html`<canvas ${ref(this.canvasRef)}></canvas>`;
95
89
  }
96
- set target(value) {
97
- this.targetSelector = value;
98
- }
99
90
  connectedCallback() {
100
91
  super.connectedCallback();
101
- if (this.targetElement) {
102
- new CrossUpdateController(this.targetElement, this);
92
+ try {
93
+ if (this.targetElement) {
94
+ new CrossUpdateController(this.targetElement, this);
95
+ }
96
+ } catch (e) {
103
97
  }
104
98
  this.resizeObserver = new ResizeObserver(() => {
105
99
  this.resizeCanvas();
@@ -113,11 +107,18 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
113
107
  }
114
108
  });
115
109
  this.mutationObserver.observe(this, { attributes: true });
110
+ if (!EF_RENDERING()) {
111
+ this.styleObserver = new CSSStyleObserver(["color"], () => {
112
+ this.frameTask.run();
113
+ });
114
+ this.styleObserver.attach(this);
115
+ }
116
116
  }
117
117
  disconnectedCallback() {
118
118
  super.disconnectedCallback();
119
119
  this.resizeObserver?.disconnect();
120
120
  this.mutationObserver?.disconnect();
121
+ this.styleObserver?.detach();
121
122
  }
122
123
  resizeCanvas() {
123
124
  this.ctx = this.initCanvas();
@@ -128,7 +129,10 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
128
129
  initCanvas() {
129
130
  const canvas = this.canvasRef.value;
130
131
  if (!canvas) return null;
131
- const rect = this.getBoundingClientRect();
132
+ const rect = {
133
+ width: this.offsetWidth,
134
+ height: this.offsetHeight
135
+ };
132
136
  const dpr = window.devicePixelRatio;
133
137
  canvas.style.width = `${rect.width}px`;
134
138
  canvas.style.height = `${rect.height}px`;
@@ -137,163 +141,233 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
137
141
  const ctx = canvas.getContext("2d");
138
142
  if (!ctx) return null;
139
143
  ctx.reset();
140
- ctx.scale(dpr, dpr);
141
144
  return ctx;
142
145
  }
143
146
  drawBars(ctx, frequencyData) {
144
147
  const canvas = ctx.canvas;
145
- const waveWidth = canvas.width / devicePixelRatio;
146
- const waveHeight = canvas.height / devicePixelRatio;
147
- const barWidth = waveWidth / frequencyData.length * 0.8;
148
- const baseline = waveHeight / 2;
148
+ const waveWidth = canvas.width;
149
+ const waveHeight = canvas.height;
150
+ const totalBars = frequencyData.length;
151
+ const paddingInner = 0.5;
152
+ const paddingOuter = 0.01;
153
+ const availableWidth = waveWidth;
154
+ const barWidth = availableWidth / (totalBars + (totalBars - 1) * paddingInner);
149
155
  ctx.clearRect(0, 0, waveWidth, waveHeight);
156
+ const path = new Path2D();
150
157
  frequencyData.forEach((value, i) => {
151
- const height = value / 255 * (waveHeight / 2);
152
- const x = i * (waveWidth / frequencyData.length);
153
- const y = baseline - height;
154
- ctx.fillRect(x, y, barWidth, Math.max(height * 2, 2));
158
+ const normalizedValue = Math.min(value / 255 * 2, 1);
159
+ const barHeight = normalizedValue * waveHeight;
160
+ const y = (waveHeight - barHeight) / 2;
161
+ const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));
162
+ path.rect(x, y, barWidth, barHeight);
155
163
  });
164
+ ctx.fill(path);
156
165
  }
157
166
  drawBricks(ctx, frequencyData) {
158
167
  const canvas = ctx.canvas;
159
- const waveWidth = canvas.width / devicePixelRatio;
160
- const waveHeight = canvas.height / devicePixelRatio;
161
- const brickWidth = waveWidth / frequencyData.length;
162
- const brickHeightFactor = waveHeight / 255 / 2;
163
- const brickPadding = 2;
164
- const midHeight = waveHeight / 2;
165
- ctx.clearRect(0, 0, waveWidth, waveHeight);
166
- ctx.beginPath();
167
- ctx.setLineDash([2]);
168
- ctx.lineWidth = 4;
169
- ctx.moveTo(0, midHeight);
170
- ctx.lineTo(waveWidth, midHeight);
171
- ctx.stroke();
172
- ctx.setLineDash([]);
173
- frequencyData.forEach((value, i) => {
174
- const x = i * brickWidth;
175
- const height = value * brickHeightFactor * 2;
176
- const y = midHeight - height / 2;
177
- ctx.fillRect(x, y, brickWidth - brickPadding, height);
178
- });
179
- }
180
- drawLine(ctx, frequencyData) {
181
- const canvas = ctx.canvas;
182
- const waveWidth = canvas.width / devicePixelRatio;
183
- const waveHeight = canvas.height / devicePixelRatio;
168
+ const waveWidth = canvas.width;
169
+ const waveHeight = canvas.height;
184
170
  ctx.clearRect(0, 0, waveWidth, waveHeight);
185
- ctx.beginPath();
171
+ const path = new Path2D();
172
+ const columnWidth = waveWidth / frequencyData.length;
173
+ const boxSize = columnWidth * 0.9;
174
+ const verticalGap = boxSize * 0.2;
175
+ const maxBricks = Math.floor(waveHeight / (boxSize + verticalGap));
186
176
  frequencyData.forEach((value, i) => {
187
- const x = i / frequencyData.length * waveWidth;
188
- const y = (1 - value / 255) * waveHeight;
189
- if (i === 0) {
190
- ctx.moveTo(x, y);
191
- } else {
192
- ctx.lineTo(x, y);
177
+ const normalizedValue = Math.min(value / 255 * 2, 1);
178
+ const brickCount = Math.floor(normalizedValue * maxBricks);
179
+ for (let j = 0; j < brickCount; j++) {
180
+ const x = columnWidth * i;
181
+ const y = waveHeight - (j + 1) * (boxSize + verticalGap);
182
+ path.rect(x, y, boxSize, boxSize);
193
183
  }
194
184
  });
195
- ctx.lineWidth = 4;
196
- ctx.stroke();
185
+ ctx.fill(path);
197
186
  }
198
187
  drawRoundBars(ctx, frequencyData) {
199
188
  const canvas = ctx.canvas;
200
- const waveWidth = canvas.width / devicePixelRatio;
201
- const waveHeight = canvas.height / devicePixelRatio;
202
- const barWidth = waveWidth / frequencyData.length * 0.5;
203
- const baseline = waveHeight / 2;
204
- const maxHeight = waveHeight / 2;
189
+ const waveWidth = canvas.width;
190
+ const waveHeight = canvas.height;
191
+ const totalBars = frequencyData.length;
192
+ const paddingInner = 0.5;
193
+ const paddingOuter = 0.01;
194
+ const availableWidth = waveWidth;
195
+ const barWidth = availableWidth / (totalBars + (totalBars - 1) * paddingInner);
205
196
  ctx.clearRect(0, 0, waveWidth, waveHeight);
197
+ const path = new Path2D();
206
198
  frequencyData.forEach((value, i) => {
207
- const height = value / 255 * maxHeight;
208
- const x = i * (waveWidth / frequencyData.length);
209
- const y = baseline - height;
210
- const radius = barWidth / 2;
211
- ctx.beginPath();
212
- ctx.roundRect(x, y, barWidth, Math.max(height * 2, 2), radius);
213
- ctx.fill();
199
+ const normalizedValue = Math.min(value / 255 * 2, 1);
200
+ const height = normalizedValue * waveHeight;
201
+ const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));
202
+ const y = (waveHeight - height) / 2;
203
+ path.roundRect(x, y, barWidth, height, barWidth / 2);
214
204
  });
205
+ ctx.fill(path);
215
206
  }
216
207
  drawEqualizer(ctx, frequencyData) {
217
208
  const canvas = ctx.canvas;
218
- const waveWidth = canvas.width / devicePixelRatio;
219
- const waveHeight = canvas.height / devicePixelRatio;
220
- const barWidth = waveWidth / frequencyData.length * 0.8;
209
+ const waveWidth = canvas.width;
210
+ const waveHeight = canvas.height;
221
211
  const baseline = waveHeight / 2;
212
+ const barWidth = waveWidth / frequencyData.length * 0.8;
222
213
  ctx.clearRect(0, 0, waveWidth, waveHeight);
223
- ctx.beginPath();
224
- ctx.lineWidth = 2;
225
- ctx.moveTo(0, baseline);
226
- ctx.lineTo(waveWidth, baseline);
227
- ctx.stroke();
214
+ const baselinePath = new Path2D();
215
+ const barsPath = new Path2D();
216
+ baselinePath.moveTo(0, baseline);
217
+ baselinePath.lineTo(waveWidth, baseline);
228
218
  frequencyData.forEach((value, i) => {
229
219
  const height = value / 255 * (waveHeight / 2);
230
220
  const x = i * (waveWidth / frequencyData.length);
231
221
  const y = baseline - height;
232
- ctx.fillRect(x, y, barWidth, Math.max(height * 2, 1));
222
+ barsPath.rect(x, y, barWidth, Math.max(height * 2, 1));
233
223
  });
224
+ ctx.lineWidth = 2;
225
+ ctx.stroke(baselinePath);
226
+ ctx.fill(barsPath);
234
227
  }
235
- drawCurve(ctx, frequencyData) {
228
+ drawLine(ctx, frequencyData) {
236
229
  const canvas = ctx.canvas;
237
- const waveWidth = canvas.width / devicePixelRatio;
238
- const waveHeight = canvas.height / devicePixelRatio;
230
+ const waveWidth = canvas.width;
231
+ const waveHeight = canvas.height;
239
232
  ctx.clearRect(0, 0, waveWidth, waveHeight);
240
- ctx.beginPath();
233
+ const path = new Path2D();
241
234
  frequencyData.forEach((value, i) => {
242
235
  const x = i / frequencyData.length * waveWidth;
243
236
  const y = (1 - value / 255) * waveHeight;
244
237
  if (i === 0) {
245
- ctx.moveTo(x, y);
238
+ path.moveTo(x, y);
246
239
  } else {
247
- ctx.lineTo(x, y);
240
+ path.lineTo(x, y);
248
241
  }
249
242
  });
250
- ctx.lineWidth = 4;
251
- ctx.stroke();
243
+ ctx.lineWidth = this.lineWidth;
244
+ ctx.stroke(path);
252
245
  }
253
246
  drawPixel(ctx, frequencyData) {
254
247
  const canvas = ctx.canvas;
255
- const waveWidth = canvas.width / devicePixelRatio;
256
- const waveHeight = canvas.height / devicePixelRatio;
248
+ const waveWidth = canvas.width;
249
+ const waveHeight = canvas.height;
257
250
  const baseline = waveHeight / 2;
258
- const barWidth = waveWidth / frequencyData.length * 0.97;
251
+ const barWidth = waveWidth / frequencyData.length;
259
252
  ctx.clearRect(0, 0, waveWidth, waveHeight);
253
+ const path = new Path2D();
260
254
  frequencyData.forEach((value, i) => {
255
+ const normalizedValue = Math.min(value / 255 * 2, 1);
261
256
  const x = i * (waveWidth / frequencyData.length);
262
- const barHeight = value / 255 * baseline;
257
+ const barHeight = normalizedValue * (waveHeight / 2);
263
258
  const y = baseline - barHeight;
264
- ctx.fillRect(x, y, barWidth, barHeight * 2);
259
+ path.rect(x, y, barWidth, barHeight * 2);
265
260
  });
261
+ ctx.fill(path);
266
262
  }
267
263
  drawWave(ctx, frequencyData) {
268
264
  const canvas = ctx.canvas;
269
- const waveWidth = canvas.width / devicePixelRatio;
270
- const waveHeight = canvas.height / devicePixelRatio;
271
- const baseline = waveHeight / 2;
272
- const barWidth = waveWidth / frequencyData.length * 0.97;
265
+ const waveWidth = canvas.width;
266
+ const waveHeight = canvas.height;
267
+ const paddingOuter = 0.01;
268
+ const availableWidth = waveWidth * (1 - 2 * paddingOuter);
269
+ const startX = waveWidth * paddingOuter;
273
270
  ctx.clearRect(0, 0, waveWidth, waveHeight);
274
- ctx.beginPath();
275
- ctx.moveTo(0, baseline);
276
- ctx.lineTo(waveWidth, baseline);
277
- ctx.strokeStyle = this.color;
278
- ctx.lineWidth = 1;
279
- ctx.stroke();
271
+ const path = new Path2D();
272
+ const firstValue = Math.min((frequencyData[0] ?? 0) / 255 * 2, 1);
273
+ const firstY = (waveHeight - firstValue * waveHeight) / 2;
274
+ path.moveTo(startX, firstY);
280
275
  frequencyData.forEach((value, i) => {
281
- const x = i * (waveWidth / frequencyData.length);
282
- const barHeight = value / 255 * (waveHeight / 2);
283
- const y = baseline - barHeight;
284
- ctx.fillRect(x, y, barWidth, barHeight * 2);
276
+ const normalizedValue = Math.min(value / 255 * 2, 1);
277
+ const x = startX + i / (frequencyData.length - 1) * availableWidth;
278
+ const barHeight = normalizedValue * waveHeight;
279
+ const y = (waveHeight - barHeight) / 2;
280
+ if (i === 0) {
281
+ path.moveTo(x, y);
282
+ } else {
283
+ const prevX = startX + (i - 1) / (frequencyData.length - 1) * availableWidth;
284
+ const prevValue = Math.min((frequencyData[i - 1] ?? 0) / 255 * 2, 1);
285
+ const prevBarHeight = prevValue * waveHeight;
286
+ const prevY = (waveHeight - prevBarHeight) / 2;
287
+ const xc = (prevX + x) / 2;
288
+ const yc = (prevY + y) / 2;
289
+ path.quadraticCurveTo(prevX, prevY, xc, yc);
290
+ }
285
291
  });
292
+ for (let i = frequencyData.length - 1; i >= 0; i--) {
293
+ const normalizedValue = Math.min((frequencyData[i] ?? 0) / 255 * 2, 1);
294
+ const x = startX + i / (frequencyData.length - 1) * availableWidth;
295
+ const barHeight = normalizedValue * waveHeight;
296
+ const y = (waveHeight + barHeight) / 2;
297
+ if (i === frequencyData.length - 1) {
298
+ path.lineTo(x, y);
299
+ } else {
300
+ const nextX = startX + (i + 1) / (frequencyData.length - 1) * availableWidth;
301
+ const nextValue = Math.min((frequencyData[i + 1] ?? 0) / 255 * 2, 1);
302
+ const nextBarHeight = nextValue * waveHeight;
303
+ const nextY = (waveHeight + nextBarHeight) / 2;
304
+ const xc = (nextX + x) / 2;
305
+ const yc = (nextY + y) / 2;
306
+ path.quadraticCurveTo(nextX, nextY, xc, yc);
307
+ }
308
+ }
309
+ const lastY = (waveHeight + firstValue * waveHeight) / 2;
310
+ const controlX = startX;
311
+ const controlY = (lastY + firstY) / 2;
312
+ path.quadraticCurveTo(controlX, controlY, startX, firstY);
313
+ ctx.fill(path);
314
+ }
315
+ drawSpikes(ctx, frequencyData) {
316
+ const canvas = ctx.canvas;
317
+ const waveWidth = canvas.width;
318
+ const waveHeight = canvas.height;
319
+ const paddingOuter = 0.01;
320
+ const availableWidth = waveWidth * (1 - 2 * paddingOuter);
321
+ const startX = waveWidth * paddingOuter;
322
+ ctx.clearRect(0, 0, waveWidth, waveHeight);
323
+ const path = new Path2D();
324
+ const firstValue = (frequencyData[0] ?? 0) / 255;
325
+ const firstY = (waveHeight - firstValue * waveHeight) / 2;
326
+ path.moveTo(startX, firstY);
327
+ frequencyData.forEach((value, i) => {
328
+ const normalizedValue = Math.min(value / 255 * 2, 1);
329
+ const x = startX + i / (frequencyData.length - 1) * availableWidth;
330
+ const barHeight = normalizedValue * (waveHeight / 2);
331
+ const y = (waveHeight - barHeight * 2) / 2;
332
+ if (i === 0) {
333
+ path.moveTo(x, y);
334
+ } else {
335
+ const prevX = startX + (i - 1) / (frequencyData.length - 1) * availableWidth;
336
+ const prevValue = (frequencyData[i - 1] ?? 0) / 255;
337
+ const prevBarHeight = prevValue * (waveHeight / 2);
338
+ const prevY = (waveHeight - prevBarHeight * 2) / 2;
339
+ const xc = (prevX + x) / 2;
340
+ const yc = (prevY + y) / 2;
341
+ path.quadraticCurveTo(prevX, prevY, xc, yc);
342
+ }
343
+ });
344
+ for (let i = frequencyData.length - 1; i >= 0; i--) {
345
+ const normalizedValue = Math.min((frequencyData[i] ?? 0) / 255 * 2, 1);
346
+ const x = startX + i / (frequencyData.length - 1) * availableWidth;
347
+ const barHeight = normalizedValue * (waveHeight / 2);
348
+ const y = (waveHeight + barHeight * 2) / 2;
349
+ if (i === frequencyData.length - 1) {
350
+ path.lineTo(x, y);
351
+ } else {
352
+ const nextX = startX + (i + 1) / (frequencyData.length - 1) * availableWidth;
353
+ const nextValue = (frequencyData[i + 1] ?? 0) / 255;
354
+ const nextBarHeight = nextValue * (waveHeight / 2);
355
+ const nextY = (waveHeight + nextBarHeight * 2) / 2;
356
+ const xc = (nextX + x) / 2;
357
+ const yc = (nextY + y) / 2;
358
+ path.quadraticCurveTo(nextX, nextY, xc, yc);
359
+ }
360
+ }
361
+ const lastY = (waveHeight + firstValue * waveHeight) / 2;
362
+ const controlX = startX;
363
+ const controlY = (lastY + firstY) / 2;
364
+ path.quadraticCurveTo(controlX, controlY, startX, firstY);
365
+ ctx.fill(path);
286
366
  }
287
367
  get durationMs() {
368
+ if (!this.targetElement) return 0;
288
369
  return this.targetElement.durationMs;
289
370
  }
290
- get targetElement() {
291
- const target = document.getElementById(this.targetSelector ?? "");
292
- if (target instanceof EFAudio || target instanceof EFVideo) {
293
- return target;
294
- }
295
- throw new Error("Invalid target, must be an EFAudio or EFVideo element");
296
- }
297
371
  updated(changedProperties) {
298
372
  super.updated(changedProperties);
299
373
  if (changedProperties.size > 0) {
@@ -326,8 +400,14 @@ __decorateClass([
326
400
  property({ type: String })
327
401
  ], EFWaveform.prototype, "color", 2);
328
402
  __decorateClass([
329
- property({ type: String, attribute: "target", reflect: true })
330
- ], EFWaveform.prototype, "targetSelector", 2);
403
+ property({ type: String, reflect: true })
404
+ ], EFWaveform.prototype, "target", 2);
405
+ __decorateClass([
406
+ state()
407
+ ], EFWaveform.prototype, "targetElement", 2);
408
+ __decorateClass([
409
+ property({ type: Number, attribute: "line-width" })
410
+ ], EFWaveform.prototype, "lineWidth", 2);
331
411
  EFWaveform = __decorateClass([
332
412
  customElement("ef-waveform")
333
413
  ], EFWaveform);
@@ -0,0 +1,25 @@
1
+ import { LitElement, ReactiveController } from 'lit';
2
+ type Constructor<T = {}> = new (...args: any[]) => T;
3
+ export declare class TargetableMixinInterface {
4
+ id: string;
5
+ }
6
+ export declare const isEFTargetable: (obj: any) => obj is TargetableMixinInterface;
7
+ export declare const EFTargetable: <T extends Constructor<LitElement>>(superClass: T) => T;
8
+ export declare class TargetController implements ReactiveController {
9
+ private host;
10
+ private targetController;
11
+ private currentTargetString;
12
+ constructor(host: LitElement & {
13
+ targetElement: Element | null;
14
+ target: string;
15
+ });
16
+ private registryCallback;
17
+ private updateTarget;
18
+ private connectToTarget;
19
+ private disconnectFromTarget;
20
+ private get registry();
21
+ hostDisconnected(): void;
22
+ hostConnected(): void;
23
+ hostUpdate(): void;
24
+ }
25
+ export {};