@editframe/elements 0.15.0-beta.9 → 0.16.0-beta.1

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 (52) hide show
  1. package/dist/EF_FRAMEGEN.d.ts +14 -10
  2. package/dist/EF_FRAMEGEN.js +17 -28
  3. package/dist/elements/EFCaptions.js +0 -7
  4. package/dist/elements/EFImage.js +0 -4
  5. package/dist/elements/EFMedia.d.ts +13 -8
  6. package/dist/elements/EFMedia.js +163 -146
  7. package/dist/elements/EFSourceMixin.js +2 -1
  8. package/dist/elements/EFTemporal.browsertest.d.ts +4 -3
  9. package/dist/elements/EFTemporal.d.ts +14 -11
  10. package/dist/elements/EFTemporal.js +63 -87
  11. package/dist/elements/EFTimegroup.d.ts +2 -4
  12. package/dist/elements/EFTimegroup.js +15 -103
  13. package/dist/elements/EFVideo.js +3 -1
  14. package/dist/elements/EFWaveform.d.ts +1 -1
  15. package/dist/elements/EFWaveform.js +11 -28
  16. package/dist/elements/durationConverter.d.ts +8 -8
  17. package/dist/elements/durationConverter.js +2 -2
  18. package/dist/elements/updateAnimations.d.ts +9 -0
  19. package/dist/elements/updateAnimations.js +62 -0
  20. package/dist/getRenderInfo.d.ts +51 -0
  21. package/dist/getRenderInfo.js +72 -0
  22. package/dist/gui/EFFilmstrip.js +7 -16
  23. package/dist/gui/EFFitScale.d.ts +27 -0
  24. package/dist/gui/EFFitScale.js +138 -0
  25. package/dist/gui/EFWorkbench.d.ts +2 -5
  26. package/dist/gui/EFWorkbench.js +11 -56
  27. package/dist/gui/TWMixin.css.js +1 -1
  28. package/dist/gui/TWMixin.js +14 -2
  29. package/dist/index.d.ts +2 -0
  30. package/dist/index.js +6 -1
  31. package/dist/style.css +3 -3
  32. package/package.json +4 -3
  33. package/src/elements/EFCaptions.browsertest.ts +2 -2
  34. package/src/elements/EFCaptions.ts +0 -7
  35. package/src/elements/EFImage.browsertest.ts +2 -2
  36. package/src/elements/EFImage.ts +0 -4
  37. package/src/elements/EFMedia.browsertest.ts +14 -14
  38. package/src/elements/EFMedia.ts +219 -182
  39. package/src/elements/EFSourceMixin.ts +4 -4
  40. package/src/elements/EFTemporal.browsertest.ts +64 -31
  41. package/src/elements/EFTemporal.ts +99 -119
  42. package/src/elements/EFTimegroup.ts +15 -133
  43. package/src/elements/EFVideo.ts +3 -1
  44. package/src/elements/EFWaveform.ts +10 -44
  45. package/src/elements/durationConverter.ts +9 -4
  46. package/src/elements/updateAnimations.ts +88 -0
  47. package/src/gui/ContextMixin.ts +0 -3
  48. package/src/gui/EFFilmstrip.ts +7 -16
  49. package/src/gui/EFFitScale.ts +152 -0
  50. package/src/gui/EFWorkbench.ts +16 -65
  51. package/src/gui/TWMixin.ts +19 -2
  52. package/types.json +1 -1
