ScaleManager + DOM - window constraint updates

ScaleManager.windowContraints now allows specifing 'visual' or 'layout' as
the constraint. Using the 'layout' constraint should prevent a mobile
device from trying to resize the game when zooming.

Including the the new changes the defaults have been changed to

   windowContraints = { right: 'layout', bottom: '' }

This changes the current scaling behavior as seen in "Game Scaling" (as it
will only scale for the right edge) but also prevents such scaling from
going wonkers in some mobile environtments like the newer Android browser.
(Automatic scroll-to-top, albeit configurable, enabled for non-desktop by
default is not a fun situation here.)

To obtain the current semantics on a desktop the bottom should be changed
to 'layout'; although this will result in different behavior depending on
mobile device. To make the sizing also follow mobile zooming they should
be changed to 'visual'.

Also added temp Rectangle re-used for various internal calculations.

---

Phaser.DOM now also special-cases desktops to align the layout bounds
correctly (this may disagree with CSS breakpoints but it aligns the with
actual CSS width), without applying a window height/width expansion as
required on mobile browsers.

(And the jshint error isn't mine..)
This commit is contained in:
Paul 2014-11-19 12:27:52 -08:00
parent babb8687c8
commit e7fd527c72
2 changed files with 83 additions and 60 deletions

View file

@ -416,18 +416,21 @@ Phaser.ScaleManager = function (game, width, height) {
this.event = null; this.event = null;
/** /**
* The edges on which to constrain the Display canvas _to_ the viewport in _addition_ to any restrictions of the Parent element. * The edges on which to constrain the game Display/canvas in _addition_ to the restrictions of the parent container.
* *
* The viewport does not include the scrollbars by default. * The properties are strings and can be '', 'visual', 'layout', or 'layout-soft'.
* - If 'visual', the edge will be constrained to the Window / displayed screen area
* - If 'layout', the edge will be constrained to the CSS Layout bounds
* - An invalid value is treated as 'visual'
* *
* Call {@link Phaser.ScaleManager#refresh refresh} after modifying this object. * @member
* * @property {string} bottom
* @property {boolean} windowConstraints * @property {string} right
* @default * @default
*/ */
this.windowConstraints = { this.windowConstraints = {
bottom: true, right: 'layout',
right: true bottom: ''
}; };
/** /**
@ -593,6 +596,13 @@ Phaser.ScaleManager = function (game, width, height) {
*/ */
this._parentBounds = new Phaser.Rectangle(); this._parentBounds = new Phaser.Rectangle();
/**
* Temporary bounds used for internal work to cut down on new objects created.
* @property {Phaser.Rectangle} _parentBounds
* @private
*/
this._tempBounds = new Phaser.Rectangle();
/** /**
* The Canvas size at which the last onSizeChange signal was triggered. * The Canvas size at which the last onSizeChange signal was triggered.
* @property {Phaser.Rectangle} _lastReportedCanvasSize * @property {Phaser.Rectangle} _lastReportedCanvasSize
@ -1376,7 +1386,7 @@ Phaser.ScaleManager.prototype = {
if (!this.compatibility.canExpandParent && if (!this.compatibility.canExpandParent &&
(scaleMode === Phaser.ScaleManager.SHOW_ALL || scaleMode === Phaser.ScaleManager.USER_SCALE)) (scaleMode === Phaser.ScaleManager.SHOW_ALL || scaleMode === Phaser.ScaleManager.USER_SCALE))
{ {
var bounds = this.getParentBounds(); var bounds = this.getParentBounds(this._tempBounds);
this.width = Math.min(this.width, bounds.width); this.width = Math.min(this.width, bounds.width);
this.height = Math.min(this.height, bounds.height); this.height = Math.min(this.height, bounds.height);
} }
@ -1409,11 +1419,12 @@ Phaser.ScaleManager.prototype = {
var bounds = target || new Phaser.Rectangle(); var bounds = target || new Phaser.Rectangle();
var parentNode = this.boundingParent; var parentNode = this.boundingParent;
var vp = this.dom.visualBounds; var visualBounds = this.dom.visualBounds;
var layoutBounds = this.dom.layoutBounds;
if (!parentNode) if (!parentNode)
{ {
bounds.setTo(0, 0, vp.width, vp.height); bounds.setTo(0, 0, visualBounds.width, visualBounds.height);
} }
else else
{ {
@ -1425,11 +1436,13 @@ Phaser.ScaleManager.prototype = {
var wc = this.windowConstraints; var wc = this.windowConstraints;
if (wc.right) if (wc.right)
{ {
bounds.right = Math.min(bounds.right, vp.width); var windowBounds = wc.right === 'layout' ? layoutBounds : visualBounds;
bounds.right = Math.min(bounds.right, windowBounds.width);
} }
if (wc.bottom) if (wc.bottom)
{ {
bounds.bottom = Math.min(bounds.bottom, vp.height); var windowBounds = wc.bottom === 'layout' ? layoutBounds : visualBounds;
bounds.bottom = Math.min(bounds.bottom, windowBounds.height);
} }
} }
@ -1453,7 +1466,7 @@ Phaser.ScaleManager.prototype = {
*/ */
alignCanvas: function (horizontal, vertical) { alignCanvas: function (horizontal, vertical) {
var parentBounds = this.getParentBounds(); var parentBounds = this.getParentBounds(this._tempBounds);
var canvas = this.game.canvas; var canvas = this.game.canvas;
var margin = this.margin; var margin = this.margin;
@ -1527,7 +1540,7 @@ Phaser.ScaleManager.prototype = {
this.resetCanvas('', ''); this.resetCanvas('', '');
var bounds = this.getParentBounds(); var bounds = this.getParentBounds(this._tempBounds);
this.updateDimensions(bounds.width, bounds.height, true); this.updateDimensions(bounds.width, bounds.height, true);
}, },
@ -1646,7 +1659,7 @@ Phaser.ScaleManager.prototype = {
*/ */
setShowAll: function (expanding) { setShowAll: function (expanding) {
var bounds = this.getParentBounds(); var bounds = this.getParentBounds(this._tempBounds);
var width = bounds.width; var width = bounds.width;
var height = bounds.height; var height = bounds.height;
@ -1674,7 +1687,7 @@ Phaser.ScaleManager.prototype = {
*/ */
setExactFit: function () { setExactFit: function () {
var bounds = this.getParentBounds(); var bounds = this.getParentBounds(this._tempBounds);
this.width = bounds.width; this.width = bounds.width;
this.height = bounds.height; this.height = bounds.height;

View file

@ -309,9 +309,6 @@ Phaser.Device.whenReady(function (device) {
get: scrollY get: scrollY
}); });
// For Phaser.DOM.visualBounds
// Ref. http://quirksmode.org/mobile/tableViewport.html
Object.defineProperty(Phaser.DOM.visualBounds, "x", { Object.defineProperty(Phaser.DOM.visualBounds, "x", {
get: scrollX get: scrollX
}); });
@ -320,23 +317,46 @@ Phaser.Device.whenReady(function (device) {
get: scrollY get: scrollY
}); });
Object.defineProperty(Phaser.DOM.layoutBounds, "x", {
value: 0
});
Object.defineProperty(Phaser.DOM.layoutBounds, "y", {
value: 0
});
var treatAsDesktop = device.desktop &&
(document.documentElement.clientWidth <= window.innerWidth) &&
(document.documentElement.clientHeight <= window.innerHeight);
// Desktop browsers align the layout viewport with the visual viewport. // Desktop browsers align the layout viewport with the visual viewport.
// This differs from mobile browsers with their zooming design. // This differs from mobile browsers with their zooming design.
if (device.desktop && // Ref. http://quirksmode.org/mobile/tableViewport.html
(document.documentElement.clientWidth <= window.innerWidth) && if (treatAsDesktop)
(document.documentElement.clientHeight <= window.innerHeight))
{ {
var clientWidth = function () {
return document.documentElement.clientWidth;
};
var clientHeight = function () {
return document.documentElement.clientHeight;
};
// Interested in area sans-scrollbar
Object.defineProperty(Phaser.DOM.visualBounds, "width", { Object.defineProperty(Phaser.DOM.visualBounds, "width", {
get: function () { get: clientWidth
return document.documentElement.clientWidth;
}
}); });
Object.defineProperty(Phaser.DOM.visualBounds, "height", { Object.defineProperty(Phaser.DOM.visualBounds, "height", {
get: function () { get: clientHeight
return document.documentElement.clientHeight; });
}
Object.defineProperty(Phaser.DOM.layoutBounds, "width", {
get: clientWidth
});
Object.defineProperty(Phaser.DOM.layoutBounds, "height", {
get: clientHeight
}); });
} else { } else {
@ -353,40 +373,30 @@ Phaser.Device.whenReady(function (device) {
} }
}); });
Object.defineProperty(Phaser.DOM.layoutBounds, "width", {
get: function () {
var a = document.documentElement.clientWidth;
var b = window.innerWidth;
return a < b ? b : a; // max
}
});
Object.defineProperty(Phaser.DOM.layoutBounds, "height", {
get: function () {
var a = document.documentElement.clientHeight;
var b = window.innerHeight;
return a < b ? b : a; // max
}
});
} }
// For Phaser.DOM.layoutBounds
Object.defineProperty(Phaser.DOM.layoutBounds, "x", {
value: 0
});
Object.defineProperty(Phaser.DOM.layoutBounds, "y", {
value: 0
});
Object.defineProperty(Phaser.DOM.layoutBounds, "width", {
get: function () {
var a = document.documentElement.clientWidth;
var b = window.innerWidth;
return a < b ? b : a; // max
}
});
Object.defineProperty(Phaser.DOM.layoutBounds, "height", {
get: function () {
var a = document.documentElement.clientHeight;
var b = window.innerHeight;
return a < b ? b : a; // max
}
});
// For Phaser.DOM.documentBounds // For Phaser.DOM.documentBounds
// Ref. http://www.quirksmode.org/mobile/tableViewport_desktop.html // Ref. http://www.quirksmode.org/mobile/tableViewport_desktop.html