mirror of
https://github.com/photonstorm/phaser
synced 2024-11-26 22:52:14 +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}
|
||||
*/
|
||||
|
||||
var Clamp = require('../math/Clamp');
|
||||
var Class = require('../utils/Class');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* The Size component is a simple structure that helps you encapsulate a `width` and `height` and, if required, maintain
|
||||
* the aspect ratios between them.
|
||||
* The Size component allows you to set `width` and `height` properties and define the relationship 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
|
||||
* @memberof Phaser.Structs
|
||||
|
@ -18,17 +22,19 @@ var Class = require('../utils/Class');
|
|||
*
|
||||
* @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 {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({
|
||||
|
||||
initialize:
|
||||
|
||||
function Size (width, height, lockAspectRatio)
|
||||
function Size (width, height, lockAspectRatio, lockWidth)
|
||||
{
|
||||
if (width === undefined) { width = 0; }
|
||||
if (height === undefined) { height = width; }
|
||||
if (lockAspectRatio === undefined) { lockAspectRatio = false; }
|
||||
if (lockWidth === undefined) { lockWidth = true; }
|
||||
|
||||
/**
|
||||
* The width.
|
||||
|
@ -61,7 +67,7 @@ var Size = new Class({
|
|||
* @readonly
|
||||
* @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.
|
||||
|
@ -74,18 +80,70 @@ var Size = new Class({
|
|||
* @readonly
|
||||
* @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}
|
||||
* @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)
|
||||
{
|
||||
this.lock = value;
|
||||
this.lockAspectRatio = value;
|
||||
|
||||
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
|
||||
*
|
||||
* @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 {boolean} [lockAspectRatio=false] - Should the aspect ratio between the `width` and `height` be locked?
|
||||
* @param {number} [width=0] - The minimum allowed width of the Size component.
|
||||
* @param {number} [height=width] - The minimum allowed height of the Size component. If not given, it will use the `width`.
|
||||
*
|
||||
* @return {this} This Size instance.
|
||||
*/
|
||||
set: function (width, height)
|
||||
setMin: function (width, height)
|
||||
{
|
||||
if (width === undefined) { width = 0; }
|
||||
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._height = height * this.ratioV;
|
||||
this.ratioH = (this._height === 0) ? 1 : this._width / this._height;
|
||||
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;
|
||||
this.height = height;
|
||||
// What's the new 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;
|
||||
},
|
||||
|
||||
|
@ -154,9 +418,7 @@ var Size = new Class({
|
|||
*/
|
||||
setWidth: function (value)
|
||||
{
|
||||
this.width = value;
|
||||
|
||||
return this;
|
||||
return this.updateWidth(value);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -186,9 +448,7 @@ var Size = new Class({
|
|||
*/
|
||||
setHeight: function (value)
|
||||
{
|
||||
this.height = value;
|
||||
|
||||
return this;
|
||||
return this.updateHeight(value);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -214,11 +474,15 @@ var Size = new Class({
|
|||
*/
|
||||
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.
|
||||
* You can also use the `setWidth` and `getWidth` methods.
|
||||
|
@ -236,23 +500,17 @@ var Size = new Class({
|
|||
|
||||
set: function (value)
|
||||
{
|
||||
this._width = 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;
|
||||
}
|
||||
this.updateWidth(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.
|
||||
* You can also use the `setHeight` and `getHeight` methods.
|
||||
|
@ -270,17 +528,7 @@ var Size = new Class({
|
|||
|
||||
set: function (value)
|
||||
{
|
||||
this._height = 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;
|
||||
}
|
||||
this.updateHeight(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue