@editframe/elements 0.15.0-beta.9 → 0.16.0-beta.0
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/EF_FRAMEGEN.d.ts +14 -10
- package/dist/EF_FRAMEGEN.js +17 -28
- package/dist/elements/EFCaptions.js +0 -7
- package/dist/elements/EFImage.js +0 -4
- package/dist/elements/EFMedia.d.ts +13 -8
- package/dist/elements/EFMedia.js +164 -146
- package/dist/elements/EFSourceMixin.js +2 -1
- package/dist/elements/EFTemporal.browsertest.d.ts +4 -3
- package/dist/elements/EFTemporal.d.ts +14 -11
- package/dist/elements/EFTemporal.js +63 -87
- package/dist/elements/EFTimegroup.d.ts +2 -4
- package/dist/elements/EFTimegroup.js +15 -103
- package/dist/elements/EFVideo.js +3 -1
- package/dist/elements/EFWaveform.d.ts +1 -1
- package/dist/elements/EFWaveform.js +11 -28
- package/dist/elements/durationConverter.d.ts +8 -8
- package/dist/elements/durationConverter.js +2 -2
- package/dist/elements/updateAnimations.d.ts +9 -0
- package/dist/elements/updateAnimations.js +62 -0
- package/dist/getRenderInfo.d.ts +51 -0
- package/dist/getRenderInfo.js +72 -0
- package/dist/gui/EFFilmstrip.js +7 -16
- package/dist/gui/EFFitScale.d.ts +27 -0
- package/dist/gui/EFFitScale.js +138 -0
- package/dist/gui/EFWorkbench.d.ts +2 -5
- package/dist/gui/EFWorkbench.js +13 -56
- package/dist/gui/TWMixin.css.js +1 -1
- package/dist/gui/TWMixin.js +14 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -1
- package/dist/style.css +3 -3
- package/package.json +4 -3
- package/src/elements/EFCaptions.browsertest.ts +2 -2
- package/src/elements/EFCaptions.ts +0 -7
- package/src/elements/EFImage.browsertest.ts +2 -2
- package/src/elements/EFImage.ts +0 -4
- package/src/elements/EFMedia.browsertest.ts +14 -14
- package/src/elements/EFMedia.ts +220 -182
- package/src/elements/EFSourceMixin.ts +4 -4
- package/src/elements/EFTemporal.browsertest.ts +64 -31
- package/src/elements/EFTemporal.ts +99 -119
- package/src/elements/EFTimegroup.ts +15 -133
- package/src/elements/EFVideo.ts +3 -1
- package/src/elements/EFWaveform.ts +10 -44
- package/src/elements/durationConverter.ts +9 -4
- package/src/elements/updateAnimations.ts +88 -0
- package/src/gui/ContextMixin.ts +0 -3
- package/src/gui/EFFilmstrip.ts +7 -16
- package/src/gui/EFFitScale.ts +152 -0
- package/src/gui/EFWorkbench.ts +18 -65
- package/src/gui/TWMixin.ts +19 -2
- 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
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
|
134
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
208
|
-
|
|
186
|
+
get intrinsicDurationMs() {
|
|
187
|
+
return void 0;
|
|
188
|
+
}
|
|
209
189
|
get durationMs() {
|
|
210
|
-
if (this.
|
|
211
|
-
return this._durationMs || this.parentTimegroup?.durationMs || 0
|
|
190
|
+
if (this.intrinsicDurationMs === void 0) {
|
|
191
|
+
return this._durationMs || this.parentTimegroup?.durationMs || 0;
|
|
212
192
|
}
|
|
213
|
-
if (this.
|
|
214
|
-
|
|
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.
|
|
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
|
-
|
|
300
|
-
|
|
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, "
|
|
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, "
|
|
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, "
|
|
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, "
|
|
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,
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
292
|
+
top: 0;
|
|
293
|
+
left: 0;
|
|
382
294
|
}
|
|
383
295
|
`;
|
|
384
296
|
__decorateClass([
|
package/dist/elements/EFVideo.js
CHANGED
|
@@ -93,7 +93,9 @@ let EFVideo = class extends TWMixin(EFMedia) {
|
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
95
|
render() {
|
|
96
|
-
return html`
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
+
};
|