aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/Transform.ts
blob: 3e103916609b360c1833a783c72df2abe6fd53c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
export class Transform {
    private _translateX: number = 0;
    private _translateY: number = 0;
    private _scale: number = 1;

    static get Identity(): Transform {
        return new Transform(0, 0, 1);
    }

    get TranslateX(): number { return this._translateX; }
    get TranslateY(): number { return this._translateY; }
    get Scale(): number { return this._scale; }

    constructor(x: number, y: number, scale: number) {
        this._translateX = x;
        this._translateY = y;
        this._scale = scale;
    }

    translate = (x: number, y: number): Transform => {
        this._translateX += x;
        this._translateY += y;
        return this;
    }

    scale = (scale: number): Transform => {
        this._scale *= scale;
        this._translateX *= scale;
        this._translateY *= scale;
        return this;
    }

    scaleAbout = (scale: number, x: number, y: number): Transform => {
        this._translateX += x * this._scale - x * this._scale * scale;
        this._translateY += y * this._scale - y * this._scale * scale;
        this._scale *= scale;
        return this;
    }

    transform = (transform: Transform): Transform => {
        this._translateX = transform._translateX + transform._scale * this._translateX;
        this._translateY = transform._translateY + transform._scale * this._translateY;
        this._scale *= transform._scale;
        return this;
    }

    preTranslate = (x: number, y: number): Transform => {
        this._translateX += this._scale * x;
        this._translateY += this._scale * y;
        return this;
    }

    preScale = (scale: number): Transform => {
        this._scale *= scale;
        return this;
    }

    preTransform = (transform: Transform): Transform => {
        this._translateX += transform._translateX * this._scale;
        this._translateY += transform._translateY * this._scale;
        this._scale *= transform._scale;
        return this;
    }

    translated = (x: number, y: number): Transform => {
        return this.copy().translate(x, y);
    }

    preTranslated = (x: number, y: number): Transform => {
        return this.copy().preTranslate(x, y);
    }

    scaled = (scale: number): Transform => {
        return this.copy().scale(scale);
    }

    scaledAbout = (scale: number, x: number, y: number): Transform => {
        return this.copy().scaleAbout(scale, x, y);
    }

    preScaled = (scale: number): Transform => {
        return this.copy().preScale(scale);
    }

    transformed = (transform: Transform): Transform => {
        return this.copy().transform(transform);
    }

    preTransformed = (transform: Transform): Transform => {
        return this.copy().preTransform(transform);
    }

    transformPoint = (x: number, y: number): [number, number] => {
        x *= this._scale;
        x += this._translateX;
        y *= this._scale;
        y += this._translateY;
        return [x, y];
    }

    transformDirection = (x: number, y: number): [number, number] => {
        return [x * this._scale, y * this._scale];
    }

    transformBounds(x: number, y: number, width: number, height: number): { x: number, y: number, width: number, height: number } {
        [x, y] = this.transformPoint(x, y);
        [width, height] = this.transformDirection(width, height);
        return { x, y, width, height };
    }

    inverse = () => {
        return new Transform(-this._translateX / this._scale, -this._translateY / this._scale, 1 / this._scale)
    }

    copy = () => {
        return new Transform(this._translateX, this._translateY, this._scale);
    }

}