@editframe/elements 0.15.0-beta.17 → 0.15.0-beta.19

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 (38) hide show
  1. package/dist/EF_FRAMEGEN.js +1 -1
  2. package/dist/elements/EFMedia.d.ts +7 -3
  3. package/dist/elements/EFMedia.js +45 -90
  4. package/dist/elements/EFTemporal.browsertest.d.ts +4 -3
  5. package/dist/elements/EFTemporal.d.ts +14 -11
  6. package/dist/elements/EFTemporal.js +63 -87
  7. package/dist/elements/EFTimegroup.d.ts +1 -3
  8. package/dist/elements/EFTimegroup.js +15 -103
  9. package/dist/elements/EFVideo.js +3 -1
  10. package/dist/elements/EFWaveform.d.ts +1 -0
  11. package/dist/elements/EFWaveform.js +6 -2
  12. package/dist/elements/durationConverter.d.ts +8 -8
  13. package/dist/elements/durationConverter.js +2 -2
  14. package/dist/elements/updateAnimations.d.ts +9 -0
  15. package/dist/elements/updateAnimations.js +62 -0
  16. package/dist/gui/EFFilmstrip.js +7 -16
  17. package/dist/gui/EFFitScale.d.ts +25 -0
  18. package/dist/gui/EFFitScale.js +123 -0
  19. package/dist/gui/EFWorkbench.d.ts +1 -5
  20. package/dist/gui/EFWorkbench.js +6 -55
  21. package/dist/gui/TWMixin.css.js +1 -1
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.js +2 -0
  24. package/dist/style.css +3 -3
  25. package/package.json +2 -2
  26. package/src/elements/EFMedia.browsertest.ts +10 -10
  27. package/src/elements/EFMedia.ts +56 -118
  28. package/src/elements/EFTemporal.browsertest.ts +64 -31
  29. package/src/elements/EFTemporal.ts +99 -119
  30. package/src/elements/EFTimegroup.ts +15 -133
  31. package/src/elements/EFVideo.ts +3 -1
  32. package/src/elements/EFWaveform.ts +5 -2
  33. package/src/elements/durationConverter.ts +9 -4
  34. package/src/elements/updateAnimations.ts +88 -0
  35. package/src/gui/EFFilmstrip.ts +7 -16
  36. package/src/gui/EFFitScale.ts +133 -0
  37. package/src/gui/EFWorkbench.ts +7 -64
  38. 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, 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;
@@ -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,7 +153,7 @@ 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);
@@ -193,7 +194,7 @@ 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);
@@ -411,6 +412,9 @@ __decorateClass([
411
412
  __decorateClass([
412
413
  property({ type: String, reflect: true })
413
414
  ], EFWaveform.prototype, "target", 2);
415
+ __decorateClass([
416
+ property({ type: Number, attribute: "bar-spacing" })
417
+ ], EFWaveform.prototype, "barSpacing", 2);
414
418
  __decorateClass([
415
419
  state()
416
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
+ };
@@ -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.trimStartMs)}px`,
88
- width: `${this.pixelsPerMs * (this.element.durationMs + this.element.trimStartMs + this.element.trimEndMs)}px`
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.trimStartMs}px`
91
+ left: `${this.pixelsPerMs * this.element.sourceStartMs}px`
101
92
  };
102
93
  }
