{"version":3,"file":"OutlineFilter.mjs","sources":["../../src/outline/OutlineFilter.ts"],"sourcesContent":["import { Color, deprecation, Filter, GlProgram, GpuProgram } from 'pixi.js';\nimport { vertex, wgslVertex } from '../defaults';\nimport fragment from './outline.frag';\nimport source from './outline.wgsl';\n\nimport type { ColorSource, FilterSystem, RenderSurface, Texture } from 'pixi.js';\n\n/** Options for the OutlineFilter constructor. */\nexport interface OutlineFilterOptions\n{\n    /**\n     * The thickness of the outline\n     * @default 1\n     */\n    thickness?: number;\n    /**\n     * The color of the outline\n     * @example [1.0, 1.0, 1.0] = 0xffffff\n     * @default 0x000000\n     */\n    color?: ColorSource;\n    /**\n     * The alpha of the outline\n     * @default 1\n     */\n    alpha?: number;\n    /**\n     * The quality of the outline from `0` to `1`.\n     * Using a higher quality setting will result in more accuracy but slower performance\n     * @default 0.1\n     */\n    quality?: number;\n    /**\n     * Whether to only render outline, not the contents.\n     * @default false\n     */\n    knockout?: boolean;\n}\n\n/**\n * OutlineFilter, originally by mishaa\n * http://www.html5gamedevs.com/topic/10640-outline-a-sprite-change-certain-colors/?p=69966\n * http://codepen.io/mishaa/pen/emGNRB<br>\n * ![original](../screenshots/original.png)![filter](../screenshots/outline.png)\n *\n * @class\n * @extends Filter *\n * @example\n *  someSprite.filters = [new OutlineFilter(2, 0x99ff99)];\n */\nexport class OutlineFilter extends Filter\n{\n    /** Default values for options. */\n    public static readonly DEFAULT_OPTIONS: OutlineFilterOptions = {\n        thickness: 1,\n        color: 0x000000,\n        alpha: 1,\n        quality: 0.1,\n        knockout: false,\n    };\n\n    /** The minimum number of samples for rendering outline. */\n    public static MIN_SAMPLES = 1;\n\n    /** The maximum number of samples for rendering outline. */\n    public static MAX_SAMPLES = 100;\n\n    public uniforms: {\n        uThickness: Float32Array,\n        uColor: Float32Array,\n        uAlpha: number;\n        uAngleStep: number,\n        uKnockout: number,\n    };\n\n    private _thickness!: number;\n    private _quality!: number;\n    private _color!: Color;\n\n    /**\n     * @param options - Options for the OutlineFilter constructor.\n     */\n    constructor(options?: OutlineFilterOptions);\n    /**\n     * @deprecated since 6.0.0\n     *\n     * @param {number} [thickness=1] - The tickness of the outline. Make it 2 times more for resolution 2\n     * @param {number} [color=0x000000] - The color of the outline.\n     * @param {number} [quality=0.1] - The quality of the outline from `0` to `1`, using a higher quality\n     *        setting will result in slower performance and more accuracy.\n     * @param {number} [alpha=1.0] - The alpha of the outline.\n     * @param {boolean} [knockout=false] - Only render outline, not the contents.\n     */\n    constructor(thickness?: number, color?: number, quality?: number, alpha?: number, knockout?: boolean);\n    /** @ignore */\n    constructor(...args: [OutlineFilterOptions?] | [number?, number?, number?, number?, boolean?])\n    {\n        let options = args[0] ?? {};\n\n        if (typeof options === 'number')\n        {\n            // eslint-disable-next-line max-len\n            deprecation('6.0.0', 'OutlineFilter constructor params are now options object. See params: { thickness, color, quality, alpha, knockout }');\n\n            options = { thickness: options };\n\n            if (args[1] !== undefined) options.color = args[1];\n            if (args[2] !== undefined) options.quality = args[2];\n            if (args[3] !== undefined) options.alpha = args[3];\n            if (args[4] !== undefined) options.knockout = args[4];\n        }\n\n        options = { ...OutlineFilter.DEFAULT_OPTIONS, ...options };\n\n        const quality = options.quality ?? 0.1;\n\n        const gpuProgram = GpuProgram.from({\n            vertex: {\n                source: wgslVertex,\n                entryPoint: 'mainVertex',\n            },\n            fragment: {\n                source,\n                entryPoint: 'mainFragment',\n            },\n        });\n\n        const glProgram = GlProgram.from({\n            vertex,\n            fragment: fragment.replace(/\\$\\{ANGLE_STEP\\}/, OutlineFilter.getAngleStep(quality).toFixed(7)),\n            name: 'outline-filter',\n        });\n\n        super({\n            gpuProgram,\n            glProgram,\n            resources: {\n                outlineUniforms: {\n                    uThickness: { value: new Float32Array(2), type: 'vec2<f32>' },\n                    uColor: { value: new Float32Array(3), type: 'vec3<f32>' },\n                    uAlpha: { value: options.alpha, type: 'f32' },\n                    uAngleStep: { value: 0, type: 'f32' },\n                    uKnockout: { value: options.knockout ? 1 : 0, type: 'f32' },\n                }\n            },\n        });\n\n        this.uniforms = this.resources.outlineUniforms.uniforms;\n        this.uniforms.uAngleStep = OutlineFilter.getAngleStep(quality);\n        this._color = new Color();\n        this.color = options.color ?? 0x000000;\n\n        Object.assign(this, options);\n    }\n\n    /**\n     * Override existing apply method in `Filter`\n     * @override\n     * @ignore\n     */\n    public override apply(\n        filterManager: FilterSystem,\n        input: Texture,\n        output: RenderSurface,\n        clearMode: boolean\n    ): void\n    {\n        this.uniforms.uThickness[0] = this.thickness / input.source.width;\n        this.uniforms.uThickness[1] = this.thickness / input.source.height;\n\n        filterManager.applyFilter(this, input, output, clearMode);\n    }\n\n    /**\n     * Get the angleStep by quality\n     * @param quality\n     */\n    private static getAngleStep(quality: number): number\n    {\n        return parseFloat(((Math.PI * 2) / Math.max(\n            quality * OutlineFilter.MAX_SAMPLES,\n            OutlineFilter.MIN_SAMPLES,\n        )).toFixed(7));\n    }\n\n    /**\n     * The thickness of the outline\n     * @default 1\n     */\n    get thickness(): number { return this._thickness; }\n    set thickness(value: number) { this._thickness = this.padding = value; }\n\n    /**\n     * The color value of the ambient color\n     * @example [1.0, 1.0, 1.0] = 0xffffff\n     * @default 0x000000\n     */\n    get color(): ColorSource { return this._color.value as ColorSource; }\n    set color(value: ColorSource)\n    {\n        this._color.setValue(value);\n        const [r, g, b] = this._color.toArray();\n\n        this.uniforms.uColor[0] = r;\n        this.uniforms.uColor[1] = g;\n        this.uniforms.uColor[2] = b;\n    }\n\n    /**\n     * Coefficient for alpha multiplication\n     * @default 1\n     */\n    get alpha(): number { return this.uniforms.uAlpha; }\n    set alpha(value: number) { this.uniforms.uAlpha = value; }\n\n    /**\n     * The quality of the outline from `0` to `1`.\n     * Using a higher quality setting will result in more accuracy but slower performance\n     * @default 0.1\n     */\n    get quality(): number { return this._quality; }\n    set quality(value: number)\n    {\n        this._quality = value;\n        this.uniforms.uAngleStep = OutlineFilter.getAngleStep(value);\n    }\n\n    /**\n     * Whether to only render outline, not the contents.\n     * @default false\n     */\n    get knockout(): boolean { return this.uniforms.uKnockout === 1; }\n    set knockout(value: boolean) { this.uniforms.uKnockout = value ? 1 : 0; }\n}\n"],"names":[],"mappings":"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"}