{"version":3,"file":"SVGResource.mjs","sources":["../../../src/textures/resources/SVGResource.ts"],"sourcesContent":["import { settings } from 'pixijs/settings';\nimport { uid } from 'pixijs/utils';\nimport { BaseImageResource } from './BaseImageResource';\n\nimport type { ISize } from 'pixijs/math';\nimport type { ICanvas } from 'pixijs/settings';\n\nexport interface ISVGResourceOptions\n{\n    source?: string;\n    scale?: number;\n    width?: number;\n    height?: number;\n    autoLoad?: boolean;\n    crossorigin?: boolean | string;\n}\n/**\n * Resource type for SVG elements and graphics.\n * @memberof PIXI\n */\nexport class SVGResource extends BaseImageResource\n{\n    /** Base64 encoded SVG element or URL for SVG file. */\n    public readonly svg: string;\n\n    /** The source scale to apply when rasterizing on load. */\n    public readonly scale: number;\n\n    /** A width override for rasterization on load. */\n    public readonly _overrideWidth: number;\n\n    /** A height override for rasterization on load. */\n    public readonly _overrideHeight: number;\n\n    /** Call when completely loaded. */\n    private _resolve: () => void;\n\n    /** Promise when loading */\n    private _load: Promise<SVGResource>;\n\n    /** Cross origin value to use */\n    private _crossorigin?: boolean | string;\n\n    /**\n     * @param sourceBase64 - Base64 encoded SVG element or URL for SVG file.\n     * @param {object} [options] - Options to use\n     * @param {number} [options.scale=1] - Scale to apply to SVG. Overridden by...\n     * @param {number} [options.width] - Rasterize SVG this wide. Aspect ratio preserved if height not specified.\n     * @param {number} [options.height] - Rasterize SVG this high. Aspect ratio preserved if width not specified.\n     * @param {boolean} [options.autoLoad=true] - Start loading right away.\n     */\n    constructor(sourceBase64: string, options?: ISVGResourceOptions)\n    {\n        options = options || {};\n\n        super(settings.ADAPTER.createCanvas());\n        this._width = 0;\n        this._height = 0;\n\n        this.svg = sourceBase64;\n        this.scale = options.scale || 1;\n        this._overrideWidth = options.width;\n        this._overrideHeight = options.height;\n\n        this._resolve = null;\n        this._crossorigin = options.crossorigin;\n        this._load = null;\n\n        if (options.autoLoad !== false)\n        {\n            this.load();\n        }\n    }\n\n    load(): Promise<SVGResource>\n    {\n        if (this._load)\n        {\n            return this._load;\n        }\n\n        this._load = new Promise((resolve): void =>\n        {\n            // Save this until after load is finished\n            this._resolve = (): void =>\n            {\n                this.resize(this.source.width, this.source.height);\n                resolve(this);\n            };\n\n            // Convert SVG inline string to data-uri\n            if (SVGResource.SVG_XML.test(this.svg.trim()))\n            {\n                if (!btoa)\n                {\n                    throw new Error('Your browser doesn\\'t support base64 conversions.');\n                }\n                (this as any).svg = `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(this.svg)))}`;\n            }\n\n            this._loadSvg();\n        });\n\n        return this._load;\n    }\n\n    /** Loads an SVG image from `imageUrl` or `data URL`. */\n    private _loadSvg(): void\n    {\n        const tempImage = new Image();\n\n        BaseImageResource.crossOrigin(tempImage, this.svg, this._crossorigin);\n        tempImage.src = this.svg;\n\n        tempImage.onerror = (event): void =>\n        {\n            if (!this._resolve)\n            {\n                return;\n            }\n\n            tempImage.onerror = null;\n            this.onError.emit(event);\n        };\n\n        tempImage.onload = (): void =>\n        {\n            if (!this._resolve)\n            {\n                return;\n            }\n\n            const svgWidth = tempImage.width;\n            const svgHeight = tempImage.height;\n\n            if (!svgWidth || !svgHeight)\n            {\n                throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.');\n            }\n\n            // Set render size\n            let width = svgWidth * this.scale;\n            let height = svgHeight * this.scale;\n\n            if (this._overrideWidth || this._overrideHeight)\n            {\n                width = this._overrideWidth || this._overrideHeight / svgHeight * svgWidth;\n                height = this._overrideHeight || this._overrideWidth / svgWidth * svgHeight;\n            }\n            width = Math.round(width);\n            height = Math.round(height);\n\n            // Create a canvas element\n            const canvas = this.source as ICanvas;\n\n            canvas.width = width;\n            canvas.height = height;\n            (canvas as any)._pixiId = `canvas_${uid()}`;\n\n            // Draw the Svg to the canvas\n            canvas\n                .getContext('2d')\n                .drawImage(tempImage, 0, 0, svgWidth, svgHeight, 0, 0, width, height);\n\n            this._resolve();\n            this._resolve = null;\n        };\n    }\n\n    /**\n     * Get size from an svg string using a regular expression.\n     * @param svgString - a serialized svg element\n     * @returns - image extension\n     */\n    static getSize(svgString?: string): ISize\n    {\n        const sizeMatch = SVGResource.SVG_SIZE.exec(svgString);\n        const size: any = {};\n\n        if (sizeMatch)\n        {\n            size[sizeMatch[1]] = Math.round(parseFloat(sizeMatch[3]));\n            size[sizeMatch[5]] = Math.round(parseFloat(sizeMatch[7]));\n        }\n\n        return size;\n    }\n\n    /** Destroys this texture. */\n    dispose(): void\n    {\n        super.dispose();\n        this._resolve = null;\n        this._crossorigin = null;\n    }\n\n    /**\n     * Used to auto-detect the type of resource.\n     * @param {*} source - The source object\n     * @param {string} extension - The extension of source, if set\n     * @returns {boolean} - If the source is a SVG source or data file\n     */\n    static test(source: unknown, extension?: string): boolean\n    {\n        // url file extension is SVG\n        return extension === 'svg'\n            // source is SVG data-uri\n            || (typeof source === 'string' && source.startsWith('data:image/svg+xml'))\n            // source is SVG inline\n            || (typeof source === 'string' && SVGResource.SVG_XML.test(source));\n    }\n\n    /**\n     * Regular expression for SVG XML document.\n     * @example &lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;&lt;!-- image/svg --&gt;&lt;svg\n     * @readonly\n     */\n    static SVG_XML = /^(<\\?xml[^?]+\\?>)?\\s*(<!--[^(-->)]*-->)?\\s*\\<svg/m;\n\n    /**\n     * Regular expression for SVG size.\n     * @example &lt;svg width=\"100\" height=\"100\"&gt;&lt;/svg&gt;\n     * @readonly\n     */\n    static SVG_SIZE = /<svg[^>]*(?:\\s(width|height)=('|\")(\\d*(?:\\.\\d+)?)(?:px)?('|\"))[^>]*(?:\\s(width|height)=('|\")(\\d*(?:\\.\\d+)?)(?:px)?('|\"))[^>]*>/i; // eslint-disable-line max-len\n}\n"],"names":[],"mappings":"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"}