diff --git a/packages/core/src/textures/resources/SVGResource.js b/packages/core/src/textures/resources/SVGResource.js index a87a355..0e090e8 100644 --- a/packages/core/src/textures/resources/SVGResource.js +++ b/packages/core/src/textures/resources/SVGResource.js @@ -8,7 +8,9 @@ * @memberof PIXI.resources * @param {string} source - Base64 encoded SVG element or URL for SVG file. * @param {object} [options] - Options to use - * @param {number} [options.scale=1] Scale to apply to SVG. + * @param {number} [options.scale=1] Scale to apply to SVG. Overridden by... + * @param {number} [options.width] Rasterize SVG this wide. Aspect ratio preserved if height not specified. + * @param {number} [options.height] Rasterize SVG this high. Aspect ratio preserved if width not specified. * @param {boolean} [options.autoLoad=true] Start loading right away. */ export default class SVGResource extends BaseImageResource @@ -27,13 +29,27 @@ this.svg = source; /** - * The source scale to apply to render + * The source scale to apply when rasterizing on load * @readonly * @member {number} */ this.scale = options.scale || 1; /** + * A width override for rasterization on load + * @readonly + * @member {number} + */ + this._overrideWidth = options.width; + + /** + * A height override for rasterization on load + * @readonly + * @member {number} + */ + this._overrideHeight = options.height; + + /** * Call when completely loaded * @private * @member {function} @@ -115,9 +131,17 @@ throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); } - // Scale realWidth and realHeight - const width = Math.round(svgWidth * this.scale); - const height = Math.round(svgHeight * this.scale); + // Set render size + let width = svgWidth * this.scale; + let height = svgHeight * this.scale; + + if (this._overrideWidth || this._overrideHeight) + { + width = this._overrideWidth || this._overrideHeight / svgHeight * svgWidth; + height = this._overrideHeight || this._overrideWidth / svgWidth * svgHeight; + } + width = Math.round(width); + height = Math.round(height); // Create a canvas element const canvas = this.source; diff --git a/packages/core/src/textures/resources/SVGResource.js b/packages/core/src/textures/resources/SVGResource.js index a87a355..0e090e8 100644 --- a/packages/core/src/textures/resources/SVGResource.js +++ b/packages/core/src/textures/resources/SVGResource.js @@ -8,7 +8,9 @@ * @memberof PIXI.resources * @param {string} source - Base64 encoded SVG element or URL for SVG file. * @param {object} [options] - Options to use - * @param {number} [options.scale=1] Scale to apply to SVG. + * @param {number} [options.scale=1] Scale to apply to SVG. Overridden by... + * @param {number} [options.width] Rasterize SVG this wide. Aspect ratio preserved if height not specified. + * @param {number} [options.height] Rasterize SVG this high. Aspect ratio preserved if width not specified. * @param {boolean} [options.autoLoad=true] Start loading right away. */ export default class SVGResource extends BaseImageResource @@ -27,13 +29,27 @@ this.svg = source; /** - * The source scale to apply to render + * The source scale to apply when rasterizing on load * @readonly * @member {number} */ this.scale = options.scale || 1; /** + * A width override for rasterization on load + * @readonly + * @member {number} + */ + this._overrideWidth = options.width; + + /** + * A height override for rasterization on load + * @readonly + * @member {number} + */ + this._overrideHeight = options.height; + + /** * Call when completely loaded * @private * @member {function} @@ -115,9 +131,17 @@ throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); } - // Scale realWidth and realHeight - const width = Math.round(svgWidth * this.scale); - const height = Math.round(svgHeight * this.scale); + // Set render size + let width = svgWidth * this.scale; + let height = svgHeight * this.scale; + + if (this._overrideWidth || this._overrideHeight) + { + width = this._overrideWidth || this._overrideHeight / svgHeight * svgWidth; + height = this._overrideHeight || this._overrideWidth / svgWidth * svgHeight; + } + width = Math.round(width); + height = Math.round(height); // Create a canvas element const canvas = this.source; diff --git a/packages/core/src/textures/resources/autoDetectResource.js b/packages/core/src/textures/resources/autoDetectResource.js index bb8e7c7..157f2e2 100644 --- a/packages/core/src/textures/resources/autoDetectResource.js +++ b/packages/core/src/textures/resources/autoDetectResource.js @@ -46,10 +46,10 @@ * or any other resource that can be auto-detected. If not resource is * detected, it's assumed to be an ImageResource. * @param {object} [options] - Pass-through options to use for Resource - * @param {number} [options.width] - BufferResource's width - * @param {number} [options.height] - BufferResource's height + * @param {number} [options.width] - Width of BufferResource or SVG rasterization + * @param {number} [options.height] - Height of BufferResource or SVG rasterization * @param {boolean} [options.autoLoad=true] - Image, SVG and Video flag to start loading - * @param {number} [options.scale=1] - SVG source scale + * @param {number} [options.scale=1] - SVG source scale. Overridden by width, height * @param {boolean} [options.createBitmap=PIXI.settings.CREATE_IMAGE_BITMAP] - Image option to create Bitmap object * @param {boolean} [options.crossorigin=true] - Image and Video option to set crossOrigin * @param {boolean} [options.autoPlay=true] - Video option to start playing video immediately diff --git a/packages/core/src/textures/resources/SVGResource.js b/packages/core/src/textures/resources/SVGResource.js index a87a355..0e090e8 100644 --- a/packages/core/src/textures/resources/SVGResource.js +++ b/packages/core/src/textures/resources/SVGResource.js @@ -8,7 +8,9 @@ * @memberof PIXI.resources * @param {string} source - Base64 encoded SVG element or URL for SVG file. * @param {object} [options] - Options to use - * @param {number} [options.scale=1] Scale to apply to SVG. + * @param {number} [options.scale=1] Scale to apply to SVG. Overridden by... + * @param {number} [options.width] Rasterize SVG this wide. Aspect ratio preserved if height not specified. + * @param {number} [options.height] Rasterize SVG this high. Aspect ratio preserved if width not specified. * @param {boolean} [options.autoLoad=true] Start loading right away. */ export default class SVGResource extends BaseImageResource @@ -27,13 +29,27 @@ this.svg = source; /** - * The source scale to apply to render + * The source scale to apply when rasterizing on load * @readonly * @member {number} */ this.scale = options.scale || 1; /** + * A width override for rasterization on load + * @readonly + * @member {number} + */ + this._overrideWidth = options.width; + + /** + * A height override for rasterization on load + * @readonly + * @member {number} + */ + this._overrideHeight = options.height; + + /** * Call when completely loaded * @private * @member {function} @@ -115,9 +131,17 @@ throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); } - // Scale realWidth and realHeight - const width = Math.round(svgWidth * this.scale); - const height = Math.round(svgHeight * this.scale); + // Set render size + let width = svgWidth * this.scale; + let height = svgHeight * this.scale; + + if (this._overrideWidth || this._overrideHeight) + { + width = this._overrideWidth || this._overrideHeight / svgHeight * svgWidth; + height = this._overrideHeight || this._overrideWidth / svgWidth * svgHeight; + } + width = Math.round(width); + height = Math.round(height); // Create a canvas element const canvas = this.source; diff --git a/packages/core/src/textures/resources/autoDetectResource.js b/packages/core/src/textures/resources/autoDetectResource.js index bb8e7c7..157f2e2 100644 --- a/packages/core/src/textures/resources/autoDetectResource.js +++ b/packages/core/src/textures/resources/autoDetectResource.js @@ -46,10 +46,10 @@ * or any other resource that can be auto-detected. If not resource is * detected, it's assumed to be an ImageResource. * @param {object} [options] - Pass-through options to use for Resource - * @param {number} [options.width] - BufferResource's width - * @param {number} [options.height] - BufferResource's height + * @param {number} [options.width] - Width of BufferResource or SVG rasterization + * @param {number} [options.height] - Height of BufferResource or SVG rasterization * @param {boolean} [options.autoLoad=true] - Image, SVG and Video flag to start loading - * @param {number} [options.scale=1] - SVG source scale + * @param {number} [options.scale=1] - SVG source scale. Overridden by width, height * @param {boolean} [options.createBitmap=PIXI.settings.CREATE_IMAGE_BITMAP] - Image option to create Bitmap object * @param {boolean} [options.crossorigin=true] - Image and Video option to set crossOrigin * @param {boolean} [options.autoPlay=true] - Video option to start playing video immediately diff --git a/packages/core/test/SVGResource.js b/packages/core/test/SVGResource.js index 0f390c7..47fa97a 100644 --- a/packages/core/test/SVGResource.js +++ b/packages/core/test/SVGResource.js @@ -43,6 +43,64 @@ }); }); + it('should create resource from SVG URL with {scale: 2.123}', function (done) + { + const resource = new SVGResource( + path.join(this.resources, 'heart.svg'), + { + autoLoad: false, + scale: 2.123, + } + ); + + resource.load().then(function () + { + expect(resource.width).to.equal(212); + expect(resource.height).to.equal(212); + + done(); + }); + }); + + it('should create resource from SVG URL with {width: 10}', function (done) + { + const resource = new SVGResource( + path.join(this.resources, 'heart.svg'), + { + autoLoad: false, + width: 10, + } + ); + + resource.load().then(function () + { + expect(resource.width).to.equal(10); + expect(resource.height).to.equal(10); + + done(); + }); + }); + + it('should create resource from SVG URL with {width: 10, height: 10}', function (done) + { + const resource = new SVGResource( + path.join(this.resources, 'heart.svg'), + { + autoLoad: false, + width: 10, + height: 10, + } + ); + + resource.load().then(function () + { + expect(resource.width).to.equal(10); + expect(resource.height).to.equal(10); + + done(); + }); + }); + it('should create resource from inline SVG', function (done) { const url = path.join(this.resources, 'heart.svg');