103
94
  render() {
@@ -0,0 +1,25 @@
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
+ setScale: () => void;
18
+ connectedCallback(): void;
19
+ disconnectedCallback(): void;
20
+ }
21
+ declare global {
22
+ interface HTMLElementTagNameMap {
23
+ "ef-fit-scale": EFFitScale;
24
+ }
25
+ }
@@ -0,0 +1,123 @@
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.setScale = () => {
22
+ if (this.isConnected) {
23
+ const { scale } = this.scaleInfo;
24
+ if (this.contentChild) {
25
+ const containerRect = this.getBoundingClientRect();
26
+ const contentRect = this.contentChild.getBoundingClientRect();
27
+ const unscaledWidth = contentRect.width / this.scale;
28
+ const unscaledHeight = contentRect.height / this.scale;
29
+ const scaledWidth = unscaledWidth * scale;
30
+ const scaledHeight = unscaledHeight * scale;
31
+ const translateX = (containerRect.width - scaledWidth) / 2;
32
+ const translateY = (containerRect.height - scaledHeight) / 2;
33
+ Object.assign(this.contentChild.style, {
34
+ transform: `translate(${translateX.toFixed(4)}px, ${translateY.toFixed(4)}px) scale(${scale.toFixed(4)})`,
35
+ transformOrigin: "top left"
36
+ });
37
+ this.scale = scale;
38
+ }
39
+ this.animationFrameId = requestAnimationFrame(this.setScale);
40
+ }
41
+ };
42
+ }
43
+ createRenderRoot() {
44
+ Object.assign(this.style, {
45
+ display: "grid",
46
+ width: "100%",
47
+ height: "100%",
48
+ gridTemplateColumns: "100%",
49
+ gridTemplateRows: "100%",
50
+ overflow: "hidden",
51
+ boxSizing: "border-box",
52
+ contain: "strict",
53
+ position: "relative"
54
+ });
55
+ this.id = `${this.uniqueId}`;
56
+ return this;
57
+ }
58
+ get contentChild() {
59
+ const firstElement = this.children[0];
60
+ if (!firstElement) return null;
61
+ let current = firstElement;
62
+ while (current) {
63
+ if (current instanceof HTMLSlotElement) {
64
+ const assigned = current.assignedElements()[0];
65
+ if (!assigned) break;
66
+ current = assigned;
67
+ continue;
68
+ }
69
+ const display = window.getComputedStyle(current).display;
70
+ if (display !== "contents" && display !== "none") {
71
+ return current;
72
+ }
73
+ const firstChild = current.children[0];
74
+ if (!firstChild) break;
75
+ current = firstChild;
76
+ }
77
+ return firstElement;
78
+ }
79
+ get scaleInfo() {
80
+ if (!this.contentChild) {
81
+ return {
82
+ scale: 1,
83
+ containerWidth: 0,
84
+ containerHeight: 0,
85
+ contentWidth: 0,
86
+ contentHeight: 0
87
+ };
88
+ }
89
+ const containerWidth = this.clientWidth;
90
+ const containerHeight = this.clientHeight;
91
+ const contentWidth = this.contentChild.clientWidth;
92
+ const contentHeight = this.contentChild.clientHeight;
93
+ const containerRatio = containerWidth / containerHeight;
94
+ const contentRatio = contentWidth / contentHeight;
95
+ const scale = containerRatio > contentRatio ? containerHeight / contentHeight : containerWidth / contentWidth;
96
+ return {
97
+ scale,
98
+ containerWidth,
99
+ containerHeight,
100
+ contentWidth,
101
+ contentHeight
102
+ };
103
+ }
104
+ connectedCallback() {
105
+ super.connectedCallback();
106
+ this.animationFrameId = requestAnimationFrame(this.setScale);
107
+ }
108
+ disconnectedCallback() {
109
+ super.disconnectedCallback();
110
+ if (this.animationFrameId) {
111
+ cancelAnimationFrame(this.animationFrameId);
112
+ }
113
+ }
114
+ };
115
+ __decorateClass([
116
+ state()
117
+ ], EFFitScale.prototype, "scale", 2);
118
+ EFFitScale = __decorateClass([
119
+ customElement("ef-fit-scale")
120
+ ], EFFitScale);
121
+ export {
122
+ EFFitScale
123
+ };
@@ -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
- private stageScale;
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;
@@ -1,5 +1,5 @@
1
1
  import { html, css, LitElement } from "lit";
2
- import { eventOptions, state, customElement } from "lit/decorators.js";
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,45 +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
- canvasElement.style.transformOrigin = "top center";
42
- }
43
- this.stageScale = scale;
44
- } else {
45
- const scale = stageWidth / canvasWidth;
46
- if (this.stageScale !== scale) {
47
- canvasElement.style.transform = `scale(${scale})`;
48
- canvasElement.style.transformOrigin = "center";
49
- }
50
- this.stageScale = scale;
51
- }
52
- }
53
- }
54
- if (this.isConnected) {
55
- requestAnimationFrame(this.setStageScale);
56
- }
57
- };
58
20
  this.drawOverlays = () => {
59
21
  const focusOverlay = this.focusOverlay.value;
60
22
  if (focusOverlay) {
@@ -84,7 +46,6 @@ let EFWorkbench = class extends ContextMixin(TWMixin(LitElement)) {
84
46
  document.documentElement.style.width = "100%";
85
47
  document.documentElement.style.height = "100%";
86
48
  super.connectedCallback();
87
- requestAnimationFrame(this.setStageScale);
88
49
  }
89
50
  disconnectedCallback() {
90
51
  super.disconnectedCallback();
@@ -102,11 +63,7 @@ let EFWorkbench = class extends ContextMixin(TWMixin(LitElement)) {
102
63
  render() {
103
64
  if (this.rendering) {
104
65
  return html`
105
- <slot
106
- ${ref(this.canvasRef)}
107
- class="fixed inset-0 h-full w-full"
108
- name="canvas"
109
- ></slot>
66
+ <slot class="fixed inset-0 h-full w-full" name="canvas"></slot>
110
67
  `;
111
68
  }
112
69
  return html`
@@ -115,15 +72,12 @@ let EFWorkbench = class extends ContextMixin(TWMixin(LitElement)) {
115
72
  style="grid-template-rows: 1fr 300px; grid-template-columns: 100%;"
116
73
  >
117
74
  <div
118
- ${ref(this.stageRef)}
119
- class="relative grid h-full w-full justify-center overflow-hidden"
75
+ class="relative h-full w-full overflow-hidden"
120
76
  @wheel=${this.handleStageWheel}
121
77
  >
122
- <slot
123
- ${ref(this.canvasRef)}
124
- name="canvas"
125
- class="inline-block"
126
- ></slot>
78
+ <ef-fit-scale class="h-full grid place-content-center">
79
+ <slot name="canvas" class="contents"></slot>
80
+ </ef-fit-scale>
127
81
  <div
128
82
  class="border border-blue-500 bg-blue-200 bg-opacity-20 absolute"
129
83
  ${ref(this.focusOverlay)}
@@ -147,9 +101,6 @@ EFWorkbench.styles = [
147
101
  __decorateClass([
148
102
  eventOptions({ passive: false, capture: true })
149
103
  ], EFWorkbench.prototype, "handleStageWheel", 1);
150
- __decorateClass([
151
- state()
152
- ], EFWorkbench.prototype, "stageScale", 2);
153
104
  EFWorkbench = __decorateClass([
154
105
  customElement("ef-workbench")
155
106
  ], EFWorkbench);