@editframe/elements 0.15.0-beta.18 → 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.
@@ -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) => {
@@ -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.hasOwnDuration) {
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.style.setProperty(
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
- transform-origin: center center;
292
+ top: 0;
293
+ left: 0;
389
294
  }
390
295
  `;
391
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;
@@ -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,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();
@@ -100,11 +63,7 @@ let EFWorkbench = class extends ContextMixin(TWMixin(LitElement)) {
100
63
  render() {
101
64
  if (this.rendering) {
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
- ${ref(this.stageRef)}
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
- <slot
121
- ${ref(this.canvasRef)}
122
- name="canvas"
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);