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);
}
}
|