diff --git a/spine-ts/spine-player/example/physics.html b/spine-ts/spine-player/example/physics.html
index 045a5ae0b..21a52b5a2 100644
--- a/spine-ts/spine-player/example/physics.html
+++ b/spine-ts/spine-player/example/physics.html
@@ -17,7 +17,7 @@
last = new spine.Vector3();
new spine.SpinePlayer("player", {
skeleton: "assets/celestial-circus-pro.skel",
- url: "assets/celestial-circus-pma.atlas",
+ atlas: "assets/celestial-circus-pma.atlas",
showControls: true,
animation: "swing",
success: (player) => {
diff --git a/spine-ts/spine-webgl/example/webcomponent.html b/spine-ts/spine-webgl/example/webcomponent.html
index a00aad89d..8b0468009 100644
--- a/spine-ts/spine-webgl/example/webcomponent.html
+++ b/spine-ts/spine-webgl/example/webcomponent.html
@@ -14,6 +14,7 @@
}
body {
font-family: Arial, sans-serif;
+ font-size: 16px;
}
.section {
display: flex;
@@ -1712,7 +1713,7 @@ stretchyman.update = (canvas, delta, skeleton, state) => {
atlas="assets/celestial-circus-pma.atlas"
skeleton="assets/celestial-circus-pro.skel"
clip
- draggable
+ isdraggable
>
diff --git a/spine-ts/spine-webgl/src/Input.ts b/spine-ts/spine-webgl/src/Input.ts
index f763685dc..4561f49cb 100644
--- a/spine-ts/spine-webgl/src/Input.ts
+++ b/spine-ts/spine-webgl/src/Input.ts
@@ -36,11 +36,11 @@ export class Input {
touch1: Touch | null = null;
initialPinchDistance = 0;
private listeners = new Array();
- private preventDefault: boolean;
+ private autoPreventDefault: boolean;
- constructor (element: HTMLElement, preventDefault = true) {
+ constructor (element: HTMLElement, autoPreventDefault = true) {
this.element = element;
- this.preventDefault = preventDefault;
+ this.autoPreventDefault = autoPreventDefault;
this.setupCallbacks(element);
}
@@ -48,7 +48,7 @@ export class Input {
let mouseDown = (ev: UIEvent) => {
if (ev instanceof MouseEvent) {
let rect = element.getBoundingClientRect();
- this.mouseX = ev.clientX - rect.left;;
+ this.mouseX = ev.clientX - rect.left;
this.mouseY = ev.clientY - rect.top;
this.buttonDown = true;
this.listeners.map((listener) => { if (listener.down) listener.down(this.mouseX, this.mouseY, ev); });
@@ -88,7 +88,7 @@ export class Input {
}
let mouseWheel = (ev: WheelEvent) => {
- if (this.preventDefault) ev.preventDefault();
+ if (this.autoPreventDefault) ev.preventDefault();
let deltaY = ev.deltaY;
if (ev.deltaMode == WheelEvent.DOM_DELTA_LINE) deltaY *= 8;
if (ev.deltaMode == WheelEvent.DOM_DELTA_PAGE) deltaY *= 24;
@@ -125,8 +125,8 @@ export class Input {
this.listeners.map((listener) => { if (listener.zoom) listener.zoom(this.initialPinchDistance, this.initialPinchDistance, ev) });
}
}
- if (this.preventDefault) ev.preventDefault();
- }, { passive: this.preventDefault });
+ if (this.autoPreventDefault) ev.preventDefault();
+ }, { passive: false, capture: false });
element.addEventListener("touchmove", (ev: TouchEvent) => {
if (this.touch0) {
@@ -154,8 +154,8 @@ export class Input {
this.listeners.map((listener) => { if (listener.zoom) listener.zoom(this.initialPinchDistance, distance, ev) });
}
}
- if (this.preventDefault) ev.preventDefault();
- }, { passive: this.preventDefault });
+ if (this.autoPreventDefault) ev.preventDefault();
+ }, { passive: false, capture: false });
let touchEnd = (ev: TouchEvent) => {
if (this.touch0) {
@@ -191,9 +191,9 @@ export class Input {
}
}
}
- if (this.preventDefault) ev.preventDefault();
+ if (this.autoPreventDefault) ev.preventDefault();
};
- element.addEventListener("touchend", touchEnd, false);
+ element.addEventListener("touchend", touchEnd, { passive: false, capture: false });
element.addEventListener("touchcancel", touchEnd);
}
diff --git a/spine-ts/spine-webgl/src/SpineWebComponentWidget.ts b/spine-ts/spine-webgl/src/SpineWebComponentWidget.ts
index 049f58651..0c79bf384 100644
--- a/spine-ts/spine-webgl/src/SpineWebComponentWidget.ts
+++ b/spine-ts/spine-webgl/src/SpineWebComponentWidget.ts
@@ -111,7 +111,7 @@ interface WidgetAttributes {
offsetY: number
width: number
height: number
- draggable: boolean
+ isDraggable: boolean
debug: boolean
identifier: string
manualStart: boolean
@@ -280,9 +280,9 @@ export class SpineWebComponentWidget extends HTMLElement implements WidgetAttrib
/**
* If true, the widget is draggable
- * Connected to `draggable` attribute.
+ * Connected to `isdraggable` attribute.
*/
- public draggable = false;
+ public isDraggable = false;
/**
* If true, some convenience elements are drawn to show the skeleton world origin (green),
@@ -488,7 +488,7 @@ export class SpineWebComponentWidget extends HTMLElement implements WidgetAttrib
skin: { propertyName: "skin", type: "string" },
width: { propertyName: "width", type: "number", defaultValue: -1 },
height: { propertyName: "height", type: "number", defaultValue: -1 },
- draggable: { propertyName: "draggable", type: "boolean" },
+ isdraggable: { propertyName: "isDraggable", type: "boolean" },
"x-axis": { propertyName: "xAxis", type: "number" },
"y-axis": { propertyName: "yAxis", type: "number" },
"offset-x": { propertyName: "offsetX", type: "number" },
@@ -505,29 +505,7 @@ export class SpineWebComponentWidget extends HTMLElement implements WidgetAttrib
}
static get observedAttributes(): string[] {
- return [
- "atlas", // atlasPath
- "skeleton", // skeletonPath
- "scale", // scale
- "animation", // animation
- "skin", // skin
- "fit", // fit
- "width", // width
- "height", // height
- "draggable", // draggable
- "mode", // mode
- "x-axis", // xAxis
- "y-axis", // yAxis
- "offset-x", // offsetX
- "offset-y", // offsetY
- "identifier", // identifier
- "debug", // debug
- "manual-start", // manualStart
- "spinner", // loadingSpinner
- "pages", // pages
- "offscreen", // offScreenUpdateBehaviour
- "clip", // clip
- ];
+ return Object.keys(SpineWebComponentWidget.attributesDescription);
}
constructor() {
@@ -843,7 +821,6 @@ class SpineWebComponentOverlay extends HTMLElement {
public skeletonList = new Array();
private intersectionObserver? : IntersectionObserver;
- private resizeObserver:ResizeObserver;
private input: Input;
// how many pixels to add to the edges to prevent "edge cuttin" on fast scrolling
@@ -896,40 +873,61 @@ class SpineWebComponentOverlay extends HTMLElement {
const context = new ManagedWebGLRenderingContext(this.canvas, { alpha: true });
this.renderer = new SceneRenderer(this.canvas, context);
this.assetManager = new AssetManager(context);
- this.input = new Input(this.canvas);
+ this.input = new Input(this.canvas, false);
this.setupRenderingElements();
- this.updateCanvasSize();
- this.zoomHandler();
-
- // translateCanvas starts a requestAnimationFrame loop
- this.translateCanvas();
-
this.overflowLeftSize = this.overflowLeft * document.documentElement.clientWidth;
this.overflowTopSize = this.overflowTop * document.documentElement.clientHeight;
- // resize and zoom
- // TODO: should I use the resize event?
- this.resizeObserver = new ResizeObserver(() => {
+ window.addEventListener('resize', () => {
this.updateCanvasSize();
- this.zoomHandler();
+ this.zoomHandler();
});
- this.resizeObserver.observe(document.body);
- const screen = window.screen;
- screen.orientation.onchange = () => {
+ window.screen.orientation.onchange = () => {
this.updateCanvasSize();
// after an orientation change the scrolling changes, but the scroll event does not fire
this.scrollHandler();
}
window.addEventListener("scroll", this.scrollHandler);
- this.scrollHandler();
+
+ window.onload = () => {
+ this.updateCanvasSize();
+ this.zoomHandler();
+
+ // translateCanvas starts a requestAnimationFrame loop
+ this.translateCanvas();
+
+ this.scrollHandler();
+ };
this.input = new Input(document.body, false);
this.setupDragUtility();
}
+ connectedCallback(): void {
+ this.intersectionObserver = new IntersectionObserver((widgets) => {
+ widgets.forEach(({ isIntersecting, target, intersectionRatio }) => {
+ const widget = this.skeletonList.find(w => w.getHTMLElementReference() == target);
+ if (!widget) return;
+
+ // old browsers do not have isIntersecting
+ if (isIntersecting === undefined) {
+ isIntersecting = intersectionRatio > 0;
+ }
+
+ widget.onScreen = isIntersecting;
+ if (isIntersecting) {
+ widget.onScreenFunction(widget);
+ }
+ })
+ }, { rootMargin: "30px 20px 30px 20px" });
+ }
+
+ disconnectedCallback(): void {
+ }
+
addWidget(widget: SpineWebComponentWidget) {
this.skeletonList.push(widget);
this.intersectionObserver!.observe(widget.getHTMLElementReference());
@@ -1028,12 +1026,13 @@ class SpineWebComponentOverlay extends HTMLElement {
const devicePixelRatio = window.devicePixelRatio;
const tempVector = new Vector3();
this.skeletonList.forEach((widget) => {
- const { skeleton, bounds, mode, debug, offsetX, offsetY, xAxis, yAxis, dragX, dragY, fit, loadingSpinner, onScreen, loading, clip, draggable } = widget;
+ const { skeleton, bounds, mode, debug, offsetX, offsetY, xAxis, yAxis, dragX, dragY, fit, loadingSpinner, onScreen, loading, clip, isDraggable } = widget;
if ((!onScreen && dragX === 0 && dragY === 0)) return;
const divBounds = widget.getHTMLElementReference().getBoundingClientRect();
- divBounds.x += this.overflowLeftSize;
- divBounds.y += this.overflowTopSize;
+ // need to use left and top, because x and y are not available on older browser
+ divBounds.x = divBounds.left + this.overflowLeftSize;
+ divBounds.y = divBounds.top + this.overflowTopSize;
let divOriginX = 0;
let divOriginY = 0;
@@ -1137,8 +1136,8 @@ class SpineWebComponentOverlay extends HTMLElement {
}
});
- // store the draggable surface to make darg logic easier
- if (draggable) {
+ // store the draggable surface to make drag logic easier
+ if (isDraggable) {
let { x: ax, y: ay, width: aw, height: ah } = bounds!;
this.worldToScreen(tempVector, ax * skeleton.scaleX + worldOffsetX, ay * skeleton.scaleY + worldOffsetY);
widget.dragBoundsRectangle.x = tempVector.x + window.scrollX;
@@ -1211,24 +1210,6 @@ class SpineWebComponentOverlay extends HTMLElement {
const transparentWhite = new Color(1, 1, 1, .3);
}
- connectedCallback(): void {
- this.intersectionObserver = new IntersectionObserver((widgets) => {
- widgets.forEach(({ isIntersecting, target }) => {
-
- const widget = this.skeletonList.find(w => w.getHTMLElementReference() == target);
- if (!widget) return;
- widget.onScreen = isIntersecting;
- if (isIntersecting) {
- widget.onScreenFunction(widget);
- }
- })
- }, { rootMargin: "30px 20px 30px 20px" });
- }
-
- disconnectedCallback(): void {
- }
-
- // TODO: drag is bugged when zoom on browser (just zoom and activare debug to see the drag surface has some offset)
private setupDragUtility() {
// TODO: we should use document - body might have some margin that offset the click events - Meanwhile I take event pageX/Y
const point: Point = { x: 0, y: 0 };
@@ -1246,7 +1227,7 @@ class SpineWebComponentOverlay extends HTMLElement {
down: (x, y, ev) => {
const input = getInput(ev);
this.skeletonList.forEach(widget => {
- if (!widget.draggable || (!widget.onScreen && widget.dragX === 0 && widget.dragY === 0)) return;
+ if (!widget.isDraggable || (!widget.onScreen && widget.dragX === 0 && widget.dragY === 0)) return;
if (inside(input, widget.dragBoundsRectangle)) {
widget.dragging = true;
ev?.preventDefault();