{"version":3,"file":"Transform.mjs","sources":["../../../src/utils/misc/Transform.ts"],"sourcesContent":["import { Matrix } from '../../maths/matrix/Matrix';\nimport { ObservablePoint } from '../../maths/point/ObservablePoint';\n\nimport type { Observer } from '../../maths/point/ObservablePoint';\n\n/**\n * Options for the {@link Transform} constructor.\n * @category utils\n * @advanced\n */\nexport interface TransformOptions\n{\n    /** The matrix to use. */\n    matrix?: Matrix;\n    /**\n     * The observer to use.\n     * @advanced\n     */\n    observer?: {_onUpdate: (transform: Transform) => void}\n}\n\n/**\n * The Transform class facilitates the manipulation of a 2D transformation matrix through\n * user-friendly properties: position, scale, rotation, skew, and pivot.\n * @example\n * ```ts\n * // Basic transform usage\n * const transform = new Transform();\n * transform.position.set(100, 100);\n * transform.rotation = Math.PI / 4; // 45 degrees\n * transform.scale.set(2, 2);\n *\n * // With pivot point\n * transform.pivot.set(50, 50);\n * transform.rotation = Math.PI; // Rotate around pivot\n *\n * // Matrix manipulation\n * const matrix = transform.matrix;\n * const position = { x: 0, y: 0 };\n * matrix.apply(position); // Transform point\n * ```\n * @remarks\n * - Manages 2D transformation properties\n * - Auto-updates matrix on changes\n * - Supports observable changes\n * - Common in display objects\n * @category utils\n * @standard\n * @see {@link Matrix} For direct matrix operations\n * @see {@link ObservablePoint} For point properties\n */\nexport class Transform\n{\n    /**\n     * The local transformation matrix.\n     * @internal\n     */\n    public _matrix: Matrix;\n\n    /**\n     * The coordinate of the object relative to the local coordinates of the parent.\n     * @example\n     * ```ts\n     * // Basic position setting\n     * transform.position.set(100, 100);\n     *\n     * // Individual coordinate access\n     * transform.position.x = 50;\n     * transform.position.y = 75;\n     * ```\n     */\n    public position: ObservablePoint;\n\n    /**\n     * The scale factor of the object.\n     * @example\n     * ```ts\n     * // Uniform scaling\n     * transform.scale.set(2, 2);\n     *\n     * // Non-uniform scaling\n     * transform.scale.x = 2; // Stretch horizontally\n     * transform.scale.y = 0.5; // Compress vertically\n     * ```\n     */\n    public scale: ObservablePoint;\n\n    /**\n     * The pivot point of the container that it rotates around.\n     * @example\n     * ```ts\n     * // Center pivot\n     * transform.pivot.set(sprite.width / 2, sprite.height / 2);\n     *\n     * // Corner rotation\n     * transform.pivot.set(0, 0);\n     * transform.rotation = Math.PI / 4; // 45 degrees\n     * ```\n     */\n    public pivot: ObservablePoint;\n\n    /**\n     * The skew amount, on the x and y axis.\n     * @example\n     * ```ts\n     * // Apply horizontal skew\n     * transform.skew.x = Math.PI / 6; // 30 degrees\n     *\n     * // Apply both skews\n     * transform.skew.set(Math.PI / 6, Math.PI / 8);\n     * ```\n     */\n    public skew: ObservablePoint;\n\n    /** The rotation amount. */\n    protected _rotation: number;\n\n    /**\n     * The X-coordinate value of the normalized local X axis,\n     * the first column of the local transformation matrix without a scale.\n     */\n    protected _cx: number;\n\n    /**\n     * The Y-coordinate value of the normalized local X axis,\n     * the first column of the local transformation matrix without a scale.\n     */\n    protected _sx: number;\n\n    /**\n     * The X-coordinate value of the normalized local Y axis,\n     * the second column of the local transformation matrix without a scale.\n     */\n    protected _cy: number;\n\n    /**\n     * The Y-coordinate value of the normalized local Y axis,\n     * the second column of the local transformation matrix without a scale.\n     */\n    protected _sy: number;\n\n    protected dirty = true;\n    protected observer: Observer<Transform>;\n\n    /**\n     * @param options - Options for the transform.\n     * @param options.matrix - The matrix to use.\n     * @param options.observer - The observer to use.\n     */\n    constructor({ matrix, observer }: TransformOptions = {})\n    {\n        this._matrix = matrix ?? new Matrix();\n        this.observer = observer;\n\n        this.position = new ObservablePoint(this, 0, 0);\n        this.scale = new ObservablePoint(this, 1, 1);\n        this.pivot = new ObservablePoint(this, 0, 0);\n        this.skew = new ObservablePoint(this, 0, 0);\n\n        this._rotation = 0;\n        this._cx = 1;\n        this._sx = 0;\n        this._cy = 0;\n        this._sy = 1;\n    }\n\n    /**\n     * The transformation matrix computed from the transform's properties.\n     * Combines position, scale, rotation, skew, and pivot into a single matrix.\n     * @example\n     * ```ts\n     * // Get current matrix\n     * const matrix = transform.matrix;\n     * console.log(matrix.toString());\n     * ```\n     * @readonly\n     * @see {@link Matrix} For matrix operations\n     * @see {@link Transform.setFromMatrix} For setting transform from matrix\n     */\n    get matrix(): Matrix\n    {\n        const lt = this._matrix;\n\n        if (!this.dirty) return lt;\n\n        lt.a = this._cx * this.scale.x;\n        lt.b = this._sx * this.scale.x;\n        lt.c = this._cy * this.scale.y;\n        lt.d = this._sy * this.scale.y;\n\n        lt.tx = this.position.x - ((this.pivot.x * lt.a) + (this.pivot.y * lt.c));\n        lt.ty = this.position.y - ((this.pivot.x * lt.b) + (this.pivot.y * lt.d));\n\n        this.dirty = false;\n\n        return lt;\n    }\n    /**\n     * Called when a value changes.\n     * @param point\n     * @internal\n     */\n    public _onUpdate(point?: ObservablePoint): void\n    {\n        this.dirty = true;\n\n        if (point === this.skew)\n        {\n            this.updateSkew();\n        }\n\n        this.observer?._onUpdate(this);\n    }\n\n    /** Called when the skew or the rotation changes. */\n    protected updateSkew(): void\n    {\n        this._cx = Math.cos(this._rotation + this.skew.y);\n        this._sx = Math.sin(this._rotation + this.skew.y);\n        this._cy = -Math.sin(this._rotation - this.skew.x); // cos, added PI/2\n        this._sy = Math.cos(this._rotation - this.skew.x); // sin, added PI/2\n\n        this.dirty = true;\n    }\n\n    // #if _DEBUG\n    public toString(): string\n    {\n        return `[pixi.js/math:Transform `\n            + `position=(${this.position.x}, ${this.position.y}) `\n            + `rotation=${this.rotation} `\n            + `scale=(${this.scale.x}, ${this.scale.y}) `\n            + `skew=(${this.skew.x}, ${this.skew.y}) `\n            + `]`;\n    }\n    // #endif\n\n    /**\n     * Decomposes a matrix and sets the transforms properties based on it.\n     * @example\n     * ```ts\n     * // Basic matrix decomposition\n     * const transform = new Transform();\n     * const matrix = new Matrix()\n     *     .translate(100, 100)\n     *     .rotate(Math.PI / 4)\n     *     .scale(2, 2);\n     *\n     * transform.setFromMatrix(matrix);\n     * console.log(transform.position.x); // 100\n     * console.log(transform.rotation); // ~0.785 (π/4)\n     * ```\n     * @param matrix - The matrix to decompose\n     * @see {@link Matrix#decompose} For the decomposition logic\n     * @see {@link Transform#matrix} For getting the current matrix\n     */\n    public setFromMatrix(matrix: Matrix): void\n    {\n        matrix.decompose(this);\n        this.dirty = true;\n    }\n\n    /**\n     * The rotation of the object in radians.\n     * @example\n     * ```ts\n     * // Basic rotation\n     * transform.rotation = Math.PI / 4; // 45 degrees\n     *\n     * // Rotate around pivot point\n     * transform.pivot.set(50, 50);\n     * transform.rotation = Math.PI; // 180 degrees around pivot\n     *\n     * // Animate rotation\n     * app.ticker.add(() => {\n     *     transform.rotation += 0.1;\n     * });\n     * ```\n     * @see {@link Transform#pivot} For rotation point\n     * @see {@link Transform#skew} For skew effects\n     */\n    get rotation(): number\n    {\n        return this._rotation;\n    }\n\n    set rotation(value: number)\n    {\n        if (this._rotation !== value)\n        {\n            this._rotation = value;\n            this._onUpdate(this.skew);\n        }\n    }\n}\n"],"names":[],"mappings":"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"}