You can now resize SVG files during load, before they are rendered to textures.

Also added scale support and fixed some viewBox settings (#3941)
This commit is contained in:
Richard Davey 2018-08-22 15:43:09 +01:00
parent e99dfef136
commit dc868f8368
2 changed files with 106 additions and 13 deletions

View file

@ -144,6 +144,7 @@ Most of the updates were about documentation and module namespacing, however tho
* `TransformMatrix.setToContext` is a new method that will set the values from the Matrix to the given Canvas Rendering Context using setTransform rather than transform.
* `SetTransform` is a new Canvas Renderer function that consolidates the process of preparing a Game Object for rendering, without actually rendering it. This is used internally by the Graphics and Bitmap Text classes.
* The Texture Manager has a new method called `renameTexture` which will let you rename a texture, changing the key to the new one given. All existing Game Objects will still maintain their reference, even after a rename.
* When loading an SVG file you can now change the size of the SVG during the load process, before it is rendered to a texture. This is really helpful if you wish to increase SVGs that have small viewBoxes set, or want to try and reduce memory consumption from SVGs with extra large dimensions. You can either pass in a fixed width and height: `this.load.svg('morty', 'file.svg', { width: 300, height: 600 })` or you can provide a scale factor instead: `this.load.svg('morty', 'file.svg', { scale: 4 })` (thanks @ysraelJMM)
### Updates

View file

@ -12,12 +12,21 @@ var GetFastValue = require('../../utils/object/GetFastValue');
var IsPlainObject = require('../../utils/object/IsPlainObject');
/**
* @typedef {object} Phaser.Loader.FileTypes.SVGSizeConfig
*
* @property {integer} [width] - An optional width. The SVG will be resized to this size before being rendered to a texture.
* @property {integer} [height] - An optional height. The SVG will be resized to this size before being rendered to a texture.
* @property {number} [scale] - An optional scale. If given it overrides the width / height properties. The SVG is scaled by the scale factor before being rendered to a texture.
*/
/**
* @typedef {object} Phaser.Loader.FileTypes.SVGFileConfig
*
* @property {string} key - The key of the file. Must be unique within both the Loader and the Texture Manager.
* @property {string} [url] - The absolute or relative URL to load the file from.
* @property {string} [extension='svg'] - The default file extension to use if no url is provided.
* @property {XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file.
* @property {Phaser.Loader.FileTypes.SVGSizeConfig} [svgConfig] - The svg size configuration object.
*/
/**
@ -37,6 +46,7 @@ var IsPlainObject = require('../../utils/object/IsPlainObject');
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
* @param {(string|Phaser.Loader.FileTypes.SVGFileConfig)} key - The key to use for this file, or a file configuration object.
* @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.svg`, i.e. if `key` was "alien" then the URL will be "alien.svg".
* @param {Phaser.Loader.FileTypes.SVGSizeConfig} [svgConfig] - The svg size configuration object.
* @param {XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file.
*/
var SVGFile = new Class({
@ -55,7 +65,7 @@ var SVGFile = new Class({
key = GetFastValue(config, 'key');
url = GetFastValue(config, 'url');
svgConfig = GetFastValue(config, 'svgConfig');
svgConfig = GetFastValue(config, 'svgConfig', {});
xhrSettings = GetFastValue(config, 'xhrSettings');
extension = GetFastValue(config, 'extension', extension);
}
@ -67,8 +77,12 @@ var SVGFile = new Class({
responseType: 'text',
key: key,
url: url,
svgConfig: svgConfig,
xhrSettings: xhrSettings
xhrSettings: xhrSettings,
config: {
width: GetFastValue(svgConfig, 'width'),
height: GetFastValue(svgConfig, 'height'),
scale: GetFastValue(svgConfig, 'scale')
}
};
File.call(this, loader, fileConfig);
@ -87,23 +101,51 @@ var SVGFile = new Class({
var text = this.xhrLoader.responseText;
var svg = [ text ];
var width = this.svgConfig.width;
var height = this.svgConfig.height;
var width = this.config.width;
var height = this.config.height;
var scale = this.config.scale;
if (width && height)
resize: if (width && height || scale)
{
var xml = null;
var parser = new DOMParser();
xml = parser.parseFromString(text, 'text/xml');
var svgXML = xml.getElementsByTagName('svg')[0];
if (svgXML.getAttribute('viewBox'))
var hasViewBox = svgXML.hasAttribute('viewBox');
var svgWidth = parseFloat(svgXML.getAttribute('width'));
var svgHeight = parseFloat(svgXML.getAttribute('height'));
if (!hasViewBox && svgWidth && svgHeight)
{
svgXML.setAttribute('viewBox', '0 0 ' + svgXML.getAttribute('width') + ' ' + svgXML.getAttribute('height'));
// If there's no viewBox attribute, set one
svgXML.setAttribute('viewBox', '0 0 ' + svgWidth + ' ' + svgHeight);
}
else if (hasViewBox && !svgWidth && !svgHeight)
{
// Get the w/h from the viewbox
var viewBox = svgXML.getAttribute('viewBox').split(/\s+|,/);
svgWidth = viewBox[2];
svgHeight = viewBox[3];
}
svgXML.setAttribute('width', width);
svgXML.setAttribute('height', height);
if (scale)
{
if (svgWidth && svgHeight)
{
width = svgWidth * scale;
height = svgHeight * scale;
}
else
{
break resize;
}
}
svgXML.setAttribute('width', width.toString() + 'px');
svgXML.setAttribute('height', height.toString() + 'px');
svg = [ (new XMLSerializer()).serializeToString(svgXML) ];
}
@ -171,7 +213,8 @@ var SVGFile = new Class({
});
/**
* Adds an SVG File, or array of SVG Files, to the current load queue.
* Adds an SVG File, or array of SVG Files, to the current load queue. When the files are loaded they
* will be rendered to bitmap textures and stored in the Texture Manager.
*
* You can call this method from within your Scene's `preload`, along with any other files you wish to load:
*
@ -223,6 +266,54 @@ var SVGFile = new Class({
* If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien"
* and no URL is given then the Loader will set the URL to be "alien.html". It will always add `.html` as the extension, although
* this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
*
* You can optionally pass an SVG Resize Configuration object when you load an SVG file. By default the SVG will be rendered to a texture
* at the same size defined in the SVG file attributes. However, this isn't always desirable. You may wish to resize the SVG (either down
* or up) to improve texture clarity, or reduce texture memory consumption. You can either specify an exact width and height to resize
* the SVG to:
*
* ```javascript
* function preload ()
* {
* this.load.svg('morty', 'images/Morty.svg', { width: 300, height: 600 });
* }
* ```
*
* Or when using a configuration object:
*
* ```javascript
* this.load.svg({
* key: 'morty',
* url: 'images/Morty.svg',
* svgConfig: {
* width: 300,
* height: 600
* }
* });
* ```
*
* Alternatively, you can just provide a scale factor instead:
*
* ```javascript
* function preload ()
* {
* this.load.svg('morty', 'images/Morty.svg', { scale: 2.5 });
* }
* ```
*
* Or when using a configuration object:
*
* ```javascript
* this.load.svg({
* key: 'morty',
* url: 'images/Morty.svg',
* svgConfig: {
* scale: 2.5
* }
* });
* ```
*
* If scale, width and height values are all given, the scale has priority and the width and height values are ignored.
*
* Note: The ability to load this type of file will only be available if the SVG File type has been built into Phaser.
* It is available in the default build but can be excluded from custom builds.
@ -233,11 +324,12 @@ var SVGFile = new Class({
*
* @param {(string|Phaser.Loader.FileTypes.SVGFileConfig|Phaser.Loader.FileTypes.SVGFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
* @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.svg`, i.e. if `key` was "alien" then the URL will be "alien.svg".
* @param {Phaser.Loader.FileTypes.SVGSizeConfig} [svgConfig] - The svg size configuration object.
* @param {XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings.
*
* @return {Phaser.Loader.LoaderPlugin} The Loader instance.
*/
FileTypesManager.register('svg', function (key, url, xhrSettings)
FileTypesManager.register('svg', function (key, url, svgConfig, xhrSettings)
{
if (Array.isArray(key))
{
@ -249,7 +341,7 @@ FileTypesManager.register('svg', function (key, url, xhrSettings)
}
else
{
this.addFile(new SVGFile(this, key, url, xhrSettings));
this.addFile(new SVGFile(this, key, url, svgConfig, xhrSettings));
}
return this;