@@ -76,8 +76,10 @@ const EFTemporal = (superClass) => {
76
76
  constructor() {
77
77
  super(...arguments);
78
78
  this._offsetMs = 0;
79
- this._trimStartMs = 0;
80
- this._trimEndMs = 0;
79
+ this._trimStartMs = void 0;
80
+ this._trimEndMs = void 0;
81
+ this._sourceInMs = void 0;
82
+ this._sourceOutMs = void 0;
81
83
  this._startOffsetMs = 0;
82
84
  this.rootTimegroup = this.getRootTimegroup();
83
85
  this.frameTask = new Task(this, {
@@ -118,75 +120,46 @@ const EFTemporal = (superClass) => {
118
120
  }
119
121
  }
120
122
  get trimStartMs() {
121
- return this._trimStartMs;
122
- }
123
- set trimStartMs(value) {
124
- if (this._trimStartMs === value) {
125
- return;
123
+ if (this._trimStartMs === void 0) {
124
+ return void 0;
126
125
  }
127
- this._trimStartMs = value;
128
- this.setAttribute(
129
- "trimstart",
130
- durationConverter.toAttribute(value / 1e3)
126
+ return Math.min(
127
+ Math.max(this._trimStartMs, 0),
128
+ this.intrinsicDurationMs ?? 0
131
129
  );
132
130
  }
133
- set trimstart(value) {
134
- if (value !== void 0) {
135
- this.setAttribute("trimstart", value);
136
- } else {
137
- this.removeAttribute("trimstart");
138
- }
131
+ set trimStartMs(value) {
132
+ this._trimStartMs = value;
139
133
  }
140
134
  get trimEndMs() {
141
- return this._trimEndMs;
135
+ if (this._trimEndMs === void 0) {
136
+ return void 0;
137
+ }
138
+ return Math.min(this._trimEndMs, this.intrinsicDurationMs ?? 0);
142
139
  }
143
140
  set trimEndMs(value) {
144
- if (this._trimEndMs === value) {
145
- return;
146
- }
147
141
  this._trimEndMs = value;
148
- this.setAttribute("trimend", durationConverter.toAttribute(value / 1e3));
149
- }
150
- set trimend(value) {
151
- if (value !== void 0) {
152
- this.setAttribute("trimend", value);
153
- } else {
154
- this.removeAttribute("trimend");
155
- }
156
142
  }
157
143
  get sourceInMs() {
158
- return this._sourceInMs;
144
+ if (this._sourceInMs === void 0) {
145
+ return void 0;
146
+ }
147
+ return Math.max(this._sourceInMs, 0);
159
148
  }
160
149
  set sourceInMs(value) {
161
150
  this._sourceInMs = value;
162
- value !== void 0 ? this.setAttribute(
163
- "sourcein",
164
- durationConverter.toAttribute(value / 1e3)
165
- ) : this.removeAttribute("sourcein");
166
- }
167
- set sourcein(value) {
168
- if (value !== void 0) {
169
- this.setAttribute("sourcein", value);
170
- } else {
171
- this.removeAttribute("sourcein");
172
- }
173
151
  }
174
152
  get sourceOutMs() {
175
- return this._sourceOutMs;
153
+ if (this._sourceOutMs === void 0) {
154
+ return void 0;
155
+ }
156
+ if (this.intrinsicDurationMs && this._sourceOutMs > this.intrinsicDurationMs) {
157
+ return this.intrinsicDurationMs;
158
+ }
159
+ return Math.max(this._sourceOutMs, 0);
176
160
  }
177
161
  set sourceOutMs(value) {
178
162
  this._sourceOutMs = value;
179
- value !== void 0 ? this.setAttribute(
180
- "sourceout",
181
- durationConverter.toAttribute(value / 1e3)
182
- ) : this.removeAttribute("sourceout");
183
- }
184
- set sourceout(value) {
185
- if (value !== void 0) {
186
- this.setAttribute("sourceout", value);
187
- } else {
188
- this.removeAttribute("sourceout");
189
- }
190
163
  }
191
164
  get startOffsetMs() {
192
165
  return this._startOffsetMs;
@@ -201,19 +174,41 @@ const EFTemporal = (superClass) => {
201
174
  get hasExplicitDuration() {
202
175
  return this._durationMs !== void 0;
203
176
  }
177
+ get explicitDurationMs() {
178
+ if (this.hasExplicitDuration) {
179
+ return this._durationMs;
180
+ }
181
+ return void 0;
182
+ }
204
183
  get hasOwnDuration() {
205
184
  return false;
206
185
  }
207
- // Defining this as a getter to a private property allows us to
208
- // override it classes that include this mixin.
186
+ get intrinsicDurationMs() {
187
+ return void 0;
188
+ }
209
189
  get durationMs() {
210
- if (this.sourceInMs) {
211
- return this._durationMs || this.parentTimegroup?.durationMs || 0 - this.sourceInMs;
190
+ if (this.intrinsicDurationMs === void 0) {
191
+ return this._durationMs || this.parentTimegroup?.durationMs || 0;
212
192
  }
213
- if (this.sourceOutMs) {
214
- return this._durationMs || this.parentTimegroup?.durationMs || 0 - this.sourceOutMs;
193
+ if (this.trimStartMs || this.trimEndMs) {
194
+ const trimmedDurationMs = this.intrinsicDurationMs - (this.trimStartMs ?? 0) - (this.trimEndMs ?? 0);
195
+ if (trimmedDurationMs < 0) {
196
+ return 0;
197
+ }
198
+ return trimmedDurationMs;
199
+ }
200
+ if (this.sourceInMs || this.sourceOutMs) {
201
+ const sourceInMs = this.sourceInMs ?? 0;
202
+ const sourceOutMs = this.sourceOutMs ?? this.intrinsicDurationMs;
203
+ if (sourceInMs >= sourceOutMs) {
204
+ return 0;
205
+ }
206
+ return sourceOutMs - sourceInMs;
215
207
  }
216
- return this._durationMs || this.parentTimegroup?.durationMs || 0;
208
+ return this.intrinsicDurationMs;
209
+ }
210
+ get sourceStartMs() {
211
+ return this.trimStartMs ?? this.sourceInMs ?? 0;
217
212
  }
218
213
  get offsetMs() {
219
214
  return this._offsetMs || 0;
@@ -296,25 +291,8 @@ const EFTemporal = (superClass) => {
296
291
  * for mapping to internal media time codes for audio/video elements.
297
292
  */
298
293
  get currentSourceTimeMs() {
299
- if (this.rootTimegroup) {
300
- if (this.sourceInMs && this.sourceOutMs) {
301
- return Math.min(
302
- Math.max(
303
- 0,
304
- this.rootTimegroup.currentTimeMs - this.startTimeMs + this.trimStartMs + this.sourceInMs
305
- ),
306
- this.durationMs + Math.abs(this.startOffsetMs) + this.trimStartMs + this.sourceInMs
307
- );
308
- }
309
- return Math.min(
310
- Math.max(
311
- 0,
312
- this.rootTimegroup.currentTimeMs - this.startTimeMs + this.trimStartMs
313
- ),
314
- this.durationMs + Math.abs(this.startOffsetMs) + this.trimStartMs
315
- );
316
- }
317
- return 0;
294
+ const leadingTrimMs = this.sourceInMs || this.trimStartMs || 0;
295
+ return this.ownCurrentTimeMs + leadingTrimMs;
318
296
  }
319
297
  updated(changedProperties) {
320
298
  super.updated(changedProperties);
@@ -352,30 +330,28 @@ const EFTemporal = (superClass) => {
352
330
  attribute: "trimstart",
353
331
  converter: durationConverter
354
332
  })
355
- ], TemporalMixinClass.prototype, "trimStartMs", 1);
333
+ ], TemporalMixinClass.prototype, "_trimStartMs", 2);
356
334
  __decorateClass([
357
335
  property({
358
336
  type: Number,
359
337
  attribute: "trimend",
360
338
  converter: durationConverter
361
339
  })
362
- ], TemporalMixinClass.prototype, "trimEndMs", 1);
340
+ ], TemporalMixinClass.prototype, "_trimEndMs", 2);
363
341
  __decorateClass([
364
342
  property({
365
343
  type: Number,
366
344
  attribute: "sourcein",
367
- converter: durationConverter,
368
- reflect: true
345
+ converter: durationConverter
369
346
  })
370
- ], TemporalMixinClass.prototype, "sourceInMs", 1);
347
+ ], TemporalMixinClass.prototype, "_sourceInMs", 2);
371
348
  __decorateClass([
372
349
  property({
373
350
  type: Number,
374
351
  attribute: "sourceout",
375
- converter: durationConverter,
376
- reflect: true
352
+ converter: durationConverter
377
353
  })
378
- ], TemporalMixinClass.prototype, "sourceOutMs", 1);
354
+ ], TemporalMixinClass.prototype, "_sourceOutMs", 2);
379
355
  __decorateClass([
380
356
  property({
381
357
  type: Number,
@@ -17,9 +17,8 @@ export declare class EFTimegroup extends EFTimegroup_base {
17
17
  maybeLoadTimeFromLocalStorage(): number;
18
18
  connectedCallback(): void;
19
19
  disconnectedCallback(): void;
20
- private get displayedParent();
21
- private updateScale;
22
20
  get storageKey(): string;
21
+ get intrinsicDurationMs(): number | undefined;
23
22
  get durationMs(): number;
24
23
  /**
25
24
  * Wait for all media elements to load their initial segments.
@@ -27,7 +26,7 @@ export declare class EFTimegroup extends EFTimegroup_base {
27
26
  * that caused issues with constructing audio data. We had negative durations
28
27
  * in calculations and it was not clear why.
29
28
  */
30
- waitForMediaDurations(): Promise<Record<number, import('../../../assets/src/index.ts').TrackFragmentIndex>[]>;
29
+ waitForMediaDurations(): Promise<(Record<number, import('../../../assets/src/index.ts').TrackFragmentIndex> | undefined)[]>;
31
30
  get childTemporals(): import('./EFTemporal.js').TemporalMixinInterface[];
32
31
  protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
33
32
  private updateAnimations;
@@ -43,7 +42,6 @@ export declare class EFTimegroup extends EFTimegroup_base {
43
42
  */
44
43
  shouldWrapWithWorkbench(): boolean;
45
44
  wrapWithWorkbench(): void;
46
- get hasOwnDuration(): boolean;
47
45
  get efElements(): Element[];
48
46
  renderAudio(fromMs: number, toMs: number): Promise<AudioBuffer>;
49
47
  loadMd5Sums(): Promise<void>;
@@ -6,9 +6,10 @@ import { property, customElement } from "lit/decorators.js";
6
6
  import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
7
7
  import { isContextMixin } from "../gui/ContextMixin.js";
8
8
  import { deepGetMediaElements } from "./EFMedia.js";
9
- import { EFTemporal, shallowGetTemporalElements, isEFTemporal, timegroupContext } from "./EFTemporal.js";
9
+ import { EFTemporal, shallowGetTemporalElements, timegroupContext } from "./EFTemporal.js";
10
10
  import { TimegroupController } from "./TimegroupController.js";
11
11
  import { durationConverter } from "./durationConverter.js";
12
+ import { updateAnimations } from "./updateAnimations.js";
12
13
  var __defProp = Object.defineProperty;
13
14
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
14
15
  var __typeError = (msg) => {
@@ -107,51 +108,26 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
107
108
  if (this.shouldWrapWithWorkbench()) {
108
109
  this.wrapWithWorkbench();
109
110
  }
110
- __privateSet(this, _resizeObserver, new ResizeObserver(() => this.updateScale()));
111
- if (this.parentElement) {
112
- __privateGet(this, _resizeObserver).observe(this.parentElement);
113
- }
114
- this.updateScale();
115
- requestAnimationFrame(() => this.updateAnimations());
111
+ requestAnimationFrame(() => {
112
+ this.updateAnimations();
113
+ });
116
114
  }
117
115
  disconnectedCallback() {
118
116
  super.disconnectedCallback();
119
117
  __privateGet(this, _resizeObserver)?.disconnect();
120
118
  }
121
- get displayedParent() {
122
- let displayedParent = this.parentElement;
123
- while (displayedParent && getComputedStyle(displayedParent).display === "contents") {
124
- displayedParent = displayedParent.parentElement;
125
- }
126
- return displayedParent;
127
- }
128
- updateScale() {
129
- if (this.fit === "none") return;
130
- const displayedParent = this.displayedParent;
131
- if (!displayedParent) return;
132
- const contentWidth = this.clientWidth;
133
- const contentHeight = this.clientHeight;
134
- const containerWidth = displayedParent.clientWidth;
135
- const containerHeight = displayedParent.clientHeight;
136
- const widthRatio = containerWidth / contentWidth;
137
- const heightRatio = containerHeight / contentHeight;
138
- let scale;
139
- if (this.fit === "contain") {
140
- scale = heightRatio;
141
- if (contentWidth * scale > containerWidth) {
142
- scale = widthRatio;
143
- }
144
- } else {
145
- scale = Math.max(widthRatio, heightRatio);
146
- }
147
- this.style.transform = `scale(${scale})`;
148
- }
149
119
  get storageKey() {
150
120
  if (!this.id) {
151
121
  throw new Error("Timegroup must have an id to use localStorage.");
152
122
  }
153
123
  return `ef-timegroup-${this.id}`;
154
124
  }
125
+ get intrinsicDurationMs() {
126
+ if (this.hasExplicitDuration) {
127
+ return this.explicitDurationMs;
128
+ }
129
+ return void 0;
130
+ }
155
131
  get durationMs() {
156
132
  switch (this.mode) {
157
133
  case "fixed":
@@ -169,7 +145,7 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
169
145
  case "contain": {
170
146
  let maxDuration = 0;
171
147
  for (const node of this.childTemporals) {
172
- if (node.hasOwnDuration) {
148
+ if (node.intrinsicDurationMs !== void 0) {
173
149
  maxDuration = Math.max(maxDuration, node.durationMs);
174
150
  }
175
151
  }
@@ -201,69 +177,7 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
201
177
  }
202
178
  }
203
179
  updateAnimations() {
204
- this.style.setProperty(
205
- "--ef-progress",
206
- `${Math.max(0, Math.min(1, this.currentTimeMs / this.durationMs)) * 100}%`
207
- );
208
- const timelineTimeMs = (this.rootTimegroup ?? this).currentTimeMs;
209
- if (this.startTimeMs > timelineTimeMs || this.endTimeMs < timelineTimeMs) {
210
- this.style.display = "none";
211
- return;
212
- }
213
- this.style.display = "";
214
- const animations = this.getAnimations({ subtree: true });
215
- this.style.setProperty("--ef-duration", `${this.durationMs}ms`);
216
- this.style.setProperty(
217
- "--ef-transition-duration",
218
- `${this.parentTimegroup?.overlapMs ?? 0}ms`
219
- );
220
- this.style.setProperty(
221
- "--ef-transition-out-start",
222
- `${this.durationMs - (this.parentTimegroup?.overlapMs ?? 0)}ms`
223
- );
224
- for (const animation of animations) {
225
- if (animation.playState === "running") {
226
- animation.pause();
227
- }
228
- const effect = animation.effect;
229
- if (!(effect && effect instanceof KeyframeEffect)) {
230
- return;
231
- }
232
- const target = effect.target;
233
- if (!target) {
234
- return;
235
- }
236
- if (target.closest("ef-timegroup") !== this) {
237
- return;
238
- }
239
- if (isEFTemporal(target)) {
240
- const timing = effect.getTiming();
241
- const duration = Number(timing.duration) ?? 0;
242
- const delay = Number(timing.delay);
243
- const newTime = Math.floor(
244
- Math.min(target.ownCurrentTimeMs, duration - 1 + delay)
245
- );
246
- if (Number.isNaN(newTime)) {
247
- return;
248
- }
249
- animation.currentTime = newTime;
250
- } else if (target) {
251
- const nearestTimegroup = target.closest("ef-timegroup");
252
- if (!nearestTimegroup) {
253
- return;
254
- }
255
- const timing = effect.getTiming();
256
- const duration = Number(timing.duration) ?? 0;
257
- const delay = Number(timing.delay);
258
- const newTime = Math.floor(
259
- Math.min(nearestTimegroup.ownCurrentTimeMs, duration - 1 + delay)
260
- );
261
- if (Number.isNaN(newTime)) {
262
- return;
263
- }
264
- animation.currentTime = newTime;
265
- }
266
- }
180
+ updateAnimations(this);
267
181
  }
268
182
  get contextProvider() {
269
183
  let parent = this.parentNode;
@@ -300,9 +214,6 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
300
214
  filmstrip.setAttribute("target", this.id);
301
215
  workbench.append(filmstrip);
302
216
  }
303
- get hasOwnDuration() {
304
- return true;
305
- }
306
217
  get efElements() {
307
218
  return Array.from(
308
219
  this.querySelectorAll(
@@ -378,7 +289,8 @@ EFTimegroup.styles = css`
378
289
  width: 100%;
379
290
  height: 100%;
380
291
  position: absolute;
381
- transform-origin: center center;
292
+ top: 0;
293
+ left: 0;
382
294
  }
383
295
  `;
384
296
  __decorateClass([
@@ -93,7 +93,9 @@ let EFVideo = class extends TWMixin(EFMedia) {
93
93
  });
94
94
  }
95
95
  render() {
96
- return html` <canvas ${ref(this.canvasRef)}></canvas>`;
96
+ return html`
97
+ <canvas ${ref(this.canvasRef)}></canvas>
98
+ `;
97
99
  }
98
100
  get canvasElement() {
99
101
  return this.canvasRef.value;
@@ -16,6 +16,7 @@ export declare class EFWaveform extends EFWaveform_base {
16
16
  mode: "roundBars" | "bars" | "bricks" | "line" | "curve" | "pixel" | "wave" | "spikes";
17
17
  color: string;
18
18
  target: string;
19
+ barSpacing: number;
19
20
  targetElement: EFAudio | EFVideo | null;
20
21
  lineWidth: number;
21
22
  targetController: TargetController;
@@ -26,7 +27,6 @@ export declare class EFWaveform extends EFWaveform_base {
26
27
  protected drawBars(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
27
28
  protected drawBricks(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
28
29
  protected drawRoundBars(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
29
- protected drawEqualizer(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
30
30
  protected drawLine(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
31
31
  protected drawCurve(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
32
32
  protected drawPixel(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
@@ -28,6 +28,7 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
28
28
  this.mode = "bars";
29
29
  this.color = "currentColor";
30
30
  this.target = "";
31
+ this.barSpacing = 0.5;
31
32
  this.targetElement = null;
32
33
  this.lineWidth = 4;
33
34
  this.targetController = new TargetController(this);
@@ -152,14 +153,14 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
152
153
  const waveWidth = canvas.width;
153
154
  const waveHeight = canvas.height;
154
155
  const totalBars = frequencyData.length;
155
- const paddingInner = 0.5;
156
+ const paddingInner = this.barSpacing;
156
157
  const paddingOuter = 0.01;
157
158
  const availableWidth = waveWidth;
158
159
  const barWidth = availableWidth / (totalBars + (totalBars - 1) * paddingInner);
159
160
  ctx.clearRect(0, 0, waveWidth, waveHeight);
160
161
  const path = new Path2D();
161
162
  frequencyData.forEach((value, i) => {
162
- const normalizedValue = Math.min(value / 255 * 2, 1);
163
+ const normalizedValue = value / 255;
163
164
  const barHeight = normalizedValue * waveHeight;
164
165
  const y = (waveHeight - barHeight) / 2;
165
166
  const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));
@@ -178,7 +179,7 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
178
179
  const verticalGap = boxSize * 0.2;
179
180
  const maxBricks = Math.floor(waveHeight / (boxSize + verticalGap));
180
181
  frequencyData.forEach((value, i) => {
181
- const normalizedValue = Math.min(value / 255 * 2, 1);
182
+ const normalizedValue = value / 255;
182
183
  const brickCount = Math.floor(normalizedValue * maxBricks);
183
184
  for (let j = 0; j < brickCount; j++) {
184
185
  const x = columnWidth * i;
@@ -193,14 +194,14 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
193
194
  const waveWidth = canvas.width;
194
195
  const waveHeight = canvas.height;
195
196
  const totalBars = frequencyData.length;
196
- const paddingInner = 0.5;
197
+ const paddingInner = this.barSpacing;
197
198
  const paddingOuter = 0.01;
198
199
  const availableWidth = waveWidth;
199
200
  const barWidth = availableWidth / (totalBars + (totalBars - 1) * paddingInner);
200
201
  ctx.clearRect(0, 0, waveWidth, waveHeight);
201
202
  const path = new Path2D();
202
203
  frequencyData.forEach((value, i) => {
203
- const normalizedValue = Math.min(value / 255 * 2, 1);
204
+ const normalizedValue = value / 255;
204
205
  const height = normalizedValue * waveHeight;
205
206
  const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));
206
207
  const y = (waveHeight - height) / 2;
@@ -208,34 +209,13 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
208
209
  });
209
210
  ctx.fill(path);
210
211
  }
211
- drawEqualizer(ctx, frequencyData) {
212
- const canvas = ctx.canvas;
213
- const waveWidth = canvas.width;
214
- const waveHeight = canvas.height;
215
- const baseline = waveHeight / 2;
216
- const barWidth = waveWidth / frequencyData.length * 0.8;
217
- ctx.clearRect(0, 0, waveWidth, waveHeight);
218
- const baselinePath = new Path2D();
219
- const barsPath = new Path2D();
220
- baselinePath.moveTo(0, baseline);
221
- baselinePath.lineTo(waveWidth, baseline);
222
- frequencyData.forEach((value, i) => {
223
- const height = value / 255 * (waveHeight / 2);
224
- const x = i * (waveWidth / frequencyData.length);
225
- const y = baseline - height;
226
- barsPath.rect(x, y, barWidth, Math.max(height * 2, 1));
227
- });
228
- ctx.lineWidth = 2;
229
- ctx.stroke(baselinePath);
230
- ctx.fill(barsPath);
231
- }
232
212
  drawLine(ctx, frequencyData) {
233
213
  const canvas = ctx.canvas;
234
214
  const waveWidth = canvas.width;
235
215
  const waveHeight = canvas.height;
236
216
  ctx.clearRect(0, 0, waveWidth, waveHeight);
237
217
  const path = new Path2D();
238
- const sampleRate = 4;
218
+ const sampleRate = 1;
239
219
  for (let i = 0; i < frequencyData.length; i += sampleRate) {
240
220
  const x = i / frequencyData.length * waveWidth;
241
221
  const y = (1 - (frequencyData[i] ?? 0) / 255) * waveHeight;
@@ -282,7 +262,7 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
282
262
  ctx.clearRect(0, 0, waveWidth, waveHeight);
283
263
  const path = new Path2D();
284
264
  frequencyData.forEach((value, i) => {
285
- const normalizedValue = Math.min(value / 255 * 2, 1);
265
+ const normalizedValue = value / 255;
286
266
  const x = i * (waveWidth / frequencyData.length);
287
267
  const barHeight = normalizedValue * (waveHeight / 2);
288
268
  const y = baseline - barHeight;
@@ -432,6 +412,9 @@ __decorateClass([
432
412
  __decorateClass([
433
413
  property({ type: String, reflect: true })
434
414
  ], EFWaveform.prototype, "target", 2);
415
+ __decorateClass([
416
+ property({ type: Number, attribute: "bar-spacing" })
417
+ ], EFWaveform.prototype, "barSpacing", 2);
435
418
  __decorateClass([
436
419
  state()
437
420
  ], EFWaveform.prototype, "targetElement", 2);
@@ -1,16 +1,16 @@
1
1
  export declare const durationConverter: {
2
- fromAttribute: (value: string) => number;
3
- toAttribute: (value: number) => string;
2
+ fromAttribute: (value: string | null) => number | null;
3
+ toAttribute: (value: number | null) => string | null;
4
4
  };
5
5
  export declare const trimDurationConverter: {
6
- fromAttribute: (value: string) => number;
7
- toAttribute: (value: number) => string;
6
+ fromAttribute: (value: string | null) => number | null;
7
+ toAttribute: (value: number | null) => string | null;
8
8
  };
9
9
  export declare const imageDurationConverter: {
10
- fromAttribute: (value: string) => number;
11
- toAttribute: (value: number) => string;
10
+ fromAttribute: (value: string | null) => number | null;
11
+ toAttribute: (value: number | null) => string | null;
12
12
  };
13
13
  export declare const sourceDurationConverter: {
14
- fromAttribute: (value: string) => number;
15
- toAttribute: (value: number) => string;
14
+ fromAttribute: (value: string | null) => number | null;
15
+ toAttribute: (value: number | null) => string | null;
16
16
  };
@@ -1,7 +1,7 @@
1
1
  import { parseTimeToMs } from "./parseTimeToMs.js";
2
2
  const durationConverter = {
3
- fromAttribute: (value) => parseTimeToMs(value),
4
- toAttribute: (value) => `${value}s`
3
+ fromAttribute: (value) => value === null ? null : parseTimeToMs(value),
4
+ toAttribute: (value) => value === null ? null : `${value}s`
5
5
  };
6
6
  export {
7
7
  durationConverter
@@ -0,0 +1,9 @@
1
+ import { EFTimegroup } from './EFTimegroup.ts';
2
+ export declare const updateAnimations: (element: HTMLElement & {
3
+ currentTimeMs: number;
4
+ durationMs: number;
5
+ rootTimegroup?: EFTimegroup;
6
+ parentTimegroup?: EFTimegroup;
7
+ startTimeMs: number;
8
+ endTimeMs: number;
9
+ }) => void;
@@ -0,0 +1,62 @@
1
+ import { isEFTemporal } from "./EFTemporal.js";
2
+ const updateAnimations = (element) => {
3
+ element.style.setProperty(
4
+ "--ef-progress",
5
+ `${Math.max(0, Math.min(1, element.currentTimeMs / element.durationMs)) * 100}%`
6
+ );
7
+ const timelineTimeMs = (element.rootTimegroup ?? element).currentTimeMs;
8
+ if (element.startTimeMs > timelineTimeMs || element.endTimeMs < timelineTimeMs) {
9
+ element.style.display = "none";
10
+ return;
11
+ }
12
+ element.style.display = "";
13
+ const animations = element.getAnimations({ subtree: true });
14
+ element.style.setProperty("--ef-duration", `${element.durationMs}ms`);
15
+ element.style.setProperty(
16
+ "--ef-transition-duration",
17
+ `${element.parentTimegroup?.overlapMs ?? 0}ms`
18
+ );
19
+ element.style.setProperty(
20
+ "--ef-transition-out-start",
21
+ `${element.durationMs - (element.parentTimegroup?.overlapMs ?? 0)}ms`
22
+ );
23
+ for (const animation of animations) {
24
+ if (animation.playState === "running") {
25
+ animation.pause();
26
+ }
27
+ const effect = animation.effect;
28
+ if (!(effect && effect instanceof KeyframeEffect)) {
29
+ continue;
30
+ }
31
+ const target = effect.target;
32
+ if (!target) {
33
+ continue;
34
+ }
35
+ if (target.closest("ef-timegroup") !== element) {
36
+ continue;
37
+ }
38
+ const timing = effect.getTiming();
39
+ const duration = Number(timing.duration) ?? 0;
40
+ const delay = Number(timing.delay) ?? 0;
41
+ const iterations = Number(timing.iterations) ?? 1;
42
+ const timeTarget = isEFTemporal(target) ? target : target.closest("ef-timegroup");
43
+ if (!timeTarget) {
44
+ continue;
45
+ }
46
+ const currentTime = timeTarget.ownCurrentTimeMs;
47
+ if (currentTime < delay) {
48
+ animation.currentTime = 0;
49
+ continue;
50
+ }
51
+ const currentIteration = Math.floor((currentTime - delay) / duration);
52
+ const currentIterationTime = (currentTime - delay) % duration;
53
+ if (currentIteration >= iterations) {
54
+ animation.currentTime = duration - 0.01;
55
+ continue;
56
+ }
57
+ animation.currentTime = Math.min(currentIterationTime, duration - 0.01) + delay;
58
+ }
59
+ };
60
+ export {
61
+ updateAnimations
62
+ };