Skip to content

Commit 728fb01

Browse files
committed
Correctly using zoom and resolution across all scale modes.
1 parent ab75b1a commit 728fb01

1 file changed

Lines changed: 165 additions & 90 deletions

File tree

src/dom/ScaleManager.js

Lines changed: 165 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
var Class = require('../utils/Class');
88
var NOOP = require('../utils/NOOP');
9+
var Rectangle = require('../geom/rectangle/Rectangle');
910
var Size = require('../structs/Size');
11+
var Vector2 = require('../math/Vector2');
1012

1113
/**
1214
* @classdesc
@@ -36,7 +38,17 @@ var ScaleManager = new Class({
3638
*/
3739
this.game = game;
3840

39-
this.scaleMode = 0;
41+
// Reference to the canvas being scaled
42+
this.canvas;
43+
44+
/**
45+
* The DOM bounds of the canvas element.
46+
*
47+
* @name Phaser.Input.InputManager#canvasBounds
48+
* @type {Phaser.Geom.Rectangle}
49+
* @since 3.16.0
50+
*/
51+
this.canvasBounds = new Rectangle();
4052

4153
// The parent object, often a div, or the browser window
4254
this.parent;
@@ -46,22 +58,32 @@ var ScaleManager = new Class({
4658
// The parent Size object.
4759
this.parentSize = new Size();
4860

49-
// The un-modified game size, as requested in the game config.
61+
// The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, cameras, etc
5062
this.gameSize = new Size();
5163

52-
// The canvas size, which is the game size * zoom * resolution, with the scale mode applied and factoring in the parent.
53-
this.canvasSize = new Size();
64+
// The modified game size, which is the gameSize * resolution, used to set the canvas width/height (but not the CSS style)
65+
this.baseSize = new Size();
66+
67+
// The size used for the canvas style, factoring in the scale mode, parent and other values
68+
this.displaySize = new Size();
69+
70+
this.scaleMode = 0;
5471

5572
// The canvas resolution
5673
this.resolution = 1;
5774

5875
// The canvas zoom factor
5976
this.zoom = 1;
6077

78+
this.autoRound = false;
79+
6180
this.trackParent = false;
6281

6382
this.allowFullScreen = false;
6483

84+
// The scale between the baseSize and the canvasBounds
85+
this.displayScale = new Vector2(1, 1);
86+
6587
this.listeners = {
6688

6789
orientationChange: NOOP,
@@ -79,13 +101,76 @@ var ScaleManager = new Class({
79101
// Parse the config to get the scaling values we need
80102
console.log('preBoot');
81103

82-
this.setParent(this.game.config.parent, this.game.config.expandParent);
83-
84104
this.parseConfig(this.game.config);
85105

86106
this.game.events.once('boot', this.boot, this);
87107
},
88108

109+
// Fires BEFORE the canvas has been created
110+
parseConfig: function (config)
111+
{
112+
console.log('parseConfig');
113+
114+
this.setParent(config.parent, config.expandParent);
115+
116+
var width = config.width;
117+
var height = config.height;
118+
var resolution = config.resolution;
119+
var scaleMode = config.scaleMode;
120+
var zoom = config.zoom;
121+
var autoRound = config.autoRound;
122+
123+
// If width = '100%', or similar value
124+
if (typeof width === 'string')
125+
{
126+
var parentScaleX = parseInt(width, 10) / 100;
127+
128+
width = Math.floor(this.parentSize.width * parentScaleX);
129+
}
130+
131+
// If height = '100%', or similar value
132+
if (typeof height === 'string')
133+
{
134+
var parentScaleY = parseInt(height, 10) / 100;
135+
136+
height = Math.floor(this.parentSize.height * parentScaleY);
137+
}
138+
139+
this.resolution = resolution;
140+
141+
this.zoom = zoom;
142+
143+
this.scaleMode = scaleMode;
144+
145+
this.autoRound = autoRound;
146+
147+
// The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc
148+
this.gameSize.setSize(width, height);
149+
150+
// The modified game size, which is the w/h * resolution
151+
this.baseSize.setSize(width * resolution, height * resolution);
152+
153+
if (autoRound)
154+
{
155+
this.baseSize.width = Math.floor(this.baseSize.width);
156+
this.baseSize.height = Math.floor(this.baseSize.height);
157+
}
158+
159+
if (config.minWidth > 0)
160+
{
161+
this.displaySize.setMin(config.minWidth * zoom, config.minHeight * zoom);
162+
}
163+
164+
if (config.maxWidth > 0)
165+
{
166+
this.displaySize.setMax(config.maxWidth * zoom, config.maxHeight * zoom);
167+
}
168+
169+
// The size used for the canvas style, factoring in the scale mode and parent and zoom value
170+
// We just use the w/h here as this is what sets the aspect ratio (which doesn't then change)
171+
this.displaySize.setSize(width, height);
172+
},
173+
89174
setParent: function (parent, canExpandParent)
90175
{
91176
console.log('setParent');
@@ -138,76 +223,17 @@ var ScaleManager = new Class({
138223

139224
console.log('dom', DOMRect.width, DOMRect.height);
140225

141-
this.parentSize.setSize(DOMRect.width, DOMRect.height);
142-
},
143-
144-
parseConfig: function (config)
145-
{
146-
console.log('parseConfig');
147-
148-
var width = config.width;
149-
var height = config.height;
150-
var resolution = config.resolution;
151-
var scaleMode = config.scaleMode;
152-
var zoom = config.zoom;
153-
154-
// If width = '100%', or similar value
155-
if (typeof width === 'string')
156-
{
157-
var parentScaleX = parseInt(width, 10) / 100;
158-
159-
width = this.parentSize.width * parentScaleX;
160-
}
161-
162-
// If height = '100%', or similar value
163-
if (typeof height === 'string')
164-
{
165-
var parentScaleY = parseInt(height, 10) / 100;
226+
var resolution = this.resolution;
166227

167-
height = this.parentSize.height * parentScaleY;
168-
}
169-
170-
this.resolution = resolution;
171-
172-
this.zoom = zoom;
173-
174-
this.scaleMode = scaleMode;
175-
176-
// The un-modified game size, as requested in the game config.
177-
this.gameSize.setSize(width * resolution, height * resolution);
178-
179-
// this.gameSize.setSize((width * zoom) * resolution, (height * zoom) * resolution);
180-
181-
// if (scaleMode < 5)
182-
// {
183-
// this.canvasSize.setAspectMode(scaleMode);
184-
// }
185-
186-
if (config.minWidth > 0)
187-
{
188-
this.canvasSize.setMin(config.minWidth * zoom, config.minHeight * zoom);
189-
}
190-
191-
if (config.maxWidth > 0)
192-
{
193-
this.canvasSize.setMax(config.maxWidth * zoom, config.maxHeight * zoom);
194-
}
195-
196-
// console.log('set canvas size', width, height);
197-
198-
this.canvasSize.setSize(width * zoom, height * zoom);
199-
200-
// this.canvasSize.setSize((width * zoom) * resolution, (height * zoom) * resolution);
201-
202-
// console.log(this.canvasSize.toString());
228+
this.parentSize.setSize(DOMRect.width * resolution, DOMRect.height * resolution);
203229
},
204230

205-
// Fires AFTER the canvas has been added to the DOM
231+
// Fires AFTER the canvas has been created and added to the DOM
206232
boot: function ()
207233
{
208234
console.log('boot');
209235

210-
// this.setScaleMode(this.scaleMode);
236+
this.canvas = this.game.canvas;
211237

212238
var DOMRect = this.parent.getBoundingClientRect();
213239

@@ -222,14 +248,12 @@ var ScaleManager = new Class({
222248

223249
if (this.scaleMode < 5)
224250
{
225-
this.canvasSize.setAspectMode(this.scaleMode);
251+
this.displaySize.setAspectMode(this.scaleMode);
226252
}
227253

228254
if (this.scaleMode > 0)
229255
{
230-
console.log('set parent');
231-
this.canvasSize.setParent(this.parentSize);
232-
console.log(this.canvasSize.toString());
256+
this.displaySize.setParent(this.parentSize);
233257
}
234258

235259
this.updateScale();
@@ -239,36 +263,87 @@ var ScaleManager = new Class({
239263
this.startListeners();
240264
},
241265

242-
setScaleMode: function ()
243-
{
244-
},
245-
246266
updateScale: function ()
247267
{
248268
console.log('updateScale');
249269

250270
this.getParentBounds();
251271

252-
if (this.scaleMode > 0)
272+
var style = this.canvas.style;
273+
274+
var width = this.gameSize.width;
275+
var height = this.gameSize.height;
276+
277+
var styleWidth;
278+
var styleHeight;
279+
280+
var zoom = this.zoom;
281+
var autoRound = this.autoRound;
282+
var resolution = this.resolution;
283+
284+
if (this.scaleMode === 0)
253285
{
254-
var style = this.game.canvas.style;
286+
// No scale
287+
this.displaySize.setSize((width * zoom) * resolution, (height * zoom) * resolution);
255288

256-
this.canvasSize.setSize(this.parentSize.width, this.parentSize.height);
257-
258-
// var sx = (this.canvasSize.width / this.gameSize.width) / this.resolution;
259-
// var sy = (this.canvasSize.height / this.gameSize.height) / this.resolution;
289+
styleWidth = this.displaySize.width / resolution;
290+
styleHeight = this.displaySize.height / resolution;
291+
292+
if (autoRound)
293+
{
294+
styleWidth = Math.floor(styleWidth);
295+
styleHeight = Math.floor(styleHeight);
296+
}
260297

261-
// style.transformOrigin = '0 0';
262-
// style.transform = 'scale(' + sx + ',' + sy + ')';
298+
style.width = styleWidth + 'px';
299+
style.height = styleHeight + 'px';
300+
}
301+
else if (this.scaleMode === 5)
302+
{
303+
// Resize to match parent
304+
}
305+
else
306+
{
307+
// All other scale modes
308+
this.displaySize.setSize(this.parentSize.width, this.parentSize.height);
263309

264-
style.width = this.canvasSize.width + 'px';
265-
style.height = this.canvasSize.height + 'px';
310+
styleWidth = this.displaySize.width / resolution;
311+
styleHeight = this.displaySize.height / resolution;
266312

267-
// style.width = this.canvasSize.width / this.resolution + 'px';
268-
// style.height = this.canvasSize.height / this.resolution + 'px';
313+
if (autoRound)
314+
{
315+
styleWidth = Math.floor(styleWidth);
316+
styleHeight = Math.floor(styleHeight);
317+
}
269318

270-
console.log(this.canvasSize.toString());
319+
style.width = styleWidth + 'px';
320+
style.height = styleHeight + 'px';
271321
}
322+
323+
this.updateBounds();
324+
325+
// this.game.resize();
326+
},
327+
328+
/**
329+
* Updates the Input Manager bounds rectangle to match the bounding client rectangle of the
330+
* canvas element being used to track input events.
331+
*
332+
* @method Phaser.DOM.ScaleManager#updateBounds
333+
* @since 3.16.0
334+
*/
335+
updateBounds: function ()
336+
{
337+
var bounds = this.canvasBounds;
338+
339+
var clientRect = this.canvas.getBoundingClientRect();
340+
341+
bounds.x = clientRect.left + window.pageXOffset - document.documentElement.clientLeft;
342+
bounds.y = clientRect.top + window.pageYOffset - document.documentElement.clientTop;
343+
bounds.width = clientRect.width;
344+
bounds.height = clientRect.height;
345+
346+
this.displayScale.set(this.baseSize.width / bounds.width, this.baseSize.height / bounds.height);
272347
},
273348

274349
startListeners: function ()

0 commit comments

Comments
 (0)