{"version":3,"file":"CanvasContextSystem.mjs","sources":["../src/CanvasContextSystem.ts"],"sourcesContent":["import { BaseTexture, BLEND_MODES, Color, extensions, ExtensionType, Matrix, SCALE_MODES } from '@pixi/core';\nimport { mapCanvasBlendModesToPixi } from './utils/mapCanvasBlendModesToPixi';\n\nimport type { ColorSource, ExtensionMetadata, ICanvasRenderingContext2D, ISystem } from '@pixi/core';\nimport type { CanvasRenderer } from './CanvasRenderer';\n\nconst tempMatrix = new Matrix();\n\n/**\n * Rendering context for all browsers. This includes platform-specific\n * properties that are not included in the spec for CanvasRenderingContext2D\n */\nexport interface CrossPlatformCanvasRenderingContext2D extends ICanvasRenderingContext2D\n{\n    webkitImageSmoothingEnabled: boolean;\n    mozImageSmoothingEnabled: boolean;\n    oImageSmoothingEnabled: boolean;\n    msImageSmoothingEnabled: boolean;\n}\n\n/*\n * Different browsers support different smoothing property names\n * this is the list of all platform props.\n */\nexport type SmoothingEnabledProperties =\n    'imageSmoothingEnabled' |\n    'webkitImageSmoothingEnabled' |\n    'mozImageSmoothingEnabled' |\n    'oImageSmoothingEnabled' |\n    'msImageSmoothingEnabled';\n\n/**\n * System that manages the canvas `2d` contexts\n * @memberof PIXI\n */\nexport class CanvasContextSystem implements ISystem\n{\n    /** @ignore */\n    static extension: ExtensionMetadata = {\n        type:  ExtensionType.CanvasRendererSystem,\n        name: 'canvasContext',\n    };\n\n    /** A reference to the current renderer */\n    private renderer: CanvasRenderer;\n\n    /** The root canvas 2d context that everything is drawn with. */\n    public rootContext: CrossPlatformCanvasRenderingContext2D;\n    /** The currently active canvas 2d context (could change with renderTextures) */\n    public activeContext: CrossPlatformCanvasRenderingContext2D;\n    public activeResolution = 1;\n\n    /** The canvas property used to set the canvas smoothing property. */\n    public smoothProperty: SmoothingEnabledProperties = 'imageSmoothingEnabled';\n    /** Tracks the blend modes useful for this renderer. */\n    public readonly blendModes: string[] = mapCanvasBlendModesToPixi();\n\n    _activeBlendMode: BLEND_MODES = null;\n    /** Projection transform, passed in render() stored here */\n    _projTransform: Matrix = null;\n\n    /** @private */\n    _outerBlend = false;\n\n    /** @param renderer - A reference to the current renderer */\n    constructor(renderer: CanvasRenderer)\n    {\n        this.renderer = renderer;\n    }\n\n    /** initiates the system */\n    init(): void\n    {\n        const alpha = this.renderer.background.alpha < 1;\n\n        this.rootContext = this.renderer.view.getContext('2d', { alpha }) as\n        CrossPlatformCanvasRenderingContext2D;\n\n        this.activeContext = this.rootContext;\n\n        if (!this.rootContext.imageSmoothingEnabled)\n        {\n            const rc = this.rootContext;\n\n            if (rc.webkitImageSmoothingEnabled)\n            {\n                this.smoothProperty = 'webkitImageSmoothingEnabled';\n            }\n            else if (rc.mozImageSmoothingEnabled)\n            {\n                this.smoothProperty = 'mozImageSmoothingEnabled';\n            }\n            else if (rc.oImageSmoothingEnabled)\n            {\n                this.smoothProperty = 'oImageSmoothingEnabled';\n            }\n            else if (rc.msImageSmoothingEnabled)\n            {\n                this.smoothProperty = 'msImageSmoothingEnabled';\n            }\n        }\n    }\n\n    /**\n     * Sets matrix of context.\n     * called only from render() methods\n     * takes care about resolution\n     * @param transform - world matrix of current element\n     * @param roundPixels - whether to round (tx,ty) coords\n     * @param localResolution - If specified, used instead of `renderer.resolution` for local scaling\n     */\n    setContextTransform(transform: Matrix, roundPixels?: boolean, localResolution?: number): void\n    {\n        let mat = transform;\n        const proj = this._projTransform;\n        const contextResolution = this.activeResolution;\n\n        localResolution = localResolution || contextResolution;\n\n        if (proj)\n        {\n            mat = tempMatrix;\n            mat.copyFrom(transform);\n            mat.prepend(proj);\n        }\n\n        if (roundPixels)\n        {\n            this.activeContext.setTransform(\n                mat.a * localResolution,\n                mat.b * localResolution,\n                mat.c * localResolution,\n                mat.d * localResolution,\n                (mat.tx * contextResolution) | 0,\n                (mat.ty * contextResolution) | 0\n            );\n        }\n        else\n        {\n            this.activeContext.setTransform(\n                mat.a * localResolution,\n                mat.b * localResolution,\n                mat.c * localResolution,\n                mat.d * localResolution,\n                mat.tx * contextResolution,\n                mat.ty * contextResolution\n            );\n        }\n    }\n\n    /**\n     * Clear the canvas of renderer.\n     * @param {string} [clearColor] - Clear the canvas with this color, except the canvas is transparent.\n     * @param {number} [alpha] - Alpha to apply to the background fill color.\n     */\n    public clear(clearColor?: ColorSource, alpha?: number): void\n    {\n        const { activeContext: context, renderer } = this;\n        const fillColor = clearColor\n            ? Color.shared.setValue(clearColor)\n            : this.renderer.background.backgroundColor;\n\n        context.clearRect(0, 0, renderer.width, renderer.height);\n\n        if (clearColor)\n        {\n            context.globalAlpha = alpha ?? this.renderer.background.alpha;\n            context.fillStyle = fillColor.toHex();\n            context.fillRect(0, 0, renderer.width, renderer.height);\n            context.globalAlpha = 1;\n        }\n    }\n\n    /**\n     * Sets the blend mode of the renderer.\n     * @param {number} blendMode - See {@link PIXI.BLEND_MODES} for valid values.\n     * @param {boolean} [readyForOuterBlend=false] - Some blendModes are dangerous, they affect outer space of sprite.\n     * Pass `true` only if you are ready to use them.\n     */\n    setBlendMode(blendMode: BLEND_MODES, readyForOuterBlend?: boolean): void\n    {\n        const outerBlend = blendMode === BLEND_MODES.SRC_IN\n                 || blendMode === BLEND_MODES.SRC_OUT\n                 || blendMode === BLEND_MODES.DST_IN\n                 || blendMode === BLEND_MODES.DST_ATOP;\n\n        if (!readyForOuterBlend && outerBlend)\n        {\n            blendMode = BLEND_MODES.NORMAL;\n        }\n\n        if (this._activeBlendMode === blendMode)\n        {\n            return;\n        }\n\n        this._activeBlendMode = blendMode;\n        this._outerBlend = outerBlend;\n        this.activeContext.globalCompositeOperation = this.blendModes[blendMode] as GlobalCompositeOperation;\n    }\n\n    resize(): void\n    {\n        // reset the scale mode.. oddly this seems to be reset when the canvas is resized.\n        // surely a browser bug?? Let PixiJS fix that for you..\n        if (this.smoothProperty)\n        {\n            this.rootContext[this.smoothProperty] = (BaseTexture.defaultOptions.scaleMode === SCALE_MODES.LINEAR);\n        }\n    }\n\n    /** Checks if blend mode has changed. */\n    invalidateBlendMode(): void\n    {\n        this._activeBlendMode = this.blendModes.indexOf(this.activeContext.globalCompositeOperation);\n    }\n\n    public destroy(): void\n    {\n        this.renderer = null;\n        this.rootContext = null;\n\n        this.activeContext = null;\n        this.smoothProperty = null;\n    }\n}\n\nextensions.add(CanvasContextSystem);\n"],"names":[],"mappings":";;AAMA,MAAM,aAAa,IAAI;AA6BhB,MAAM,oBACb;AAAA;AAAA,EA6BI,YAAY,UACZ;AAhBA,SAAO,mBAAmB,GAG1B,KAAO,iBAA6C,yBAEpD,KAAgB,aAAuB,6BAEP,KAAA,mBAAA,MAEP,KAAA,iBAAA,MAGX,KAAA,cAAA,IAKV,KAAK,WAAW;AAAA,EACpB;AAAA;AAAA,EAGA,OACA;AACI,UAAM,QAAQ,KAAK,SAAS,WAAW,QAAQ;AAO/C,QALA,KAAK,cAAc,KAAK,SAAS,KAAK,WAAW,MAAM,EAAE,MAAO,CAAA,GAGhE,KAAK,gBAAgB,KAAK,aAEtB,CAAC,KAAK,YAAY,uBACtB;AACI,YAAM,KAAK,KAAK;AAEZ,SAAG,8BAEH,KAAK,iBAAiB,gCAEjB,GAAG,2BAER,KAAK,iBAAiB,6BAEjB,GAAG,yBAER,KAAK,iBAAiB,2BAEjB,GAAG,4BAER,KAAK,iBAAiB;AAAA,IAE9B;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,oBAAoB,WAAmB,aAAuB,iBAC9D;AACI,QAAI,MAAM;AACV,UAAM,OAAO,KAAK,gBACZ,oBAAoB,KAAK;AAE/B,sBAAkB,mBAAmB,mBAEjC,SAEA,MAAM,YACN,IAAI,SAAS,SAAS,GACtB,IAAI,QAAQ,IAAI,IAGhB,cAEA,KAAK,cAAc;AAAA,MACf,IAAI,IAAI;AAAA,MACR,IAAI,IAAI;AAAA,MACR,IAAI,IAAI;AAAA,MACR,IAAI,IAAI;AAAA,MACP,IAAI,KAAK,oBAAqB;AAAA,MAC9B,IAAI,KAAK,oBAAqB;AAAA,IAAA,IAKnC,KAAK,cAAc;AAAA,MACf,IAAI,IAAI;AAAA,MACR,IAAI,IAAI;AAAA,MACR,IAAI,IAAI;AAAA,MACR,IAAI,IAAI;AAAA,MACR,IAAI,KAAK;AAAA,MACT,IAAI,KAAK;AAAA,IAAA;AAAA,EAGrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,MAAM,YAA0B,OACvC;AACI,UAAM,EAAE,eAAe,SAAS,SAAA,IAAa,MACvC,YAAY,aACZ,MAAM,OAAO,SAAS,UAAU,IAChC,KAAK,SAAS,WAAW;AAE/B,YAAQ,UAAU,GAAG,GAAG,SAAS,OAAO,SAAS,MAAM,GAEnD,eAEA,QAAQ,cAAc,SAAS,KAAK,SAAS,WAAW,OACxD,QAAQ,YAAY,UAAU,MAAM,GACpC,QAAQ,SAAS,GAAG,GAAG,SAAS,OAAO,SAAS,MAAM,GACtD,QAAQ,cAAc;AAAA,EAE9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,WAAwB,oBACrC;AACU,UAAA,aAAa,cAAc,YAAY,UACjC,cAAc,YAAY,WAC1B,cAAc,YAAY,UAC1B,cAAc,YAAY;AAElC,KAAC,sBAAsB,eAEvB,YAAY,YAAY,SAGxB,KAAK,qBAAqB,cAK9B,KAAK,mBAAmB,WACxB,KAAK,cAAc,YACnB,KAAK,cAAc,2BAA2B,KAAK,WAAW,SAAS;AAAA,EAC3E;AAAA,EAEA,SACA;AAGQ,SAAK,mBAEL,KAAK,YAAY,KAAK,cAAc,IAAK,YAAY,eAAe,cAAc,YAAY;AAAA,EAEtG;AAAA;AAAA,EAGA,sBACA;AACI,SAAK,mBAAmB,KAAK,WAAW,QAAQ,KAAK,cAAc,wBAAwB;AAAA,EAC/F;AAAA,EAEO,UACP;AACS,SAAA,WAAW,MAChB,KAAK,cAAc,MAEnB,KAAK,gBAAgB,MACrB,KAAK,iBAAiB;AAAA,EAC1B;AACJ;AA9La,oBAGF,YAA+B;AAAA,EAClC,MAAO,cAAc;AAAA,EACrB,MAAM;AACV;AA0LJ,WAAW,IAAI,mBAAmB;"}