@editframe/elements 0.15.0-beta.18 → 0.15.0-beta.20
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.js +1 -0
- package/dist/elements/EFMedia.d.ts +7 -3
- package/dist/elements/EFMedia.js +42 -90
- 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 +1 -1
- package/dist/elements/EFTimegroup.js +12 -107
- package/dist/elements/EFVideo.js +3 -1
- 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 +2 -2
- package/dist/gui/EFFilmstrip.js +7 -16
- package/dist/gui/EFFitScale.d.ts +27 -0
- package/dist/gui/EFFitScale.js +137 -0
- package/dist/gui/EFWorkbench.d.ts +1 -5
- package/dist/gui/EFWorkbench.js +7 -54
- package/dist/gui/TWMixin.css.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/style.css +0 -6
- package/package.json +2 -2
- package/src/elements/EFMedia.browsertest.ts +10 -10
- package/src/elements/EFMedia.ts +48 -118
- package/src/elements/EFTemporal.browsertest.ts +64 -31
- package/src/elements/EFTemporal.ts +99 -119
- package/src/elements/EFTimegroup.ts +12 -131
- package/src/elements/EFVideo.ts +3 -1
- 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 +151 -0
- package/src/gui/EFWorkbench.ts +13 -63
- package/types.json +1 -1
|
@@ -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) => {
|
|
@@ -115,50 +116,18 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
115
116
|
super.disconnectedCallback();
|
|
116
117
|
__privateGet(this, _resizeObserver)?.disconnect();
|
|
117
118
|
}
|
|
118
|
-
// private get displayedParent(): Element | null {
|
|
119
|
-
// let displayedParent = this.parentElement;
|
|
120
|
-
// while (
|
|
121
|
-
// displayedParent &&
|
|
122
|
-
// getComputedStyle(displayedParent).display === "contents"
|
|
123
|
-
// ) {
|
|
124
|
-
// displayedParent = displayedParent.parentElement;
|
|
125
|
-
// }
|
|
126
|
-
// return displayedParent;
|
|
127
|
-
// }
|
|
128
|
-
// private updateScale() {
|
|
129
|
-
// if (this.fit === "none") return;
|
|
130
|
-
// const displayedParent = this.displayedParent;
|
|
131
|
-
// if (!displayedParent) return;
|
|
132
|
-
// // Get the natural size of the content
|
|
133
|
-
// const contentWidth = this.clientWidth;
|
|
134
|
-
// const contentHeight = this.clientHeight;
|
|
135
|
-
// // Get the available space from displayed parent
|
|
136
|
-
// const containerWidth = displayedParent.clientWidth;
|
|
137
|
-
// const containerHeight = displayedParent.clientHeight;
|
|
138
|
-
// // Calculate scale ratios
|
|
139
|
-
// const widthRatio = containerWidth / contentWidth;
|
|
140
|
-
// const heightRatio = containerHeight / contentHeight;
|
|
141
|
-
// let scale: number;
|
|
142
|
-
// if (this.fit === "contain") {
|
|
143
|
-
// // Use height ratio for contain mode to ensure it fits vertically
|
|
144
|
-
// scale = heightRatio;
|
|
145
|
-
// // If width would overflow after scaling, use width ratio instead
|
|
146
|
-
// if (contentWidth * scale > containerWidth) {
|
|
147
|
-
// scale = widthRatio;
|
|
148
|
-
// }
|
|
149
|
-
// } else {
|
|
150
|
-
// // cover
|
|
151
|
-
// scale = Math.max(widthRatio, heightRatio);
|
|
152
|
-
// }
|
|
153
|
-
// // Apply transform with fixed center origin
|
|
154
|
-
// this.style.transform = `scale(${scale})`;
|
|
155
|
-
// }
|
|
156
119
|
get storageKey() {
|
|
157
120
|
if (!this.id) {
|
|
158
121
|
throw new Error("Timegroup must have an id to use localStorage.");
|
|
159
122
|
}
|
|
160
123
|
return `ef-timegroup-${this.id}`;
|
|
161
124
|
}
|
|
125
|
+
get intrinsicDurationMs() {
|
|
126
|
+
if (this.hasExplicitDuration) {
|
|
127
|
+
return this.explicitDurationMs;
|
|
128
|
+
}
|
|
129
|
+
return void 0;
|
|
130
|
+
}
|
|
162
131
|
get durationMs() {
|
|
163
132
|
switch (this.mode) {
|
|
164
133
|
case "fixed":
|
|
@@ -176,7 +145,7 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
176
145
|
case "contain": {
|
|
177
146
|
let maxDuration = 0;
|
|
178
147
|
for (const node of this.childTemporals) {
|
|
179
|
-
if (node.
|
|
148
|
+
if (node.intrinsicDurationMs !== void 0) {
|
|
180
149
|
maxDuration = Math.max(maxDuration, node.durationMs);
|
|
181
150
|
}
|
|
182
151
|
}
|
|
@@ -208,69 +177,7 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
208
177
|
}
|
|
209
178
|
}
|
|
210
179
|
updateAnimations() {
|
|
211
|
-
this
|
|
212
|
-
"--ef-progress",
|
|
213
|
-
`${Math.max(0, Math.min(1, this.currentTimeMs / this.durationMs)) * 100}%`
|
|
214
|
-
);
|
|
215
|
-
const timelineTimeMs = (this.rootTimegroup ?? this).currentTimeMs;
|
|
216
|
-
if (this.startTimeMs > timelineTimeMs || this.endTimeMs < timelineTimeMs) {
|
|
217
|
-
this.style.display = "none";
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
this.style.display = "";
|
|
221
|
-
const animations = this.getAnimations({ subtree: true });
|
|
222
|
-
this.style.setProperty("--ef-duration", `${this.durationMs}ms`);
|
|
223
|
-
this.style.setProperty(
|
|
224
|
-
"--ef-transition-duration",
|
|
225
|
-
`${this.parentTimegroup?.overlapMs ?? 0}ms`
|
|
226
|
-
);
|
|
227
|
-
this.style.setProperty(
|
|
228
|
-
"--ef-transition-out-start",
|
|
229
|
-
`${this.durationMs - (this.parentTimegroup?.overlapMs ?? 0)}ms`
|
|
230
|
-
);
|
|
231
|
-
for (const animation of animations) {
|
|
232
|
-
if (animation.playState === "running") {
|
|
233
|
-
animation.pause();
|
|
234
|
-
}
|
|
235
|
-
const effect = animation.effect;
|
|
236
|
-
if (!(effect && effect instanceof KeyframeEffect)) {
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
const target = effect.target;
|
|
240
|
-
if (!target) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
if (target.closest("ef-timegroup") !== this) {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
if (isEFTemporal(target)) {
|
|
247
|
-
const timing = effect.getTiming();
|
|
248
|
-
const duration = Number(timing.duration) ?? 0;
|
|
249
|
-
const delay = Number(timing.delay);
|
|
250
|
-
const newTime = Math.floor(
|
|
251
|
-
Math.min(target.ownCurrentTimeMs, duration - 1 + delay)
|
|
252
|
-
);
|
|
253
|
-
if (Number.isNaN(newTime)) {
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
animation.currentTime = newTime;
|
|
257
|
-
} else if (target) {
|
|
258
|
-
const nearestTimegroup = target.closest("ef-timegroup");
|
|
259
|
-
if (!nearestTimegroup) {
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
const timing = effect.getTiming();
|
|
263
|
-
const duration = Number(timing.duration) ?? 0;
|
|
264
|
-
const delay = Number(timing.delay);
|
|
265
|
-
const newTime = Math.floor(
|
|
266
|
-
Math.min(nearestTimegroup.ownCurrentTimeMs, duration - 1 + delay)
|
|
267
|
-
);
|
|
268
|
-
if (Number.isNaN(newTime)) {
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
animation.currentTime = newTime;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
180
|
+
updateAnimations(this);
|
|
274
181
|
}
|
|
275
182
|
get contextProvider() {
|
|
276
183
|
let parent = this.parentNode;
|
|
@@ -307,9 +214,6 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
307
214
|
filmstrip.setAttribute("target", this.id);
|
|
308
215
|
workbench.append(filmstrip);
|
|
309
216
|
}
|
|
310
|
-
get hasOwnDuration() {
|
|
311
|
-
return true;
|
|
312
|
-
}
|
|
313
217
|
get efElements() {
|
|
314
218
|
return Array.from(
|
|
315
219
|
this.querySelectorAll(
|
|
@@ -385,7 +289,8 @@ EFTimegroup.styles = css`
|
|
|
385
289
|
width: 100%;
|
|
386
290
|
height: 100%;
|
|
387
291
|
position: absolute;
|
|
388
|
-
|
|
292
|
+
top: 0;
|
|
293
|
+
left: 0;
|
|
389
294
|
}
|
|
390
295
|
`;
|
|
391
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;
|
|
@@ -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
|
+
};
|
package/dist/getRenderInfo.d.ts
CHANGED
|
@@ -20,8 +20,8 @@ export declare const RenderInfo: z.ZodObject<{
|
|
|
20
20
|
}, "strip", z.ZodTypeAny, {
|
|
21
21
|
width: number;
|
|
22
22
|
height: number;
|
|
23
|
-
fps: number;
|
|
24
23
|
durationMs: number;
|
|
24
|
+
fps: number;
|
|
25
25
|
assets: {
|
|
26
26
|
efMedia: Record<string, any>;
|
|
27
27
|
efCaptions: string[];
|
|
@@ -30,8 +30,8 @@ export declare const RenderInfo: z.ZodObject<{
|
|
|
30
30
|
}, {
|
|
31
31
|
width: number;
|
|
32
32
|
height: number;
|
|
33
|
-
fps: number;
|
|
34
33
|
durationMs: number;
|
|
34
|
+
fps: number;
|
|
35
35
|
assets: {
|
|
36
36
|
efMedia: Record<string, any>;
|
|
37
37
|
efCaptions: string[];
|
package/dist/gui/EFFilmstrip.js
CHANGED
|
@@ -74,30 +74,21 @@ class FilmstripItem extends TWMixin(LitElement) {
|
|
|
74
74
|
get isFocused() {
|
|
75
75
|
return this.element && this.focusContext?.focusedElement === this.element;
|
|
76
76
|
}
|
|
77
|
+
// Gutter styles represent the entire source media.
|
|
78
|
+
// If there is no trim, then the gutter and trim portion are the same.
|
|
77
79
|
get gutterStyles() {
|
|
78
|
-
if (this.element.sourceInMs || this.element.sourceOutMs) {
|
|
79
|
-
return {
|
|
80
|
-
position: "relative",
|
|
81
|
-
left: `${this.pixelsPerMs * (this.element.startTimeWithinParentMs - this.element.trimStartMs - this.element.sourceInMs)}px`,
|
|
82
|
-
width: `${this.pixelsPerMs * (this.element.durationMs + this.element.trimStartMs + this.element.trimEndMs + this.element.sourceOutMs + this.element.sourceInMs)}px`
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
80
|
return {
|
|
86
81
|
position: "relative",
|
|
87
|
-
left: `${this.pixelsPerMs * (this.element.startTimeWithinParentMs - this.element.
|
|
88
|
-
width: `${this.pixelsPerMs * (this.element.
|
|
82
|
+
left: `${this.pixelsPerMs * (this.element.startTimeWithinParentMs - this.element.sourceStartMs)}px`,
|
|
83
|
+
width: `${this.pixelsPerMs * (this.element.intrinsicDurationMs ?? this.element.durationMs)}px`
|
|
89
84
|
};
|
|
90
85
|
}
|
|
86
|
+
// Trim portion is the section of source that will be placed in the timeline
|
|
87
|
+
// If there is no trim, then the gutter and trim portion are the same.
|
|
91
88
|
get trimPortionStyles() {
|
|
92
|
-
if (this.element.sourceInMs || this.element.sourceOutMs) {
|
|
93
|
-
return {
|
|
94
|
-
width: `${this.pixelsPerMs * this.element.durationMs}px`,
|
|
95
|
-
left: `${this.pixelsPerMs * (this.element.trimStartMs + this.element.sourceInMs)}px`
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
89
|
return {
|
|
99
90
|
width: `${this.pixelsPerMs * this.element.durationMs}px`,
|
|
100
|
-
left: `${this.pixelsPerMs * this.element.
|
|
91
|
+
left: `${this.pixelsPerMs * this.element.sourceStartMs}px`
|
|
101
92
|
};
|
|
102
93
|
}
|
|
103
94
|
render() {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export declare class EFFitScale extends LitElement {
|
|
3
|
+
containerRef: import('lit-html/directives/ref.js').Ref<HTMLDivElement>;
|
|
4
|
+
contentRef: import('lit-html/directives/ref.js').Ref<HTMLSlotElement>;
|
|
5
|
+
createRenderRoot(): this;
|
|
6
|
+
uniqueId: string;
|
|
7
|
+
private scale;
|
|
8
|
+
private animationFrameId?;
|
|
9
|
+
get contentChild(): HTMLElement | null;
|
|
10
|
+
get scaleInfo(): {
|
|
11
|
+
scale: number;
|
|
12
|
+
containerWidth: number;
|
|
13
|
+
containerHeight: number;
|
|
14
|
+
contentWidth: number;
|
|
15
|
+
contentHeight: number;
|
|
16
|
+
};
|
|
17
|
+
scaleLastSetOn: HTMLElement | null;
|
|
18
|
+
setScale: () => void;
|
|
19
|
+
removeScale: () => void;
|
|
20
|
+
connectedCallback(): void;
|
|
21
|
+
disconnectedCallback(): void;
|
|
22
|
+
}
|
|
23
|
+
declare global {
|
|
24
|
+
interface HTMLElementTagNameMap {
|
|
25
|
+
"ef-fit-scale": EFFitScale;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
import { state, customElement } from "lit/decorators.js";
|
|
3
|
+
import { createRef } from "lit/directives/ref.js";
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
7
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
8
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
9
|
+
if (decorator = decorators[i])
|
|
10
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
11
|
+
if (kind && result) __defProp(target, key, result);
|
|
12
|
+
return result;
|
|
13
|
+
};
|
|
14
|
+
let EFFitScale = class extends LitElement {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.containerRef = createRef();
|
|
18
|
+
this.contentRef = createRef();
|
|
19
|
+
this.uniqueId = Math.random().toString(36).substring(2, 15);
|
|
20
|
+
this.scale = 1;
|
|
21
|
+
this.scaleLastSetOn = null;
|
|
22
|
+
this.setScale = () => {
|
|
23
|
+
if (this.isConnected) {
|
|
24
|
+
const { scale } = this.scaleInfo;
|
|
25
|
+
if (this.contentChild) {
|
|
26
|
+
const containerRect = this.getBoundingClientRect();
|
|
27
|
+
const contentRect = this.contentChild.getBoundingClientRect();
|
|
28
|
+
const unscaledWidth = contentRect.width / this.scale;
|
|
29
|
+
const unscaledHeight = contentRect.height / this.scale;
|
|
30
|
+
const scaledWidth = unscaledWidth * scale;
|
|
31
|
+
const scaledHeight = unscaledHeight * scale;
|
|
32
|
+
const translateX = (containerRect.width - scaledWidth) / 2;
|
|
33
|
+
const translateY = (containerRect.height - scaledHeight) / 2;
|
|
34
|
+
if (this.scaleLastSetOn !== this.contentChild) {
|
|
35
|
+
this.removeScale();
|
|
36
|
+
}
|
|
37
|
+
Object.assign(this.contentChild.style, {
|
|
38
|
+
transform: `translate(${translateX.toFixed(4)}px, ${translateY.toFixed(4)}px) scale(${scale.toFixed(4)})`,
|
|
39
|
+
transformOrigin: "top left"
|
|
40
|
+
});
|
|
41
|
+
this.scale = scale;
|
|
42
|
+
this.scaleLastSetOn = this.contentChild;
|
|
43
|
+
}
|
|
44
|
+
this.animationFrameId = requestAnimationFrame(this.setScale);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
this.removeScale = () => {
|
|
48
|
+
if (this.scaleLastSetOn) {
|
|
49
|
+
Object.assign(this.scaleLastSetOn.style, {
|
|
50
|
+
transform: "",
|
|
51
|
+
transformOrigin: ""
|
|
52
|
+
});
|
|
53
|
+
this.scaleLastSetOn = null;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
createRenderRoot() {
|
|
58
|
+
Object.assign(this.style, {
|
|
59
|
+
display: "grid",
|
|
60
|
+
width: "100%",
|
|
61
|
+
height: "100%",
|
|
62
|
+
gridTemplateColumns: "100%",
|
|
63
|
+
gridTemplateRows: "100%",
|
|
64
|
+
overflow: "hidden",
|
|
65
|
+
boxSizing: "border-box",
|
|
66
|
+
contain: "strict",
|
|
67
|
+
position: "relative"
|
|
68
|
+
});
|
|
69
|
+
this.id = `${this.uniqueId}`;
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
get contentChild() {
|
|
73
|
+
const firstElement = this.children[0];
|
|
74
|
+
if (!firstElement) return null;
|
|
75
|
+
let current = firstElement;
|
|
76
|
+
while (current) {
|
|
77
|
+
if (current instanceof HTMLSlotElement) {
|
|
78
|
+
const assigned = current.assignedElements()[0];
|
|
79
|
+
if (!assigned) break;
|
|
80
|
+
current = assigned;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const display = window.getComputedStyle(current).display;
|
|
84
|
+
if (display !== "contents" && display !== "none") {
|
|
85
|
+
return current;
|
|
86
|
+
}
|
|
87
|
+
const firstChild = current.children[0];
|
|
88
|
+
if (!firstChild) break;
|
|
89
|
+
current = firstChild;
|
|
90
|
+
}
|
|
91
|
+
return firstElement;
|
|
92
|
+
}
|
|
93
|
+
get scaleInfo() {
|
|
94
|
+
if (!this.contentChild) {
|
|
95
|
+
return {
|
|
96
|
+
scale: 1,
|
|
97
|
+
containerWidth: 0,
|
|
98
|
+
containerHeight: 0,
|
|
99
|
+
contentWidth: 0,
|
|
100
|
+
contentHeight: 0
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const containerWidth = this.clientWidth;
|
|
104
|
+
const containerHeight = this.clientHeight;
|
|
105
|
+
const contentWidth = this.contentChild.clientWidth;
|
|
106
|
+
const contentHeight = this.contentChild.clientHeight;
|
|
107
|
+
const containerRatio = containerWidth / containerHeight;
|
|
108
|
+
const contentRatio = contentWidth / contentHeight;
|
|
109
|
+
const scale = containerRatio > contentRatio ? containerHeight / contentHeight : containerWidth / contentWidth;
|
|
110
|
+
return {
|
|
111
|
+
scale,
|
|
112
|
+
containerWidth,
|
|
113
|
+
containerHeight,
|
|
114
|
+
contentWidth,
|
|
115
|
+
contentHeight
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
connectedCallback() {
|
|
119
|
+
super.connectedCallback();
|
|
120
|
+
this.animationFrameId = requestAnimationFrame(this.setScale);
|
|
121
|
+
}
|
|
122
|
+
disconnectedCallback() {
|
|
123
|
+
super.disconnectedCallback();
|
|
124
|
+
if (this.animationFrameId) {
|
|
125
|
+
cancelAnimationFrame(this.animationFrameId);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
__decorateClass([
|
|
130
|
+
state()
|
|
131
|
+
], EFFitScale.prototype, "scale", 2);
|
|
132
|
+
EFFitScale = __decorateClass([
|
|
133
|
+
customElement("ef-fit-scale")
|
|
134
|
+
], EFFitScale);
|
|
135
|
+
export {
|
|
136
|
+
EFFitScale
|
|
137
|
+
};
|
|
@@ -2,12 +2,8 @@ import { LitElement, PropertyValueMap } from 'lit';
|
|
|
2
2
|
declare const EFWorkbench_base: (new (...args: any[]) => import('./ContextMixin.js').ContextMixinInterface) & typeof LitElement;
|
|
3
3
|
export declare class EFWorkbench extends EFWorkbench_base {
|
|
4
4
|
static styles: import('lit').CSSResult[];
|
|
5
|
-
stageRef: import('lit-html/directives/ref.js').Ref<HTMLDivElement>;
|
|
6
|
-
canvasRef: import('lit-html/directives/ref.js').Ref<HTMLSlotElement>;
|
|
7
|
-
handleStageWheel(event: WheelEvent): void;
|
|
8
5
|
focusOverlay: import('lit-html/directives/ref.js').Ref<HTMLDivElement>;
|
|
9
|
-
|
|
10
|
-
setStageScale: () => void;
|
|
6
|
+
handleStageWheel(event: WheelEvent): void;
|
|
11
7
|
connectedCallback(): void;
|
|
12
8
|
disconnectedCallback(): void;
|
|
13
9
|
update(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
|
package/dist/gui/EFWorkbench.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { html, css, LitElement } from "lit";
|
|
2
|
-
import { eventOptions,
|
|
2
|
+
import { eventOptions, customElement } from "lit/decorators.js";
|
|
3
3
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
4
4
|
import { ContextMixin } from "./ContextMixin.js";
|
|
5
5
|
import { TWMixin } from "./TWMixin.js";
|
|
@@ -16,43 +16,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
16
16
|
let EFWorkbench = class extends ContextMixin(TWMixin(LitElement)) {
|
|
17
17
|
constructor() {
|
|
18
18
|
super(...arguments);
|
|
19
|
-
this.stageRef = createRef();
|
|
20
|
-
this.canvasRef = createRef();
|
|
21
19
|
this.focusOverlay = createRef();
|
|
22
|
-
this.stageScale = 1;
|
|
23
|
-
this.setStageScale = () => {
|
|
24
|
-
if (this.isConnected && !this.rendering) {
|
|
25
|
-
const canvasElement = this.canvasRef.value;
|
|
26
|
-
const stageElement = this.stageRef.value;
|
|
27
|
-
const canvasChild = canvasElement?.assignedElements()[0];
|
|
28
|
-
if (stageElement && canvasElement && canvasChild) {
|
|
29
|
-
canvasElement.style.width = `${canvasChild.clientWidth}px`;
|
|
30
|
-
canvasElement.style.height = `${canvasChild.clientHeight}px`;
|
|
31
|
-
const stageWidth = stageElement.clientWidth;
|
|
32
|
-
const stageHeight = stageElement.clientHeight;
|
|
33
|
-
const canvasWidth = canvasElement.clientWidth;
|
|
34
|
-
const canvasHeight = canvasElement.clientHeight;
|
|
35
|
-
const stageRatio = stageWidth / stageHeight;
|
|
36
|
-
const canvasRatio = canvasWidth / canvasHeight;
|
|
37
|
-
if (stageRatio > canvasRatio) {
|
|
38
|
-
const scale = stageHeight / canvasHeight;
|
|
39
|
-
if (this.stageScale !== scale) {
|
|
40
|
-
canvasElement.style.transform = `scale(${scale})`;
|
|
41
|
-
}
|
|
42
|
-
this.stageScale = scale;
|
|
43
|
-
} else {
|
|
44
|
-
const scale = stageWidth / canvasWidth;
|
|
45
|
-
if (this.stageScale !== scale) {
|
|
46
|
-
canvasElement.style.transform = `scale(${scale})`;
|
|
47
|
-
}
|
|
48
|
-
this.stageScale = scale;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
if (this.isConnected) {
|
|
53
|
-
requestAnimationFrame(this.setStageScale);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
20
|
this.drawOverlays = () => {
|
|
57
21
|
const focusOverlay = this.focusOverlay.value;
|
|
58
22
|
if (focusOverlay) {
|
|
@@ -82,7 +46,6 @@ let EFWorkbench = class extends ContextMixin(TWMixin(LitElement)) {
|
|
|
82
46
|
document.documentElement.style.width = "100%";
|
|
83
47
|
document.documentElement.style.height = "100%";
|
|
84
48
|
super.connectedCallback();
|
|
85
|
-
requestAnimationFrame(this.setStageScale);
|
|
86
49
|
}
|
|
87
50
|
disconnectedCallback() {
|
|
88
51
|
super.disconnectedCallback();
|
|
@@ -98,13 +61,9 @@ let EFWorkbench = class extends ContextMixin(TWMixin(LitElement)) {
|
|
|
98
61
|
}
|
|
99
62
|
}
|
|
100
63
|
render() {
|
|
101
|
-
if (this.rendering) {
|
|
64
|
+
if (this.rendering || typeof window !== "undefined" && window.FRAMEGEN_BRIDGE) {
|
|
102
65
|
return html`
|
|
103
|
-
<slot
|
|
104
|
-
${ref(this.canvasRef)}
|
|
105
|
-
class="fixed inset-0 h-full w-full"
|
|
106
|
-
name="canvas"
|
|
107
|
-
></slot>
|
|
66
|
+
<slot class="fixed inset-0 h-full w-full" name="canvas"></slot>
|
|
108
67
|
`;
|
|
109
68
|
}
|
|
110
69
|
return html`
|
|
@@ -113,15 +72,12 @@ let EFWorkbench = class extends ContextMixin(TWMixin(LitElement)) {
|
|
|
113
72
|
style="grid-template-rows: 1fr 300px; grid-template-columns: 100%;"
|
|
114
73
|
>
|
|
115
74
|
<div
|
|
116
|
-
|
|
117
|
-
class="relative grid h-full w-full justify-center overflow-hidden place-content-center place-items-center"
|
|
75
|
+
class="relative h-full w-full overflow-hidden"
|
|
118
76
|
@wheel=${this.handleStageWheel}
|
|
119
77
|
>
|
|
120
|
-
<
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
class="inline-block"
|
|
124
|
-
></slot>
|
|
78
|
+
<ef-fit-scale class="h-full grid place-content-center">
|
|
79
|
+
<slot name="canvas" class="contents"></slot>
|
|
80
|
+
</ef-fit-scale>
|
|
125
81
|
<div
|
|
126
82
|
class="border border-blue-500 bg-blue-200 bg-opacity-20 absolute"
|
|
127
83
|
${ref(this.focusOverlay)}
|
|
@@ -145,9 +101,6 @@ EFWorkbench.styles = [
|
|
|
145
101
|
__decorateClass([
|
|
146
102
|
eventOptions({ passive: false, capture: true })
|
|
147
103
|
], EFWorkbench.prototype, "handleStageWheel", 1);
|
|
148
|
-
__decorateClass([
|
|
149
|
-
state()
|
|
150
|
-
], EFWorkbench.prototype, "stageScale", 2);
|
|
151
104
|
EFWorkbench = __decorateClass([
|
|
152
105
|
customElement("ef-workbench")
|
|
153
106
|
], EFWorkbench);
|