mirror of
https://github.com/photonstorm/phaser
synced 2025-02-18 15:08:31 +00:00
Updated Size component to handle fitting, ratios, locking and more.
This commit is contained in:
parent
c6f72241e3
commit
f5fcea898c
1 changed files with 303 additions and 55 deletions
|
@ -4,12 +4,16 @@
|
||||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var Clamp = require('../math/Clamp');
|
||||||
var Class = require('../utils/Class');
|
var Class = require('../utils/Class');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @classdesc
|
* @classdesc
|
||||||
* The Size component is a simple structure that helps you encapsulate a `width` and `height` and, if required, maintain
|
* The Size component allows you to set `width` and `height` properties and define the relationship between them.
|
||||||
* the aspect ratios between them.
|
*
|
||||||
|
* The component can automatically maintain the aspect ratios between the two values, and clamp them
|
||||||
|
* to a defined min-max range. You can also control the dominant axis. When dimensions are given to the Size component
|
||||||
|
* that would cause it to exceed its min-max range, the dimensions are adjusted based on the dominant axis.
|
||||||
*
|
*
|
||||||
* @class Size
|
* @class Size
|
||||||
* @memberof Phaser.Structs
|
* @memberof Phaser.Structs
|
||||||
|
@ -18,17 +22,19 @@ var Class = require('../utils/Class');
|
||||||
*
|
*
|
||||||
* @param {number} [width] - The width of the Size component.
|
* @param {number} [width] - The width of the Size component.
|
||||||
* @param {number} [height=width] - The height of the Size component. If not given, it will use the `width`.
|
* @param {number} [height=width] - The height of the Size component. If not given, it will use the `width`.
|
||||||
* @param {boolean} [lockAspectRatio=false] - Should the aspect ratio between the `width` and `height` be locked?
|
* @param {boolean} [lockAspectRatio=false] - Should the aspect ratio be locked? It will be based on the given `width` and `height` arguments.
|
||||||
|
* @param {boolean} [lockWidth=true] - Set to `true` to make the `width` the dominant axis, or `false` to make `height` the dominant axis.
|
||||||
*/
|
*/
|
||||||
var Size = new Class({
|
var Size = new Class({
|
||||||
|
|
||||||
initialize:
|
initialize:
|
||||||
|
|
||||||
function Size (width, height, lockAspectRatio)
|
function Size (width, height, lockAspectRatio, lockWidth)
|
||||||
{
|
{
|
||||||
if (width === undefined) { width = 0; }
|
if (width === undefined) { width = 0; }
|
||||||
if (height === undefined) { height = width; }
|
if (height === undefined) { height = width; }
|
||||||
if (lockAspectRatio === undefined) { lockAspectRatio = false; }
|
if (lockAspectRatio === undefined) { lockAspectRatio = false; }
|
||||||
|
if (lockWidth === undefined) { lockWidth = true; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width.
|
* The width.
|
||||||
|
@ -61,7 +67,7 @@ var Size = new Class({
|
||||||
* @readonly
|
* @readonly
|
||||||
* @since 3.16.0
|
* @since 3.16.0
|
||||||
*/
|
*/
|
||||||
this.ratioH = (height === 0) ? 0 : width / height;
|
this.ratioH = (height === 0) ? 1 : width / height;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The proportional relationship between the height and width.
|
* The proportional relationship between the height and width.
|
||||||
|
@ -74,18 +80,70 @@ var Size = new Class({
|
||||||
* @readonly
|
* @readonly
|
||||||
* @since 3.16.0
|
* @since 3.16.0
|
||||||
*/
|
*/
|
||||||
this.ratioV = (width === 0) ? 0 : height / width;
|
this.ratioV = (width === 0) ? 1 : height / width;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock the aspect ratio to its current value?
|
* Set this property to lock the aspect ratios to their current values.
|
||||||
*
|
*
|
||||||
* If enabled, changing the width or height properties will automatically adjust the other based on the aspect ratio.
|
* Once enabled, changing the `width` or `height` properties will automatically adjust the other based on the aspect ratio.
|
||||||
*
|
*
|
||||||
* @name Phaser.Structs.Size#lock
|
* @name Phaser.Structs.Size#lockAspectRatio
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
* @since 3.16.0
|
* @since 3.16.0
|
||||||
*/
|
*/
|
||||||
this.lock = lockAspectRatio;
|
this.lockAspectRatio = lockAspectRatio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When scaling the Size based on the min-max range and the aspect ratio, this property controls the priority of
|
||||||
|
* the axis. If `true` (the default) the `width` will be the dominant axis, and the height will adjust to match it. If `false`,
|
||||||
|
* the `height` will be the dominant axis, and the `width` will adjust to match it.
|
||||||
|
*
|
||||||
|
* @name Phaser.Structs.Size#lockWidth
|
||||||
|
* @type {boolean}
|
||||||
|
* @default true
|
||||||
|
* @since 3.16.0
|
||||||
|
*/
|
||||||
|
this.lockWidth = lockWidth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum allowed width.
|
||||||
|
*
|
||||||
|
* @name Phaser.Structs.Size#_minWidth
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
* @since 3.16.0
|
||||||
|
*/
|
||||||
|
this._minWidth = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum allowed height.
|
||||||
|
*
|
||||||
|
* @name Phaser.Structs.Size#_minHeight
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
* @since 3.16.0
|
||||||
|
*/
|
||||||
|
this._minHeight = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum allowed width.
|
||||||
|
*
|
||||||
|
* @name Phaser.Structs.Size#_maxWidth
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
* @since 3.16.0
|
||||||
|
*/
|
||||||
|
this._maxWidth = Number.MAX_VALUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum allowed height.
|
||||||
|
*
|
||||||
|
* @name Phaser.Structs.Size#_maxHeight
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
* @since 3.16.0
|
||||||
|
*/
|
||||||
|
this._maxHeight = Number.MAX_VALUE;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,41 +160,247 @@ var Size = new Class({
|
||||||
*/
|
*/
|
||||||
setAspectRatioLock: function (value)
|
setAspectRatioLock: function (value)
|
||||||
{
|
{
|
||||||
this.lock = value;
|
this.lockAspectRatio = value;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock the aspect ratio to its current value?
|
* Set the minimum width and height values this Size component will allow.
|
||||||
*
|
*
|
||||||
* If enabled, changing the `width` or `height` properties will automatically adjust the other based on the aspect ratio.
|
* If enabled, the properties will be clamped to the min-max range, including when locked to their aspect ratios.
|
||||||
|
*
|
||||||
|
* Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range.
|
||||||
*
|
*
|
||||||
* @method Phaser.Structs.Size#set
|
* @method Phaser.Structs.Size#setMin
|
||||||
* @since 3.16.0
|
* @since 3.16.0
|
||||||
*
|
*
|
||||||
* @param {number} [width] - The width of the Size component.
|
* @param {number} [width=0] - The minimum allowed width of the Size component.
|
||||||
* @param {number} [height=width] - The height of the Size component. If not given, it will use the `width`.
|
* @param {number} [height=width] - The minimum allowed height of the Size component. If not given, it will use the `width`.
|
||||||
* @param {boolean} [lockAspectRatio=false] - Should the aspect ratio between the `width` and `height` be locked?
|
|
||||||
*
|
*
|
||||||
* @return {this} This Size instance.
|
* @return {this} This Size instance.
|
||||||
*/
|
*/
|
||||||
set: function (width, height)
|
setMin: function (width, height)
|
||||||
{
|
{
|
||||||
if (width === undefined) { width = 0; }
|
if (width === undefined) { width = 0; }
|
||||||
if (height === undefined) { height = width; }
|
if (height === undefined) { height = width; }
|
||||||
|
|
||||||
if (this.lock)
|
this._minWidth = width;
|
||||||
|
this._minHeight = height;
|
||||||
|
|
||||||
|
return this.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the maximum width and height values this Size component will allow.
|
||||||
|
*
|
||||||
|
* If enabled, the properties will be clamped to the min-max range, including when locked to their aspect ratios.
|
||||||
|
*
|
||||||
|
* Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range.
|
||||||
|
*
|
||||||
|
* @method Phaser.Structs.Size#setMax
|
||||||
|
* @since 3.16.0
|
||||||
|
*
|
||||||
|
* @param {number} [width=Number.MAX_VALUE] - The maximum allowed width of the Size component.
|
||||||
|
* @param {number} [height=width] - The maximum allowed height of the Size component. If not given, it will use the `width`.
|
||||||
|
*
|
||||||
|
* @return {this} This Size instance.
|
||||||
|
*/
|
||||||
|
setMax: function (width, height)
|
||||||
|
{
|
||||||
|
if (width === undefined) { width = Number.MAX_VALUE; }
|
||||||
|
if (height === undefined) { height = width; }
|
||||||
|
|
||||||
|
this._maxWidth = width;
|
||||||
|
this._maxHeight = height;
|
||||||
|
|
||||||
|
return this.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls `setSize` with the current width and height.
|
||||||
|
* This has the effect of applying min-max clamping and axis locking to the current values.
|
||||||
|
*
|
||||||
|
* @method Phaser.Structs.Size#update
|
||||||
|
* @since 3.16.0
|
||||||
|
*
|
||||||
|
* @return {this} This Size instance.
|
||||||
|
*/
|
||||||
|
update: function ()
|
||||||
|
{
|
||||||
|
return this.setSize(this._width, this._height);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the `ratioH` and `ratioV` properties based on the current width and height.
|
||||||
|
*
|
||||||
|
* They are only updated if `lockAspectRatio` is `false`.
|
||||||
|
*
|
||||||
|
* @method Phaser.Structs.Size#updateRatios
|
||||||
|
* @since 3.16.0
|
||||||
|
*
|
||||||
|
* @return {this} This Size instance.
|
||||||
|
*/
|
||||||
|
updateRatios: function ()
|
||||||
|
{
|
||||||
|
if (!this.lockAspectRatio)
|
||||||
{
|
{
|
||||||
this._width = width * this.ratioH;
|
this.ratioH = (this._height === 0) ? 1 : this._width / this._height;
|
||||||
this._height = height * this.ratioV;
|
this.ratioV = (this._width === 0) ? 1 : this._height / this._width;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a new width for this Size component.
|
||||||
|
*
|
||||||
|
* The new width is clamped to the min-max range automatically.
|
||||||
|
*
|
||||||
|
* Additionally, if the aspect ratio is locked, the height will also be adjusted based on the new width.
|
||||||
|
*
|
||||||
|
* @method Phaser.Structs.Size#updateWidth
|
||||||
|
* @since 3.16.0
|
||||||
|
*
|
||||||
|
* @param {number} width - The new width of the Size component.
|
||||||
|
*
|
||||||
|
* @return {this} This Size instance.
|
||||||
|
*/
|
||||||
|
updateWidth: function (width)
|
||||||
|
{
|
||||||
|
width = Clamp(width, this._minWidth, this._maxWidth);
|
||||||
|
|
||||||
|
if (this.lockAspectRatio)
|
||||||
{
|
{
|
||||||
this._width = width;
|
// What's the new height?
|
||||||
this.height = height;
|
var height = width * this.ratioV;
|
||||||
|
|
||||||
|
// height takes priority
|
||||||
|
if (!this.lockWidth)
|
||||||
|
{
|
||||||
|
if (height < this._minHeight)
|
||||||
|
{
|
||||||
|
height = this._minHeight;
|
||||||
|
}
|
||||||
|
else if (height > this._maxHeight)
|
||||||
|
{
|
||||||
|
height = this._maxHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-adjust the width based on the dominant height
|
||||||
|
width = height * this.ratioH;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._width = width;
|
||||||
|
this._height = height;
|
||||||
|
|
||||||
|
return this.updateRatios();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a new height for this Size component.
|
||||||
|
*
|
||||||
|
* The new height is clamped to the min-max range automatically.
|
||||||
|
*
|
||||||
|
* Additionally, if the aspect ratio is locked, the width will also be adjusted based on the new height.
|
||||||
|
*
|
||||||
|
* @method Phaser.Structs.Size#updateHeight
|
||||||
|
* @since 3.16.0
|
||||||
|
*
|
||||||
|
* @param {number} height - The new height of the Size component.
|
||||||
|
*
|
||||||
|
* @return {this} This Size instance.
|
||||||
|
*/
|
||||||
|
updateHeight: function (height)
|
||||||
|
{
|
||||||
|
height = Clamp(height, this._minHeight, this._maxHeight);
|
||||||
|
|
||||||
|
if (this.lockAspectRatio)
|
||||||
|
{
|
||||||
|
// What's the new width?
|
||||||
|
var width = height * this.ratioH;
|
||||||
|
|
||||||
|
// width takes priority
|
||||||
|
if (this.lockWidth)
|
||||||
|
{
|
||||||
|
if (width < this._minWidth)
|
||||||
|
{
|
||||||
|
width = this._minWidth;
|
||||||
|
}
|
||||||
|
else if (width > this._maxWidth)
|
||||||
|
{
|
||||||
|
width = this._maxWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-adjust the height based on the dominant width
|
||||||
|
height = width * this.ratioV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._width = width;
|
||||||
|
this._height = height;
|
||||||
|
|
||||||
|
return this.updateRatios();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the width and height of this Size component, adjusting for the aspect ratio, if locked.
|
||||||
|
*
|
||||||
|
* @method Phaser.Structs.Size#setSize
|
||||||
|
* @since 3.16.0
|
||||||
|
*
|
||||||
|
* @param {number} [width] - The width of the Size component.
|
||||||
|
* @param {number} [height=width] - The height of the Size component. If not given, it will use the `width`.
|
||||||
|
*
|
||||||
|
* @return {this} This Size instance.
|
||||||
|
*/
|
||||||
|
setSize: function (width, height)
|
||||||
|
{
|
||||||
|
if (width === undefined) { width = 0; }
|
||||||
|
if (height === undefined) { height = width; }
|
||||||
|
|
||||||
|
return (this.lockWidth) ? this.updateWidth(width) : this.updateHeight(height);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `width` and `height` are adjusted to fit inside the given dimensions, while keeping the current aspect ratio.
|
||||||
|
*
|
||||||
|
* There may be some space inside the parent area which is not covered if its aspect ratio differs.
|
||||||
|
*
|
||||||
|
* @method Phaser.Structs.Size#fitTo
|
||||||
|
* @since 3.16.0
|
||||||
|
*
|
||||||
|
* @param {number} width - The width of the Size component.
|
||||||
|
* @param {number} height - The height of the Size component.
|
||||||
|
*
|
||||||
|
* @return {this} This Size instance.
|
||||||
|
*/
|
||||||
|
fitTo: function (width, height)
|
||||||
|
{
|
||||||
|
// Get the aspect ratios in case we need to expand or shrink to fit
|
||||||
|
var newRatio = (height === 0) ? 1 : width / height;
|
||||||
|
|
||||||
|
var newWidth = width;
|
||||||
|
var newHeight = height;
|
||||||
|
|
||||||
|
// Get the larger aspect ratio of the two.
|
||||||
|
// If aspect ratio is 1 then no adjustment needed
|
||||||
|
if (this.ratioH > newRatio)
|
||||||
|
{
|
||||||
|
newHeight = width / this.ratioH;
|
||||||
|
}
|
||||||
|
else if (this.ratioH < newRatio)
|
||||||
|
{
|
||||||
|
newWidth = height * this.ratioH;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._width = newWidth;
|
||||||
|
this._height = newHeight;
|
||||||
|
|
||||||
|
this.ratioH = (this._height === 0) ? 1 : this._width / this._height;
|
||||||
|
this.ratioV = (this._width === 0) ? 1 : this._height / this._width;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -154,9 +418,7 @@ var Size = new Class({
|
||||||
*/
|
*/
|
||||||
setWidth: function (value)
|
setWidth: function (value)
|
||||||
{
|
{
|
||||||
this.width = value;
|
return this.updateWidth(value);
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -186,9 +448,7 @@ var Size = new Class({
|
||||||
*/
|
*/
|
||||||
setHeight: function (value)
|
setHeight: function (value)
|
||||||
{
|
{
|
||||||
this.height = value;
|
return this.updateHeight(value);
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -214,11 +474,15 @@ var Size = new Class({
|
||||||
*/
|
*/
|
||||||
toString: function ()
|
toString: function ()
|
||||||
{
|
{
|
||||||
return '[{ Size (width=' + this._width + ' height=' + this._height + ' ratioH=' + this.ratioH + ' ratioV=' + this.ratioV + ' lock=' + this.lock + ') }]';
|
return '[{ Size (width=' + this._width + ' height=' + this._height + ' ratioH=' + this.ratioH + ' ratioV=' + this.ratioV + ' lockAspectRatio=' + this.lockAspectRatio + ') }]';
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width.
|
* The width of this Size component.
|
||||||
|
*
|
||||||
|
* This value is clamped to the range specified by `minWidth` and `maxWidth`, if enabled.
|
||||||
|
*
|
||||||
|
* A width can never be less than zero.
|
||||||
*
|
*
|
||||||
* Changing this value will automatically update the `height` if the aspect ratio lock is enabled.
|
* Changing this value will automatically update the `height` if the aspect ratio lock is enabled.
|
||||||
* You can also use the `setWidth` and `getWidth` methods.
|
* You can also use the `setWidth` and `getWidth` methods.
|
||||||
|
@ -236,23 +500,17 @@ var Size = new Class({
|
||||||
|
|
||||||
set: function (value)
|
set: function (value)
|
||||||
{
|
{
|
||||||
this._width = value;
|
this.updateWidth(value);
|
||||||
|
|
||||||
if (this.lock)
|
|
||||||
{
|
|
||||||
this._height = value * this.ratioV;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.ratioH = (this._height === 0) ? 0 : value / this._height;
|
|
||||||
this.ratioV = (this._width === 0) ? 0 : this._height / value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The height.
|
* The height of this Size component.
|
||||||
|
*
|
||||||
|
* This value is clamped to the range specified by `minHeight` and `maxHeight`, if enabled.
|
||||||
|
*
|
||||||
|
* A height can never be less than zero.
|
||||||
*
|
*
|
||||||
* Changing this value will automatically update the `width` if the aspect ratio lock is enabled.
|
* Changing this value will automatically update the `width` if the aspect ratio lock is enabled.
|
||||||
* You can also use the `setHeight` and `getHeight` methods.
|
* You can also use the `setHeight` and `getHeight` methods.
|
||||||
|
@ -270,17 +528,7 @@ var Size = new Class({
|
||||||
|
|
||||||
set: function (value)
|
set: function (value)
|
||||||
{
|
{
|
||||||
this._height = value;
|
this.updateHeight(value);
|
||||||
|
|
||||||
if (this.lock)
|
|
||||||
{
|
|
||||||
this._width = value * this.ratioH;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.ratioH = (this._height === 0) ? 0 : this._width / value;
|
|
||||||
this.ratioV = (this._width === 0) ? 0 : value / this._width;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue