canvasengine 2.0.0-beta.49 → 2.0.0-beta.50
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/components/DOMContainer.d.ts.map +1 -1
- package/dist/components/DOMSprite.d.ts +20 -1
- package/dist/components/DOMSprite.d.ts.map +1 -1
- package/dist/index.global.js +1 -1
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +813 -676
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/DOMContainer.ts +62 -16
- package/src/components/DOMSprite.ts +294 -13
- package/testing/index.ts +3 -1
package/package.json
CHANGED
|
@@ -268,26 +268,72 @@ export class CanvasDOMContainer extends DisplayObject(PixiDOMContainer) {
|
|
|
268
268
|
// Handle internal _scopeClass prop for scoped CSS
|
|
269
269
|
const scopeClass = props._scopeClass;
|
|
270
270
|
let divProps: any = { element: "div" };
|
|
271
|
+
const divAttrs = { ...(props.attrs || {}) };
|
|
271
272
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if (
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
273
|
+
const mergeScopeClass = (classValue: any) => {
|
|
274
|
+
if (!scopeClass) return classValue;
|
|
275
|
+
if (classValue == null) return scopeClass;
|
|
276
|
+
if (typeof classValue === "string") {
|
|
277
|
+
return `${scopeClass} ${classValue}`;
|
|
278
|
+
}
|
|
279
|
+
if (Array.isArray(classValue)) {
|
|
280
|
+
return [scopeClass, ...classValue];
|
|
281
|
+
}
|
|
282
|
+
if (typeof classValue === "object") {
|
|
283
|
+
if ("items" in classValue) {
|
|
284
|
+
const itemsValue = (classValue as any).items;
|
|
285
|
+
return { ...classValue, items: [scopeClass, itemsValue] };
|
|
286
|
+
}
|
|
287
|
+
if ("value" in classValue) {
|
|
288
|
+
const valueValue = (classValue as any).value;
|
|
289
|
+
return { ...classValue, value: [scopeClass, valueValue] };
|
|
284
290
|
}
|
|
291
|
+
return { [scopeClass]: true, ...classValue };
|
|
292
|
+
}
|
|
293
|
+
return [scopeClass, classValue];
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
if (props.class !== undefined) {
|
|
297
|
+
if (divAttrs.class) {
|
|
298
|
+
divAttrs.class = [props.class, divAttrs.class];
|
|
299
|
+
} else {
|
|
300
|
+
divAttrs.class = props.class;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (props.style !== undefined) {
|
|
305
|
+
if (
|
|
306
|
+
typeof divAttrs.style === "object"
|
|
307
|
+
&& divAttrs.style !== null
|
|
308
|
+
&& typeof props.style === "object"
|
|
309
|
+
&& props.style !== null
|
|
310
|
+
) {
|
|
311
|
+
divAttrs.style = { ...divAttrs.style, ...props.style };
|
|
312
|
+
} else if (divAttrs.style === undefined) {
|
|
313
|
+
divAttrs.style = props.style;
|
|
314
|
+
} else if (typeof divAttrs.style === "string" && typeof props.style === "string") {
|
|
315
|
+
divAttrs.style = `${divAttrs.style}; ${props.style}`;
|
|
316
|
+
} else {
|
|
317
|
+
divAttrs.style = props.style;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (props.zIndex !== undefined) {
|
|
322
|
+
if (typeof divAttrs.style === "object" && divAttrs.style !== null) {
|
|
323
|
+
divAttrs.style = { ...divAttrs.style, zIndex: props.zIndex };
|
|
324
|
+
} else if (typeof divAttrs.style === "string") {
|
|
325
|
+
divAttrs.style = `${divAttrs.style}; z-index: ${props.zIndex}`;
|
|
285
326
|
} else {
|
|
286
|
-
|
|
287
|
-
divProps.attrs.class = scopeClass;
|
|
327
|
+
divAttrs.style = { zIndex: props.zIndex };
|
|
288
328
|
}
|
|
289
|
-
}
|
|
290
|
-
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (scopeClass) {
|
|
332
|
+
// Merge scope class with existing attrs.class
|
|
333
|
+
divProps.attrs = { ...divAttrs };
|
|
334
|
+
divProps.attrs.class = mergeScopeClass(divProps.attrs.class);
|
|
335
|
+
} else if (Object.keys(divAttrs).length > 0) {
|
|
336
|
+
divProps.attrs = divAttrs;
|
|
291
337
|
}
|
|
292
338
|
|
|
293
339
|
const routedChildren = this.routeDomChildren(props.children);
|
|
@@ -40,6 +40,8 @@ export interface DOMSpriteProps extends DOMElementProps {
|
|
|
40
40
|
onFinish?: () => void;
|
|
41
41
|
};
|
|
42
42
|
element?: "div" | "img";
|
|
43
|
+
class?: any;
|
|
44
|
+
style?: any;
|
|
43
45
|
attrs?: Record<string, any> & {
|
|
44
46
|
class?:
|
|
45
47
|
| string
|
|
@@ -144,18 +146,36 @@ export class CanvasDOMSprite extends CanvasDOMElement {
|
|
|
144
146
|
private rafId?: number;
|
|
145
147
|
private lastRafTimestamp?: number;
|
|
146
148
|
private lastTickTimestamp?: number;
|
|
147
|
-
private
|
|
149
|
+
private renderElementType: "div" | "img" = "div";
|
|
150
|
+
private wrapperElementType: "div" | "img" = "div";
|
|
148
151
|
private isAnimating = false;
|
|
149
152
|
private playingSubscription?: Subscription;
|
|
150
153
|
private playingSignal?: Signal<boolean>;
|
|
154
|
+
private explicitWidth?: string;
|
|
155
|
+
private explicitHeight?: string;
|
|
156
|
+
private frameWidth = 0;
|
|
157
|
+
private frameHeight = 0;
|
|
158
|
+
private fitMode?: string;
|
|
159
|
+
private renderElement?: HTMLElement;
|
|
160
|
+
private isContained = false;
|
|
151
161
|
|
|
152
162
|
onInit(props: DOMElementProps) {
|
|
153
163
|
const spriteProps = props as DOMSpriteProps;
|
|
154
|
-
|
|
155
|
-
const
|
|
164
|
+
const hasSheet = spriteProps.sheet !== undefined;
|
|
165
|
+
const defaultElement: "div" | "img" = !hasSheet && spriteProps.image ? "img" : "div";
|
|
166
|
+
this.renderElementType = spriteProps.element ?? defaultElement;
|
|
167
|
+
const resolvedFit = this.resolveValue(spriteProps.objectFit);
|
|
168
|
+
this.fitMode = resolvedFit ?? undefined;
|
|
169
|
+
this.wrapperElementType =
|
|
170
|
+
this.fitMode === "contain" && this.renderElementType === "img"
|
|
171
|
+
? "div"
|
|
172
|
+
: this.renderElementType;
|
|
173
|
+
const nextProps = this.mergeEventAttrs({ ...spriteProps, element: this.wrapperElementType });
|
|
156
174
|
this.tickSignal = nextProps.context?.tick;
|
|
157
175
|
this.applyProps(nextProps);
|
|
158
176
|
super.onInit(nextProps as any);
|
|
177
|
+
this.syncRenderElement();
|
|
178
|
+
this.applyDisplayProps(nextProps);
|
|
159
179
|
this.render();
|
|
160
180
|
this.updateAnimationLoop();
|
|
161
181
|
}
|
|
@@ -172,6 +192,8 @@ export class CanvasDOMSprite extends CanvasDOMElement {
|
|
|
172
192
|
const nextProps = this.mergeEventAttrs(props as DOMSpriteProps);
|
|
173
193
|
super.onUpdate(nextProps as any);
|
|
174
194
|
this.applyProps(nextProps);
|
|
195
|
+
this.syncRenderElement();
|
|
196
|
+
this.applyDisplayProps(nextProps);
|
|
175
197
|
this.render();
|
|
176
198
|
this.updateAnimationLoop();
|
|
177
199
|
}
|
|
@@ -444,6 +466,31 @@ export class CanvasDOMSprite extends CanvasDOMElement {
|
|
|
444
466
|
merged[event] = handler;
|
|
445
467
|
}
|
|
446
468
|
}
|
|
469
|
+
if (props.class !== undefined) {
|
|
470
|
+
if (!merged) merged = {};
|
|
471
|
+
if (merged.class) {
|
|
472
|
+
merged.class = [props.class, merged.class];
|
|
473
|
+
} else {
|
|
474
|
+
merged.class = props.class;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
if (props.style !== undefined) {
|
|
478
|
+
if (!merged) merged = {};
|
|
479
|
+
if (
|
|
480
|
+
typeof merged.style === "object"
|
|
481
|
+
&& merged.style !== null
|
|
482
|
+
&& typeof props.style === "object"
|
|
483
|
+
&& props.style !== null
|
|
484
|
+
) {
|
|
485
|
+
merged.style = { ...merged.style, ...props.style };
|
|
486
|
+
} else if (merged.style === undefined) {
|
|
487
|
+
merged.style = props.style;
|
|
488
|
+
} else if (typeof merged.style === "string" && typeof props.style === "string") {
|
|
489
|
+
merged.style = `${merged.style}; ${props.style}`;
|
|
490
|
+
} else {
|
|
491
|
+
merged.style = props.style;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
447
494
|
if (!merged) return props;
|
|
448
495
|
return { ...props, attrs: merged };
|
|
449
496
|
}
|
|
@@ -517,6 +564,228 @@ export class CanvasDOMSprite extends CanvasDOMElement {
|
|
|
517
564
|
this.loop = resolvedLoop;
|
|
518
565
|
}
|
|
519
566
|
}
|
|
567
|
+
if (props.objectFit !== undefined) {
|
|
568
|
+
const resolvedFit = this.resolveValue(props.objectFit);
|
|
569
|
+
this.fitMode = resolvedFit ?? undefined;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
private resolveValue<T>(value: T | Signal<T> | { value?: T } | undefined): T | undefined {
|
|
574
|
+
if (value === undefined) return undefined;
|
|
575
|
+
const resolved = isSignal(value as any) ? (value as any)() : value;
|
|
576
|
+
if (resolved && typeof resolved === "object" && "value" in (resolved as any)) {
|
|
577
|
+
return (resolved as any).value as T;
|
|
578
|
+
}
|
|
579
|
+
return resolved as T;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
private resolvePoint(
|
|
583
|
+
value: DOMSpriteProps["scale"] | DOMSpriteProps["anchor"] | DOMSpriteProps["skew"] | DOMSpriteProps["pivot"]
|
|
584
|
+
): { x: number; y: number } | undefined {
|
|
585
|
+
const resolved = this.resolveValue<any>(value as any);
|
|
586
|
+
if (resolved === undefined || resolved === null) return undefined;
|
|
587
|
+
if (typeof resolved === "number") {
|
|
588
|
+
return { x: resolved, y: resolved };
|
|
589
|
+
}
|
|
590
|
+
if (Array.isArray(resolved)) {
|
|
591
|
+
const [x, y] = resolved;
|
|
592
|
+
return { x: x ?? 0, y: y ?? x ?? 0 };
|
|
593
|
+
}
|
|
594
|
+
if (typeof resolved === "object") {
|
|
595
|
+
return { x: resolved.x ?? 0, y: resolved.y ?? 0 };
|
|
596
|
+
}
|
|
597
|
+
return undefined;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
private resolveSize(value: DOMSpriteProps["width"] | DOMSpriteProps["height"]): string | undefined {
|
|
601
|
+
const resolved = this.resolveValue<any>(value as any);
|
|
602
|
+
if (resolved === undefined || resolved === null) return undefined;
|
|
603
|
+
if (typeof resolved === "number") return `${resolved}px`;
|
|
604
|
+
if (typeof resolved === "string") return resolved;
|
|
605
|
+
return undefined;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
private resolvePixelSize(value?: string): number | undefined {
|
|
609
|
+
if (!value) return undefined;
|
|
610
|
+
if (value.endsWith("px")) {
|
|
611
|
+
const parsed = parseFloat(value);
|
|
612
|
+
return Number.isNaN(parsed) ? undefined : parsed;
|
|
613
|
+
}
|
|
614
|
+
if (/^\d+(\.\d+)?$/.test(value)) {
|
|
615
|
+
const parsed = parseFloat(value);
|
|
616
|
+
return Number.isNaN(parsed) ? undefined : parsed;
|
|
617
|
+
}
|
|
618
|
+
return undefined;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
private toCssColor(tint: number): string {
|
|
622
|
+
const clamped = Math.max(0, Math.min(0xffffff, tint));
|
|
623
|
+
return `#${clamped.toString(16).padStart(6, "0")}`;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
private applyDisplayProps(props: DOMSpriteProps) {
|
|
627
|
+
if (!this.element) return;
|
|
628
|
+
|
|
629
|
+
if (props.width !== undefined) {
|
|
630
|
+
this.explicitWidth = this.resolveSize(props.width);
|
|
631
|
+
} else {
|
|
632
|
+
this.explicitWidth = undefined;
|
|
633
|
+
}
|
|
634
|
+
if (props.height !== undefined) {
|
|
635
|
+
this.explicitHeight = this.resolveSize(props.height);
|
|
636
|
+
} else {
|
|
637
|
+
this.explicitHeight = undefined;
|
|
638
|
+
}
|
|
639
|
+
if (this.explicitWidth !== undefined) {
|
|
640
|
+
this.element.style.width = this.explicitWidth;
|
|
641
|
+
}
|
|
642
|
+
if (this.explicitHeight !== undefined) {
|
|
643
|
+
this.element.style.height = this.explicitHeight;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (props.alpha !== undefined) {
|
|
647
|
+
const alpha = this.resolveValue(props.alpha);
|
|
648
|
+
if (alpha !== undefined) {
|
|
649
|
+
this.element.style.opacity = String(alpha);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
if (props.visible !== undefined) {
|
|
654
|
+
const visible = this.resolveValue(props.visible);
|
|
655
|
+
this.element.style.display = visible === false ? "none" : "";
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
if (props.zIndex !== undefined) {
|
|
659
|
+
const zIndex = this.resolveValue(props.zIndex);
|
|
660
|
+
if (zIndex !== undefined) {
|
|
661
|
+
this.element.style.zIndex = String(zIndex);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
if (props.cursor !== undefined) {
|
|
666
|
+
const cursor = this.resolveValue(props.cursor);
|
|
667
|
+
if (cursor !== undefined) {
|
|
668
|
+
this.element.style.cursor = String(cursor);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
if (props.tint !== undefined) {
|
|
673
|
+
const tint = this.resolveValue(props.tint);
|
|
674
|
+
if (typeof tint === "number") {
|
|
675
|
+
this.element.style.filter = `drop-shadow(0 0 0 ${this.toCssColor(tint)})`;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
const hasTransformProps = [
|
|
680
|
+
props.x,
|
|
681
|
+
props.y,
|
|
682
|
+
props.scale,
|
|
683
|
+
props.rotation,
|
|
684
|
+
props.angle,
|
|
685
|
+
props.skew,
|
|
686
|
+
props.roundPixels,
|
|
687
|
+
].some((value) => value !== undefined);
|
|
688
|
+
|
|
689
|
+
if (hasTransformProps) {
|
|
690
|
+
let x = this.resolveValue(props.x) ?? 0;
|
|
691
|
+
let y = this.resolveValue(props.y) ?? 0;
|
|
692
|
+
const roundPixels = this.resolveValue(props.roundPixels);
|
|
693
|
+
if (roundPixels) {
|
|
694
|
+
x = Math.round(x);
|
|
695
|
+
y = Math.round(y);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
const scale = this.resolvePoint(props.scale) ?? { x: 1, y: 1 };
|
|
699
|
+
const skew = this.resolvePoint(props.skew);
|
|
700
|
+
|
|
701
|
+
const angle = this.resolveValue(props.angle);
|
|
702
|
+
const rotation = this.resolveValue(props.rotation);
|
|
703
|
+
const rotationDeg = angle !== undefined
|
|
704
|
+
? angle
|
|
705
|
+
: rotation !== undefined
|
|
706
|
+
? (rotation * 180) / Math.PI
|
|
707
|
+
: 0;
|
|
708
|
+
|
|
709
|
+
const transformParts = [
|
|
710
|
+
`translate3d(${x}px, ${y}px, 0)`,
|
|
711
|
+
];
|
|
712
|
+
|
|
713
|
+
if (rotationDeg !== 0) {
|
|
714
|
+
transformParts.push(`rotate(${rotationDeg}deg)`);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
if (skew) {
|
|
718
|
+
const skewX = (skew.x * 180) / Math.PI;
|
|
719
|
+
const skewY = (skew.y * 180) / Math.PI;
|
|
720
|
+
if (skewX !== 0 || skewY !== 0) {
|
|
721
|
+
transformParts.push(`skew(${skewX}deg, ${skewY}deg)`);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
if (scale.x !== 1 || scale.y !== 1) {
|
|
726
|
+
transformParts.push(`scale(${scale.x}, ${scale.y})`);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
this.element.style.transform = transformParts.join(" ");
|
|
730
|
+
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
const pivot = this.resolvePoint(props.pivot);
|
|
734
|
+
const anchor = this.resolvePoint(props.anchor);
|
|
735
|
+
if (pivot) {
|
|
736
|
+
this.element.style.transformOrigin = `${pivot.x}px ${pivot.y}px`;
|
|
737
|
+
} else if (anchor) {
|
|
738
|
+
this.element.style.transformOrigin = `${anchor.x * 100}% ${anchor.y * 100}%`;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
private syncRenderElement() {
|
|
743
|
+
if (!this.element) return;
|
|
744
|
+
if (this.fitMode === "contain" && !(this.element instanceof HTMLImageElement)) {
|
|
745
|
+
if (!this.isContained) {
|
|
746
|
+
const inner = document.createElement(this.renderElementType);
|
|
747
|
+
this.element.style.position = "relative";
|
|
748
|
+
this.element.style.overflow = "hidden";
|
|
749
|
+
inner.style.position = "absolute";
|
|
750
|
+
inner.style.left = "0";
|
|
751
|
+
inner.style.top = "0";
|
|
752
|
+
inner.style.transformOrigin = "0 0";
|
|
753
|
+
this.element.appendChild(inner);
|
|
754
|
+
this.renderElement = inner;
|
|
755
|
+
this.isContained = true;
|
|
756
|
+
}
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
if (this.isContained) {
|
|
761
|
+
if (this.renderElement && this.renderElement !== this.element) {
|
|
762
|
+
this.renderElement.remove();
|
|
763
|
+
}
|
|
764
|
+
this.renderElement = undefined;
|
|
765
|
+
this.isContained = false;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
private getRenderElement() {
|
|
770
|
+
return this.renderElement ?? this.element;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
private applyContainScale() {
|
|
774
|
+
if (!this.isContained) return;
|
|
775
|
+
const target = this.getRenderElement();
|
|
776
|
+
if (!target || !this.element) return;
|
|
777
|
+
if (this.frameWidth <= 0 || this.frameHeight <= 0) return;
|
|
778
|
+
|
|
779
|
+
const containerWidth =
|
|
780
|
+
this.resolvePixelSize(this.explicitWidth) ?? this.element.clientWidth;
|
|
781
|
+
const containerHeight =
|
|
782
|
+
this.resolvePixelSize(this.explicitHeight) ?? this.element.clientHeight;
|
|
783
|
+
|
|
784
|
+
if (!containerWidth || !containerHeight) return;
|
|
785
|
+
|
|
786
|
+
const scale = Math.min(containerWidth / this.frameWidth, containerHeight / this.frameHeight);
|
|
787
|
+
if (!Number.isFinite(scale) || scale <= 0) return;
|
|
788
|
+
target.style.transform = `scale(${scale})`;
|
|
520
789
|
}
|
|
521
790
|
|
|
522
791
|
private bindPlayingSignal(context: Element<CanvasDOMElement>) {
|
|
@@ -577,6 +846,7 @@ export class CanvasDOMSprite extends CanvasDOMElement {
|
|
|
577
846
|
|
|
578
847
|
private render() {
|
|
579
848
|
if (!this.element) return;
|
|
849
|
+
const target = this.getRenderElement();
|
|
580
850
|
const sheetFrame = this.getCurrentSheetFrame();
|
|
581
851
|
if (sheetFrame) {
|
|
582
852
|
this.applyFrame(sheetFrame);
|
|
@@ -584,10 +854,10 @@ export class CanvasDOMSprite extends CanvasDOMElement {
|
|
|
584
854
|
}
|
|
585
855
|
const frames = this.getFrames();
|
|
586
856
|
if (frames.length === 0) {
|
|
587
|
-
if (this.
|
|
588
|
-
(
|
|
857
|
+
if (this.renderElementType === "img" && this.image && target) {
|
|
858
|
+
(target as HTMLImageElement).src = this.image;
|
|
589
859
|
} else if (this.image) {
|
|
590
|
-
|
|
860
|
+
target.style.backgroundImage = `url("${this.image}")`;
|
|
591
861
|
}
|
|
592
862
|
return;
|
|
593
863
|
}
|
|
@@ -603,27 +873,38 @@ export class CanvasDOMSprite extends CanvasDOMElement {
|
|
|
603
873
|
|
|
604
874
|
private applyFrame(frame: DOMSpriteFrame) {
|
|
605
875
|
if (!this.element) return;
|
|
606
|
-
|
|
607
|
-
|
|
876
|
+
const target = this.getRenderElement();
|
|
877
|
+
if (!target) return;
|
|
878
|
+
this.frameWidth = frame.width;
|
|
879
|
+
this.frameHeight = frame.height;
|
|
880
|
+
if (this.fitMode === "contain") {
|
|
881
|
+
target.style.width = `${frame.width}px`;
|
|
882
|
+
target.style.height = `${frame.height}px`;
|
|
883
|
+
} else {
|
|
884
|
+
target.style.width = this.explicitWidth ?? `${frame.width}px`;
|
|
885
|
+
target.style.height = this.explicitHeight ?? `${frame.height}px`;
|
|
886
|
+
}
|
|
608
887
|
|
|
609
888
|
const x = frame.x ?? 0;
|
|
610
889
|
const y = frame.y ?? 0;
|
|
611
890
|
|
|
612
|
-
if (this.
|
|
613
|
-
const img =
|
|
891
|
+
if (this.renderElementType === "img") {
|
|
892
|
+
const img = target as HTMLImageElement;
|
|
614
893
|
if (this.image) {
|
|
615
894
|
img.src = this.image;
|
|
616
895
|
}
|
|
617
896
|
img.style.objectFit = "none";
|
|
618
897
|
img.style.objectPosition = `-${x}px -${y}px`;
|
|
898
|
+
this.applyContainScale();
|
|
619
899
|
return;
|
|
620
900
|
}
|
|
621
901
|
|
|
622
902
|
if (this.image) {
|
|
623
|
-
|
|
903
|
+
target.style.backgroundImage = `url("${this.image}")`;
|
|
624
904
|
}
|
|
625
|
-
|
|
626
|
-
|
|
905
|
+
target.style.backgroundRepeat = "no-repeat";
|
|
906
|
+
target.style.backgroundPosition = `-${x}px -${y}px`;
|
|
907
|
+
this.applyContainScale();
|
|
627
908
|
}
|
|
628
909
|
|
|
629
910
|
private updateAnimationLoop() {
|
package/testing/index.ts
CHANGED
|
@@ -30,8 +30,10 @@ export class TestBed {
|
|
|
30
30
|
const comp = () => h(Canvas, {
|
|
31
31
|
tickStart: false
|
|
32
32
|
}, h(component, props, children))
|
|
33
|
+
const enableLayout = options.enableLayout ?? true;
|
|
33
34
|
const { canvasElement, app } = await bootstrapCanvas(root, comp, {
|
|
34
|
-
enableLayout
|
|
35
|
+
enableLayout,
|
|
36
|
+
...(enableLayout ? { layout: { throttle: 0 } } : {})
|
|
35
37
|
})
|
|
36
38
|
app.render()
|
|
37
39
|
TestBed.lastApp = app as Application;
|