Skip to content

Commit 95caa33

Browse files
committed
Reduce DPI if canvas is too big to avoid page crash - this happen on webpage on mobile with high dpi and missing meta viewport tag with width=device-width.
1 parent 59d6cf1 commit 95caa33

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

spine-ts/spine-webgl/src/SpineWebComponentWidget.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,7 @@ export class SpineWebComponentWidget extends HTMLElement implements Disposable,
10031003
// to simplify we just assume that the user wants to load the skeleton at scale 1
10041004
// at the current browser zoom level
10051005
// this might be problematic for free-scale modes (origin and inside+none)
1006-
this.currentScaleDpi = window.devicePixelRatio;
1006+
this.currentScaleDpi = this.overlay.getDPR();
10071007
// skeleton.scaleX = this.currentScaleDpi;
10081008
// skeleton.scaleY = this.currentScaleDpi;
10091009

@@ -2124,7 +2124,7 @@ class SpineWebComponentOverlay extends HTMLElement implements OverlayAttributes,
21242124
// I'm not sure about this. With mode origin and fit none:
21252125
// case 1) If I comment this scale code, the skeleton is never scaled and will be always at the same size and won't change size while zooming
21262126
// case 2) Otherwise, the skeleton is loaded always at the same size, but changes size while zooming
2127-
const scale = window.devicePixelRatio;
2127+
const scale = this.getDPR();
21282128
skeleton.scaleX = skeleton.scaleX / widget.currentScaleDpi * scale;
21292129
skeleton.scaleY = skeleton.scaleY / widget.currentScaleDpi * scale;
21302130
widget.currentScaleDpi = scale;
@@ -2177,8 +2177,8 @@ class SpineWebComponentOverlay extends HTMLElement implements OverlayAttributes,
21772177

21782178
private resize (width: number, height: number) {
21792179
let canvas = this.canvas;
2180-
this.canvas.width = Math.round(this.screenToWorldLength(width));
2181-
this.canvas.height = Math.round(this.screenToWorldLength(height));
2180+
canvas.width = Math.round(this.screenToWorldLength(width));
2181+
canvas.height = Math.round(this.screenToWorldLength(height));
21822182
this.renderer.context.gl.viewport(0, 0, canvas.width, canvas.height);
21832183
this.renderer.camera.setViewport(canvas.width, canvas.height);
21842184
this.renderer.camera.update();
@@ -2196,11 +2196,13 @@ class SpineWebComponentOverlay extends HTMLElement implements OverlayAttributes,
21962196
private previousDPR = 0;
21972197
private static readonly WIDTH_INCREMENT = 1.15;
21982198
private static readonly HEIGHT_INCREMENT = 1.2;
2199-
private getScreenSize () {
2199+
private static readonly MAX_CANVAS_WIDTH = 7000;
2200+
private static readonly MAX_CANVAS_HEIGHT = 7000;
2201+
private getScreenSize (): { width: number, height: number} {
22002202
let width = window.innerWidth;
22012203
let height = window.innerHeight;
22022204

2203-
const dpr = window.devicePixelRatio;
2205+
const dpr = this.getDPR();
22042206
if (dpr !== this.previousDPR) {
22052207
this.previousDPR = dpr;
22062208
this.previousWidth = this.previousWidth === 0 ? width : width * SpineWebComponentOverlay.WIDTH_INCREMENT;
@@ -2210,12 +2212,25 @@ class SpineWebComponentOverlay extends HTMLElement implements OverlayAttributes,
22102212
if (height > this.previousHeight) this.previousHeight = height * SpineWebComponentOverlay.HEIGHT_INCREMENT;
22112213
}
22122214

2215+
// if the resulting canvas width/height is too high, scale the DPI
2216+
if (this.previousHeight * (1 + this.overflowTop + this.overflowBottom) * dpr > SpineWebComponentOverlay.MAX_CANVAS_HEIGHT ||
2217+
this.previousWidth * (1 + this.overflowLeft + this.overflowRight) * dpr > SpineWebComponentOverlay.MAX_CANVAS_WIDTH)
2218+
{
2219+
this.scaleDPR += .5;
2220+
return this.getScreenSize();
2221+
}
2222+
22132223
return {
22142224
width: this.previousWidth,
22152225
height: this.previousHeight,
22162226
}
22172227
}
22182228

2229+
private scaleDPR = 1;
2230+
public getDPR() {
2231+
return window.devicePixelRatio / this.scaleDPR;
2232+
}
2233+
22192234
/*
22202235
* Other utilities
22212236
*/
@@ -2231,10 +2246,10 @@ class SpineWebComponentOverlay extends HTMLElement implements OverlayAttributes,
22312246
this.renderer.camera.worldToScreen(vec, this.worldToScreenLength(this.renderer.camera.viewportWidth), this.worldToScreenLength(this.renderer.camera.viewportHeight));
22322247
}
22332248
public screenToWorldLength (length: number) {
2234-
return length * window.devicePixelRatio;
2249+
return length * this.getDPR();
22352250
}
22362251
public worldToScreenLength (length: number) {
2237-
return length / window.devicePixelRatio;
2252+
return length / this.getDPR();
22382253
}
22392254
}
22402255

0 commit comments

Comments
 (0)