@@ -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