@editframe/elements 0.15.0-beta.12 → 0.15.0-beta.14
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/elements/EFMedia.d.ts +4 -4
- package/dist/elements/EFMedia.js +57 -46
- package/dist/elements/EFWaveform.d.ts +1 -3
- package/dist/elements/EFWaveform.js +21 -104
- package/dist/gui/TWMixin.js +7 -3
- package/package.json +2 -2
- package/src/elements/EFMedia.ts +80 -54
- package/src/elements/EFWaveform.ts +29 -155
- package/src/gui/TWMixin.ts +8 -4
- package/types.json +1 -1
|
@@ -45,15 +45,8 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
45
45
|
type: String,
|
|
46
46
|
attribute: "mode",
|
|
47
47
|
})
|
|
48
|
-
mode:
|
|
49
|
-
|
|
50
|
-
| "bars"
|
|
51
|
-
| "bricks"
|
|
52
|
-
| "line"
|
|
53
|
-
| "curve"
|
|
54
|
-
| "pixel"
|
|
55
|
-
| "wave"
|
|
56
|
-
| "spikes" = "bars";
|
|
48
|
+
mode: "roundBars" | "bars" | "bricks" | "line" | "curve" | "pixel" | "wave" =
|
|
49
|
+
"bars";
|
|
57
50
|
|
|
58
51
|
@property({ type: String })
|
|
59
52
|
color = "currentColor";
|
|
@@ -164,7 +157,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
164
157
|
const path = new Path2D();
|
|
165
158
|
|
|
166
159
|
frequencyData.forEach((value, i) => {
|
|
167
|
-
const normalizedValue = Math.
|
|
160
|
+
const normalizedValue = Math.abs(value - 128) / 128;
|
|
168
161
|
const barHeight = normalizedValue * waveHeight;
|
|
169
162
|
const y = (waveHeight - barHeight) / 2;
|
|
170
163
|
const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));
|
|
@@ -190,7 +183,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
190
183
|
const maxBricks = Math.floor(waveHeight / (boxSize + verticalGap)); // Account for gaps in height calculation
|
|
191
184
|
|
|
192
185
|
frequencyData.forEach((value, i) => {
|
|
193
|
-
const normalizedValue = Math.
|
|
186
|
+
const normalizedValue = Math.abs(value - 128) / 128;
|
|
194
187
|
const brickCount = Math.floor(normalizedValue * maxBricks);
|
|
195
188
|
|
|
196
189
|
for (let j = 0; j < brickCount; j++) {
|
|
@@ -225,7 +218,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
225
218
|
const path = new Path2D();
|
|
226
219
|
|
|
227
220
|
frequencyData.forEach((value, i) => {
|
|
228
|
-
const normalizedValue = Math.
|
|
221
|
+
const normalizedValue = Math.abs(value - 128) / 128;
|
|
229
222
|
const height = normalizedValue * waveHeight; // Use full wave height like in drawBars
|
|
230
223
|
const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));
|
|
231
224
|
const y = (waveHeight - height) / 2; // Center vertically
|
|
@@ -238,42 +231,6 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
238
231
|
ctx.fill(path);
|
|
239
232
|
}
|
|
240
233
|
|
|
241
|
-
protected drawEqualizer(
|
|
242
|
-
ctx: CanvasRenderingContext2D,
|
|
243
|
-
frequencyData: Uint8Array,
|
|
244
|
-
) {
|
|
245
|
-
const canvas = ctx.canvas;
|
|
246
|
-
const waveWidth = canvas.width;
|
|
247
|
-
const waveHeight = canvas.height;
|
|
248
|
-
const baseline = waveHeight / 2;
|
|
249
|
-
const barWidth = (waveWidth / frequencyData.length) * 0.8;
|
|
250
|
-
|
|
251
|
-
ctx.clearRect(0, 0, waveWidth, waveHeight);
|
|
252
|
-
|
|
253
|
-
// Create paths for baseline and bars
|
|
254
|
-
const baselinePath = new Path2D();
|
|
255
|
-
const barsPath = new Path2D();
|
|
256
|
-
|
|
257
|
-
// Draw baseline
|
|
258
|
-
baselinePath.moveTo(0, baseline);
|
|
259
|
-
baselinePath.lineTo(waveWidth, baseline);
|
|
260
|
-
|
|
261
|
-
// Draw bars
|
|
262
|
-
frequencyData.forEach((value, i) => {
|
|
263
|
-
const height = (value / 255) * (waveHeight / 2);
|
|
264
|
-
const x = i * (waveWidth / frequencyData.length);
|
|
265
|
-
const y = baseline - height;
|
|
266
|
-
barsPath.rect(x, y, barWidth, Math.max(height * 2, 1));
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
// Render baseline
|
|
270
|
-
ctx.lineWidth = 2;
|
|
271
|
-
ctx.stroke(baselinePath);
|
|
272
|
-
|
|
273
|
-
// Render bars
|
|
274
|
-
ctx.fill(barsPath);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
234
|
protected drawLine(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array) {
|
|
278
235
|
const canvas = ctx.canvas;
|
|
279
236
|
const waveWidth = canvas.width;
|
|
@@ -283,7 +240,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
283
240
|
const path = new Path2D();
|
|
284
241
|
|
|
285
242
|
// Sample fewer points to make sharp angles more visible
|
|
286
|
-
const sampleRate =
|
|
243
|
+
const sampleRate = 1; // Only use every 4th point
|
|
287
244
|
|
|
288
245
|
for (let i = 0; i < frequencyData.length; i += sampleRate) {
|
|
289
246
|
const x = (i / frequencyData.length) * waveWidth;
|
|
@@ -295,7 +252,6 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
295
252
|
path.lineTo(x, y);
|
|
296
253
|
}
|
|
297
254
|
}
|
|
298
|
-
|
|
299
255
|
// Ensure we draw to the end
|
|
300
256
|
const lastX = waveWidth;
|
|
301
257
|
const lastY =
|
|
@@ -351,7 +307,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
351
307
|
const path = new Path2D();
|
|
352
308
|
|
|
353
309
|
frequencyData.forEach((value, i) => {
|
|
354
|
-
const normalizedValue = Math.
|
|
310
|
+
const normalizedValue = Math.abs(value - 128) / 128;
|
|
355
311
|
const x = i * (waveWidth / frequencyData.length);
|
|
356
312
|
const barHeight = normalizedValue * (waveHeight / 2); // Half height since we extend both ways
|
|
357
313
|
const y = baseline - barHeight;
|
|
@@ -372,129 +328,50 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
372
328
|
ctx.clearRect(0, 0, waveWidth, waveHeight);
|
|
373
329
|
const path = new Path2D();
|
|
374
330
|
|
|
375
|
-
//
|
|
376
|
-
const firstValue =
|
|
377
|
-
const firstY =
|
|
331
|
+
// For PCM data, normalize around the center point (128)
|
|
332
|
+
const firstValue = ((frequencyData[0] ?? 128) - 128) / 128;
|
|
333
|
+
const firstY = waveHeight / 2 + (firstValue * waveHeight) / 2;
|
|
378
334
|
path.moveTo(startX, firstY);
|
|
379
335
|
|
|
380
336
|
// Draw top half
|
|
381
337
|
frequencyData.forEach((value, i) => {
|
|
382
|
-
const normalizedValue =
|
|
338
|
+
const normalizedValue = (value - 128) / 128; // Center around 0 (-1 to 1)
|
|
383
339
|
const x = startX + (i / (frequencyData.length - 1)) * availableWidth;
|
|
384
|
-
const
|
|
385
|
-
const y = (waveHeight - barHeight) / 2;
|
|
340
|
+
const y = waveHeight / 2 - (normalizedValue * waveHeight) / 2; // Create downward curve for top
|
|
386
341
|
|
|
387
342
|
if (i === 0) {
|
|
388
343
|
path.moveTo(x, y);
|
|
389
344
|
} else {
|
|
390
345
|
const prevX =
|
|
391
346
|
startX + ((i - 1) / (frequencyData.length - 1)) * availableWidth;
|
|
392
|
-
const prevValue =
|
|
393
|
-
const
|
|
394
|
-
const prevY = (waveHeight - prevBarHeight) / 2;
|
|
347
|
+
const prevValue = ((frequencyData[i - 1] ?? 128) - 128) / 128;
|
|
348
|
+
const prevY = waveHeight / 2 - (prevValue * waveHeight) / 2; // Create downward curve for top
|
|
395
349
|
const xc = (prevX + x) / 2;
|
|
396
|
-
const yc = (prevY + y) / 2;
|
|
397
|
-
path.quadraticCurveTo(prevX, prevY, xc, yc);
|
|
350
|
+
const yc = (prevY + y) / 2; // Control point for smooth curve
|
|
351
|
+
path.quadraticCurveTo(prevX, prevY, xc, yc); // Maintain the curve
|
|
398
352
|
}
|
|
399
353
|
});
|
|
400
354
|
|
|
401
|
-
// Draw bottom
|
|
355
|
+
// Draw bottom mirror
|
|
402
356
|
for (let i = frequencyData.length - 1; i >= 0; i--) {
|
|
403
|
-
const normalizedValue =
|
|
357
|
+
const normalizedValue = ((frequencyData[i] ?? 128) - 128) / 128; // Center around 0 (-1 to 1)
|
|
404
358
|
const x = startX + (i / (frequencyData.length - 1)) * availableWidth;
|
|
405
|
-
const
|
|
406
|
-
const y = (waveHeight + barHeight) / 2;
|
|
359
|
+
const y = waveHeight / 2 + (normalizedValue * waveHeight) / 2; // Create upward curve for bottom
|
|
407
360
|
|
|
408
361
|
if (i === frequencyData.length - 1) {
|
|
409
362
|
path.lineTo(x, y);
|
|
410
363
|
} else {
|
|
411
364
|
const nextX =
|
|
412
365
|
startX + ((i + 1) / (frequencyData.length - 1)) * availableWidth;
|
|
413
|
-
const nextValue =
|
|
414
|
-
const
|
|
415
|
-
const nextY = (waveHeight + nextBarHeight) / 2;
|
|
366
|
+
const nextValue = ((frequencyData[i + 1] ?? 128) - 128) / 128;
|
|
367
|
+
const nextY = waveHeight / 2 + (nextValue * waveHeight) / 2; // Create upward curve for bottom
|
|
416
368
|
const xc = (nextX + x) / 2;
|
|
417
|
-
const yc = (nextY + y) / 2;
|
|
418
|
-
path.quadraticCurveTo(nextX, nextY, xc, yc);
|
|
369
|
+
const yc = (nextY + y) / 2; // Control point for smooth curve
|
|
370
|
+
path.quadraticCurveTo(nextX, nextY, xc, yc); // Maintain the curve
|
|
419
371
|
}
|
|
420
372
|
}
|
|
421
373
|
|
|
422
|
-
|
|
423
|
-
const lastY = (waveHeight + firstValue * waveHeight) / 2;
|
|
424
|
-
const controlX = startX;
|
|
425
|
-
const controlY = (lastY + firstY) / 2;
|
|
426
|
-
path.quadraticCurveTo(controlX, controlY, startX, firstY);
|
|
427
|
-
|
|
428
|
-
ctx.fill(path);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
protected drawSpikes(
|
|
432
|
-
ctx: CanvasRenderingContext2D,
|
|
433
|
-
frequencyData: Uint8Array,
|
|
434
|
-
) {
|
|
435
|
-
const canvas = ctx.canvas;
|
|
436
|
-
const waveWidth = canvas.width;
|
|
437
|
-
const waveHeight = canvas.height;
|
|
438
|
-
const paddingOuter = 0.01;
|
|
439
|
-
const availableWidth = waveWidth * (1 - 2 * paddingOuter);
|
|
440
|
-
const startX = waveWidth * paddingOuter;
|
|
441
|
-
|
|
442
|
-
ctx.clearRect(0, 0, waveWidth, waveHeight);
|
|
443
|
-
const path = new Path2D();
|
|
444
|
-
|
|
445
|
-
// Draw top curve
|
|
446
|
-
const firstValue = (frequencyData[0] ?? 0) / 255;
|
|
447
|
-
const firstY = (waveHeight - firstValue * waveHeight) / 2;
|
|
448
|
-
path.moveTo(startX, firstY);
|
|
449
|
-
|
|
450
|
-
// Draw top half
|
|
451
|
-
frequencyData.forEach((value, i) => {
|
|
452
|
-
const normalizedValue = Math.min((value / 255) * 2, 1);
|
|
453
|
-
const x = startX + (i / (frequencyData.length - 1)) * availableWidth;
|
|
454
|
-
const barHeight = normalizedValue * (waveHeight / 2);
|
|
455
|
-
const y = (waveHeight - barHeight * 2) / 2;
|
|
456
|
-
|
|
457
|
-
if (i === 0) {
|
|
458
|
-
path.moveTo(x, y);
|
|
459
|
-
} else {
|
|
460
|
-
const prevX =
|
|
461
|
-
startX + ((i - 1) / (frequencyData.length - 1)) * availableWidth;
|
|
462
|
-
const prevValue = (frequencyData[i - 1] ?? 0) / 255;
|
|
463
|
-
const prevBarHeight = prevValue * (waveHeight / 2);
|
|
464
|
-
const prevY = (waveHeight - prevBarHeight * 2) / 2;
|
|
465
|
-
const xc = (prevX + x) / 2;
|
|
466
|
-
const yc = (prevY + y) / 2;
|
|
467
|
-
path.quadraticCurveTo(prevX, prevY, xc, yc);
|
|
468
|
-
}
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
// Draw bottom half
|
|
472
|
-
for (let i = frequencyData.length - 1; i >= 0; i--) {
|
|
473
|
-
const normalizedValue = Math.min(((frequencyData[i] ?? 0) / 255) * 2, 1);
|
|
474
|
-
const x = startX + (i / (frequencyData.length - 1)) * availableWidth;
|
|
475
|
-
const barHeight = normalizedValue * (waveHeight / 2);
|
|
476
|
-
const y = (waveHeight + barHeight * 2) / 2;
|
|
477
|
-
|
|
478
|
-
if (i === frequencyData.length - 1) {
|
|
479
|
-
path.lineTo(x, y);
|
|
480
|
-
} else {
|
|
481
|
-
const nextX =
|
|
482
|
-
startX + ((i + 1) / (frequencyData.length - 1)) * availableWidth;
|
|
483
|
-
const nextValue = (frequencyData[i + 1] ?? 0) / 255;
|
|
484
|
-
const nextBarHeight = nextValue * (waveHeight / 2);
|
|
485
|
-
const nextY = (waveHeight + nextBarHeight * 2) / 2;
|
|
486
|
-
const xc = (nextX + x) / 2;
|
|
487
|
-
const yc = (nextY + y) / 2;
|
|
488
|
-
path.quadraticCurveTo(nextX, nextY, xc, yc);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
// Close the path with a smooth curve
|
|
493
|
-
const lastY = (waveHeight + firstValue * waveHeight) / 2;
|
|
494
|
-
const controlX = startX;
|
|
495
|
-
const controlY = (lastY + firstY) / 2;
|
|
496
|
-
path.quadraticCurveTo(controlX, controlY, startX, firstY);
|
|
497
|
-
|
|
374
|
+
path.closePath();
|
|
498
375
|
ctx.fill(path);
|
|
499
376
|
}
|
|
500
377
|
|
|
@@ -530,10 +407,10 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
530
407
|
|
|
531
408
|
switch (this.mode) {
|
|
532
409
|
case "bars":
|
|
533
|
-
this.drawBars(ctx,
|
|
410
|
+
this.drawBars(ctx, byteTimeData);
|
|
534
411
|
break;
|
|
535
412
|
case "bricks":
|
|
536
|
-
this.drawBricks(ctx,
|
|
413
|
+
this.drawBricks(ctx, byteTimeData);
|
|
537
414
|
break;
|
|
538
415
|
case "line":
|
|
539
416
|
this.drawLine(ctx, byteTimeData);
|
|
@@ -542,16 +419,13 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
|
|
|
542
419
|
this.drawCurve(ctx, byteTimeData);
|
|
543
420
|
break;
|
|
544
421
|
case "pixel":
|
|
545
|
-
this.drawPixel(ctx,
|
|
422
|
+
this.drawPixel(ctx, byteTimeData);
|
|
546
423
|
break;
|
|
547
424
|
case "wave":
|
|
548
|
-
this.drawWave(ctx,
|
|
549
|
-
break;
|
|
550
|
-
case "spikes":
|
|
551
|
-
this.drawSpikes(ctx, frequencyData);
|
|
425
|
+
this.drawWave(ctx, byteTimeData);
|
|
552
426
|
break;
|
|
553
427
|
case "roundBars":
|
|
554
|
-
this.drawRoundBars(ctx,
|
|
428
|
+
this.drawRoundBars(ctx, byteTimeData);
|
|
555
429
|
break;
|
|
556
430
|
}
|
|
557
431
|
|
package/src/gui/TWMixin.ts
CHANGED
|
@@ -25,12 +25,16 @@ export function TWMixin<T extends new (...args: any[]) => LitElement>(Base: T) {
|
|
|
25
25
|
const constructorStylesheets: CSSStyleSheet[] = [];
|
|
26
26
|
const constructorStyles = (("styles" in this.constructor &&
|
|
27
27
|
this.constructor.styles) ||
|
|
28
|
-
[]) as CSSResult[];
|
|
28
|
+
[]) as CSSResult | CSSResult[];
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
if (Array.isArray(constructorStyles)) {
|
|
31
|
+
for (const item of constructorStyles) {
|
|
32
|
+
if (item.styleSheet) {
|
|
33
|
+
constructorStylesheets.push(item.styleSheet);
|
|
34
|
+
}
|
|
33
35
|
}
|
|
36
|
+
} else if (constructorStyles.styleSheet) {
|
|
37
|
+
constructorStylesheets.push(constructorStyles.styleSheet);
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
if (renderRoot?.adoptedStyleSheets) {
|