canvas2gl 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README_zh.md ADDED
@@ -0,0 +1,375 @@
1
+ # Canvas2GL
2
+
3
+ 将 Canvas 2D API 映射为 WebGL 渲染的高性能 2D 图形库。使用标准的 Canvas 2D API,底层通过 WebGL 加速渲染,无需学习新的 API。
4
+
5
+ ## 快速开始
6
+
7
+ ```html
8
+ <canvas id="c" width="800" height="600"></canvas>
9
+
10
+ <script type="module">
11
+ import Canvas2gl from 'canvas2gl';
12
+
13
+ const ctx = new Canvas2gl(document.getElementById('c'));
14
+
15
+ ctx.fillStyle = '#e94560';
16
+ ctx.fillRect(50, 50, 200, 100);
17
+
18
+ ctx.fillStyle = 'white';
19
+ ctx.font = '18px sans-serif';
20
+ ctx.fillText('Hello Canvas2GL', 80, 110);
21
+ </script>
22
+ ```
23
+
24
+ ## 属性
25
+
26
+ | 属性 | 类型 | 默认值 | 说明 |
27
+ |------|------|--------|------|
28
+ | `fillStyle` | `string \| Gradient` | `'#000000'` | 填充颜色或渐变 |
29
+ | `strokeStyle` | `string \| Gradient` | `'#000000'` | 描边颜色或渐变 |
30
+ | `lineWidth` | `number` | `1` | 线条宽度(像素) |
31
+ | `globalAlpha` | `number` | `1` | 全局透明度(0~1) |
32
+ | `globalCompositeOperation` | `string` | `'source-over'` | 合成操作模式 |
33
+ | `font` | `string` | `'10px sans-serif'` | 文本字体,与 CSS font 规范相同 |
34
+ | `textAlign` | `string` | `'start'` | 文本水平对齐方式 |
35
+ | `textBaseline` | `string` | `'alphabetic'` | 文本基线对齐方式 |
36
+ | `direction` | `string` | `'inherit'` | 文本方向(`'ltr'` / `'rtl'` / `'inherit'`) |
37
+ | `letterSpacing` | `string` | `'0px'` | 字符间距 |
38
+
39
+ ### globalCompositeOperation 支持的值
40
+
41
+ | 值 | 说明 |
42
+ |----|------|
43
+ | `'source-over'` | 默认,新图形绘制在已有内容上方 |
44
+ | `'lighter'` | 颜色相加 |
45
+ | `'copy'` | 只显示新图形,清除已有内容 |
46
+ | `'source-in'` | 仅在重叠区域保留新图形 |
47
+ | `'source-out'` | 仅在非重叠区域保留新图形 |
48
+ | `'source-atop'` | 新图形在上,仅在重叠区域显示 |
49
+ | `'destination-in'` | 仅在重叠区域保留已有内容 |
50
+ | `'destination-out'` | 仅在非重叠区域保留已有内容 |
51
+ | `'destination-atop'` | 已有内容在上,仅在重叠区域显示 |
52
+ | `'xor'` | 异或模式,重叠区域透明 |
53
+ | `'multiply'` | 颜色相乘(正片叠底) |
54
+
55
+ ### textAlign 支持的值
56
+
57
+ | 值 | 说明 |
58
+ |----|------|
59
+ | `'left'` | 文本左对齐 |
60
+ | `'center'` | 文本居中对齐 |
61
+ | `'right'` | 文本右对齐 |
62
+ | `'start'` | 根据文字方向对齐(默认) |
63
+ | `'end'` | 根据文字方向对齐 |
64
+
65
+ ### textBaseline 支持的值
66
+
67
+ | 值 | 说明 |
68
+ |----|------|
69
+ | `'top'` | 文本顶部对齐 |
70
+ | `'hanging'` | 悬挂基线对齐 |
71
+ | `'middle'` | 文本中间对齐 |
72
+ | `'alphabetic'` | 字母基线对齐(默认) |
73
+ | `'ideographic'` | 表意基线对齐 |
74
+ | `'bottom'` | 文本底部对齐 |
75
+
76
+ ## 路径方法
77
+
78
+ ### beginPath()
79
+ 开始一条新路径,清除之前的路径命令。
80
+
81
+ ```js
82
+ ctx.beginPath();
83
+ ```
84
+
85
+ ### moveTo(x, y)
86
+ 将画笔移动到指定坐标,开始一个新的子路径。
87
+
88
+ ```js
89
+ ctx.moveTo(100, 100);
90
+ ```
91
+
92
+ ### lineTo(x, y)
93
+ 从当前位置画一条直线到指定坐标。
94
+
95
+ ```js
96
+ ctx.lineTo(200, 100);
97
+ ```
98
+
99
+ ### arc(cx, cy, radius, startAngle, endAngle, anticlockwise?)
100
+ 绘制圆弧。角度以弧度为单位。
101
+
102
+ ```js
103
+ // 绘制一个完整的圆
104
+ ctx.arc(150, 150, 50, 0, Math.PI * 2);
105
+
106
+ // 逆时针绘制半圆
107
+ ctx.arc(150, 150, 50, 0, Math.PI, true);
108
+ ```
109
+
110
+ ### rect(x, y, w, h)
111
+ 添加一个矩形子路径。
112
+
113
+ ```js
114
+ ctx.rect(10, 10, 100, 50);
115
+ ```
116
+
117
+ ### bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
118
+ 添加一条三次贝塞尔曲线到当前路径。曲线从当前点开始,以 `(cp1x, cp1y)` 和 `(cp2x, cp2y)` 为控制点,到 `(x, y)` 结束。
119
+
120
+ ```js
121
+ ctx.beginPath();
122
+ ctx.moveTo(50, 100);
123
+ ctx.bezierCurveTo(100, 20, 200, 180, 300, 100);
124
+ ctx.stroke();
125
+ ```
126
+
127
+ ### quadraticCurveTo(cpx, cpy, x, y)
128
+ 添加一条二次贝塞尔曲线到当前路径。曲线从当前点开始,以 `(cpx, cpy)` 为控制点,到 `(x, y)` 结束。
129
+
130
+ ```js
131
+ ctx.beginPath();
132
+ ctx.moveTo(50, 100);
133
+ ctx.quadraticCurveTo(200, 20, 350, 100);
134
+ ctx.stroke();
135
+ ```
136
+
137
+ ### closePath()
138
+ 闭合当前路径,连接终点与起点。
139
+
140
+ ```js
141
+ ctx.closePath();
142
+ ```
143
+
144
+ ### fill()
145
+ 填充当前路径。调用后会自动调用 `beginPath()`。
146
+
147
+ ```js
148
+ ctx.beginPath();
149
+ ctx.arc(100, 100, 40, 0, Math.PI * 2);
150
+ ctx.fill();
151
+ ```
152
+
153
+ ### stroke()
154
+ 描边当前路径。调用后会自动调用 `beginPath()`。
155
+
156
+ ```js
157
+ ctx.beginPath();
158
+ ctx.moveTo(50, 50);
159
+ ctx.lineTo(150, 100);
160
+ ctx.stroke();
161
+ ```
162
+
163
+ ## 矩形方法
164
+
165
+ ### fillRect(x, y, w, h)
166
+ 绘制填充矩形。
167
+
168
+ ```js
169
+ ctx.fillStyle = '#e94560';
170
+ ctx.fillRect(50, 50, 200, 100);
171
+ ```
172
+
173
+ ### strokeRect(x, y, w, h)
174
+ 绘制描边矩形。
175
+
176
+ ```js
177
+ ctx.strokeStyle = '#00d4ff';
178
+ ctx.lineWidth = 3;
179
+ ctx.strokeRect(50, 50, 200, 100);
180
+ ```
181
+
182
+ ### clearRect(x, y, w, h)
183
+ 清除指定矩形区域,将其变为透明。
184
+
185
+ ```js
186
+ ctx.clearRect(0, 0, 400, 200);
187
+ ```
188
+
189
+ ## 渐变方法
190
+
191
+ ### createLinearGradient(x0, y0, x1, y1)
192
+ 创建一个从 `(x0, y0)` 到 `(x1, y1)` 的线性渐变。返回一个 `Gradient` 对象,可赋值给 `fillStyle` 或 `strokeStyle`。
193
+
194
+ ```js
195
+ const grad = ctx.createLinearGradient(0, 0, 400, 0);
196
+ grad.addColorStop(0, '#e94560');
197
+ grad.addColorStop(0.5, '#ffd700');
198
+ grad.addColorStop(1, '#00d4ff');
199
+ ctx.fillStyle = grad;
200
+ ctx.fillRect(0, 0, 400, 200);
201
+ ```
202
+
203
+ ### Gradient.addColorStop(offset, color)
204
+ 向渐变添加一个色标。`offset` 是 0 到 1 之间的值,`color` 是任意有效的 CSS 颜色字符串。
205
+
206
+ ```js
207
+ grad.addColorStop(0, '#e94560'); // 起始为红色
208
+ grad.addColorStop(0.5, 'rgba(0,255,100,0.5)'); // 中间为半透明绿色
209
+ grad.addColorStop(1, 'blue'); // 结束为蓝色
210
+ ```
211
+
212
+ ## 文本方法
213
+
214
+ ### fillText(text, x, y, maxWidth?)
215
+ 绘制填充文本。
216
+
217
+ ```js
218
+ ctx.font = '24px sans-serif';
219
+ ctx.fillStyle = 'white';
220
+ ctx.fillText('Hello World', 100, 100);
221
+
222
+ // 带最大宽度限制
223
+ ctx.fillText('Hello World', 100, 100, 200);
224
+ ```
225
+
226
+ ### strokeText(text, x, y, maxWidth?)
227
+ 绘制描边文本。
228
+
229
+ ```js
230
+ ctx.font = 'bold 18px sans-serif';
231
+ ctx.strokeStyle = '#00d4ff';
232
+ ctx.strokeText('Stroke Text', 50, 80);
233
+ ```
234
+
235
+ ### measureText(text)
236
+ 测量文本尺寸,返回 `TextMetrics` 对象。
237
+
238
+ ```js
239
+ const metrics = ctx.measureText('Hello');
240
+ console.log(metrics.width); // 文本宽度
241
+ ```
242
+
243
+ ## 图像方法
244
+
245
+ ### drawImage(source, ...args)
246
+ 绘制图像到画布上,支持三种调用形式:
247
+
248
+ **形式 1:按原始尺寸绘制**
249
+ ```js
250
+ ctx.drawImage(image, dx, dy);
251
+ ```
252
+
253
+ **形式 2:缩放绘制**
254
+ ```js
255
+ ctx.drawImage(image, dx, dy, dw, dh);
256
+ ```
257
+
258
+ **形式 3:裁剪并缩放绘制**
259
+ ```js
260
+ ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
261
+ ```
262
+
263
+ 参数说明:
264
+ - `source`:`HTMLImageElement` / `HTMLCanvasElement` / `HTMLVideoElement`
265
+ - `sx`, `sy`:源图像裁剪起始坐标
266
+ - `sw`, `sh`:源图像裁剪尺寸
267
+ - `dx`, `dy`:目标画布绘制坐标
268
+ - `dw`, `dh`:目标画布绘制尺寸
269
+
270
+ ```js
271
+ const img = new Image();
272
+ img.src = 'texture.png';
273
+ img.onload = () => {
274
+ // 在 (50, 50) 绘制原始尺寸
275
+ ctx.drawImage(img, 50, 50);
276
+
277
+ // 在 (200, 50) 缩放为 100x100
278
+ ctx.drawImage(img, 200, 50, 100, 100);
279
+
280
+ // 裁剪 (10,10,50,50) 区域,绘制到 (300,50,80,80)
281
+ ctx.drawImage(img, 10, 10, 50, 50, 300, 50, 80, 80);
282
+ };
283
+ ```
284
+
285
+ ## 像素方法
286
+
287
+ ### getImageData(sx, sy, sw, sh)
288
+ 读取画布指定矩形区域的像素数据,返回 `ImageData` 对象。
289
+
290
+ ```js
291
+ const imageData = ctx.getImageData(0, 0, 400, 200);
292
+ // imageData.data 是 Uint8ClampedArray,包含 RGBA 像素数据
293
+ // imageData.width 和 imageData.height 为请求的尺寸
294
+ const r = imageData.data[0]; // 第一个像素的红色分量
295
+ const g = imageData.data[1];
296
+ const b = imageData.data[2];
297
+ const a = imageData.data[3]; // alpha 分量
298
+ ```
299
+
300
+ ## 变换方法
301
+
302
+ ### translate(x, y)
303
+ 平移变换,将原点移动到指定位置。
304
+
305
+ ```js
306
+ ctx.translate(200, 100);
307
+ ```
308
+
309
+ ### rotate(angle)
310
+ 旋转变换,angle 以弧度为单位。
311
+
312
+ ```js
313
+ ctx.rotate(Math.PI / 4); // 旋转 45 度
314
+ ```
315
+
316
+ ### scale(x, y)
317
+ 缩放变换。
318
+
319
+ ```js
320
+ ctx.scale(2, 1); // 水平方向放大 2 倍
321
+ ```
322
+
323
+ ### transform(a, b, c, d, e, f)
324
+ 累积应用变换矩阵 `[a, b, c, d, e, f]`。
325
+
326
+ ```js
327
+ ctx.transform(1, 0.5, 0, 1, 10, 0);
328
+ ```
329
+
330
+ ### setTransform(a, b, c, d, e, f)
331
+ 重置并设置变换矩阵。
332
+
333
+ ```js
334
+ ctx.setTransform(2, 0, 0, 2, 50, 50);
335
+ ```
336
+
337
+ ### resetTransform()
338
+ 将变换矩阵重置为单位矩阵。
339
+
340
+ ```js
341
+ ctx.resetTransform();
342
+ ```
343
+
344
+ ## 状态方法
345
+
346
+ ### save()
347
+ 保存当前绘图状态到栈中,包括:变换矩阵、`fillStyle`、`strokeStyle`、`lineWidth`、`globalAlpha`、`globalCompositeOperation`。
348
+
349
+ ```js
350
+ ctx.save();
351
+ ctx.translate(100, 50);
352
+ // ... 绘制操作 ...
353
+ ctx.restore(); // 恢复保存前的状态
354
+ ```
355
+
356
+ ### restore()
357
+ 从栈中恢复最近保存的绘图状态。
358
+
359
+ ## 画布方法
360
+
361
+ ### clear()
362
+ 清除整个画布,重置为透明。
363
+
364
+ ```js
365
+ ctx.clear();
366
+ ```
367
+
368
+ ### resize()
369
+ 根据画布元素的 CSS 尺寸重新调整 WebGL 视口。在画布大小改变时调用。
370
+
371
+ ```js
372
+ window.addEventListener('resize', () => {
373
+ ctx.resize();
374
+ });
375
+ ```
@@ -0,0 +1,21 @@
1
+ export declare class Gradient {
2
+ private stops;
3
+ private x0;
4
+ private y0;
5
+ private x1;
6
+ private y1;
7
+ private _texture;
8
+ private _gl;
9
+ constructor(x0: number, y0: number, x1: number, y1: number);
10
+ addColorStop(offset: number, color: string): void;
11
+ getTexture(gl: WebGLRenderingContext): WebGLTexture;
12
+ getParams(): {
13
+ x0: number;
14
+ y0: number;
15
+ x1: number;
16
+ y1: number;
17
+ };
18
+ toCanvasGradient(ctx: CanvasRenderingContext2D): CanvasGradient;
19
+ private _sample;
20
+ }
21
+ export declare function parseColorString(color: string): [number, number, number, number];
@@ -0,0 +1,137 @@
1
+ export class Gradient {
2
+ stops = [];
3
+ x0;
4
+ y0;
5
+ x1;
6
+ y1;
7
+ _texture = null;
8
+ _gl = null;
9
+ constructor(x0, y0, x1, y1) {
10
+ this.x0 = x0;
11
+ this.y0 = y0;
12
+ this.x1 = x1;
13
+ this.y1 = y1;
14
+ }
15
+ addColorStop(offset, color) {
16
+ this.stops.push({ offset, color: parseColorString(color) });
17
+ this.stops.sort((a, b) => a.offset - b.offset);
18
+ this._texture = null;
19
+ }
20
+ getTexture(gl) {
21
+ if (this._texture && this._gl === gl)
22
+ return this._texture;
23
+ const size = 256;
24
+ const data = new Uint8Array(size * 4);
25
+ for (let i = 0; i < size; i++) {
26
+ const t = i / (size - 1);
27
+ const color = this._sample(t);
28
+ const idx = i * 4;
29
+ data[idx] = Math.round(color[0] * 255);
30
+ data[idx + 1] = Math.round(color[1] * 255);
31
+ data[idx + 2] = Math.round(color[2] * 255);
32
+ data[idx + 3] = Math.round(color[3] * 255);
33
+ }
34
+ const tex = gl.createTexture();
35
+ gl.bindTexture(gl.TEXTURE_2D, tex);
36
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
37
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
38
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
39
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
40
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
41
+ this._texture = tex;
42
+ this._gl = gl;
43
+ return tex;
44
+ }
45
+ getParams() {
46
+ return { x0: this.x0, y0: this.y0, x1: this.x1, y1: this.y1 };
47
+ }
48
+ toCanvasGradient(ctx) {
49
+ const g = ctx.createLinearGradient(this.x0, this.y0, this.x1, this.y1);
50
+ for (const stop of this.stops) {
51
+ const [r, gv, b, a] = stop.color;
52
+ g.addColorStop(stop.offset, `rgba(${Math.round(r * 255)},${Math.round(gv * 255)},${Math.round(b * 255)},${a})`);
53
+ }
54
+ return g;
55
+ }
56
+ _sample(t) {
57
+ if (this.stops.length === 0)
58
+ return [0, 0, 0, 0];
59
+ if (t <= this.stops[0].offset)
60
+ return this.stops[0].color;
61
+ for (let i = 0; i < this.stops.length - 1; i++) {
62
+ const s0 = this.stops[i];
63
+ const s1 = this.stops[i + 1];
64
+ if (t < s1.offset) {
65
+ const f = (t - s0.offset) / (s1.offset - s0.offset);
66
+ return [
67
+ s0.color[0] + (s1.color[0] - s0.color[0]) * f,
68
+ s0.color[1] + (s1.color[1] - s0.color[1]) * f,
69
+ s0.color[2] + (s1.color[2] - s0.color[2]) * f,
70
+ s0.color[3] + (s1.color[3] - s0.color[3]) * f,
71
+ ];
72
+ }
73
+ }
74
+ return this.stops[this.stops.length - 1].color;
75
+ }
76
+ }
77
+ export function parseColorString(color) {
78
+ const named = {
79
+ black: [0, 0, 0, 1], white: [1, 1, 1, 1], red: [1, 0, 0, 1],
80
+ green: [0, 0.502, 0, 1], blue: [0, 0, 1, 1], yellow: [1, 1, 0, 1],
81
+ cyan: [0, 1, 1, 1], magenta: [1, 0, 1, 1], orange: [1, 0.647, 0, 1],
82
+ gray: [0.502, 0.502, 0.502, 1], grey: [0.502, 0.502, 0.502, 1],
83
+ transparent: [0, 0, 0, 0],
84
+ };
85
+ color = color.trim().toLowerCase();
86
+ if (named[color])
87
+ return [...named[color]];
88
+ let match;
89
+ match = color.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/);
90
+ if (match) {
91
+ return [
92
+ parseInt(match[1], 16) / 255,
93
+ parseInt(match[2], 16) / 255,
94
+ parseInt(match[3], 16) / 255,
95
+ parseInt(match[4], 16) / 255,
96
+ ];
97
+ }
98
+ match = color.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])$/);
99
+ if (match) {
100
+ return [
101
+ parseInt(match[1] + match[1], 16) / 255,
102
+ parseInt(match[2] + match[2], 16) / 255,
103
+ parseInt(match[3] + match[3], 16) / 255,
104
+ parseInt(match[4] + match[4], 16) / 255,
105
+ ];
106
+ }
107
+ match = color.match(/^#([0-9a-f]{6})$/);
108
+ if (match) {
109
+ return [
110
+ parseInt(match[1].substring(0, 2), 16) / 255,
111
+ parseInt(match[1].substring(2, 4), 16) / 255,
112
+ parseInt(match[1].substring(4, 6), 16) / 255,
113
+ 1,
114
+ ];
115
+ }
116
+ match = color.match(/^#([0-9a-f]{3})$/);
117
+ if (match) {
118
+ const c = match[1];
119
+ return [
120
+ parseInt(c[0] + c[0], 16) / 255,
121
+ parseInt(c[1] + c[1], 16) / 255,
122
+ parseInt(c[2] + c[2], 16) / 255,
123
+ 1,
124
+ ];
125
+ }
126
+ match = color.match(/^rgba?\(\s*(\d+%?)\s*,\s*(\d+%?)\s*,\s*(\d+%?)\s*(?:,\s*([\d.]+%?)\s*)?\)$/);
127
+ if (match) {
128
+ const toVal = (v) => v.endsWith('%') ? parseFloat(v) / 100 * 255 : parseInt(v, 10);
129
+ return [
130
+ toVal(match[1]) / 255,
131
+ toVal(match[2]) / 255,
132
+ toVal(match[3]) / 255,
133
+ match[4] !== undefined ? parseFloat(match[4]) : 1,
134
+ ];
135
+ }
136
+ return [0, 0, 0, 1];
137
+ }
@@ -0,0 +1,64 @@
1
+ import { Gradient } from './gradient.js';
2
+ export default class Canvas2gl {
3
+ private renderer;
4
+ private pathCommands;
5
+ private pathPoints;
6
+ private pathSubpaths;
7
+ private pathClosed;
8
+ private texCache;
9
+ private _offscreen;
10
+ private _offCtx;
11
+ private _transform;
12
+ private _stateStack;
13
+ fillStyle: string | Gradient;
14
+ strokeStyle: string | Gradient;
15
+ lineWidth: number;
16
+ globalAlpha: number;
17
+ globalCompositeOperation: string;
18
+ font: string;
19
+ textAlign: CanvasTextAlign;
20
+ textBaseline: CanvasTextBaseline;
21
+ direction: CanvasDirection;
22
+ letterSpacing: string;
23
+ private currentX;
24
+ private currentY;
25
+ private subStartIdx;
26
+ constructor(canvas: HTMLCanvasElement);
27
+ beginPath(): void;
28
+ moveTo(x: number, y: number): void;
29
+ lineTo(x: number, y: number): void;
30
+ arc(cx: number, cy: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void;
31
+ bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
32
+ quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
33
+ rect(x: number, y: number, w: number, h: number): void;
34
+ fillRect(x: number, y: number, w: number, h: number): void;
35
+ strokeRect(x: number, y: number, w: number, h: number): void;
36
+ closePath(): void;
37
+ fill(): void;
38
+ stroke(): void;
39
+ clearRect(x: number, y: number, w: number, h: number): void;
40
+ clear(): void;
41
+ getImageData(sx: number, sy: number, sw: number, sh: number): ImageData;
42
+ createLinearGradient(x0: number, y0: number, x1: number, y1: number): Gradient;
43
+ resize(): void;
44
+ drawImage(source: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, dx: number, dy: number): void;
45
+ drawImage(source: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, dx: number, dy: number, dw: number, dh: number): void;
46
+ drawImage(source: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
47
+ fillText(text: string, x: number, y: number, maxWidth?: number): void;
48
+ strokeText(text: string, x: number, y: number, maxWidth?: number): void;
49
+ measureText(text: string): TextMetrics;
50
+ save(): void;
51
+ restore(): void;
52
+ translate(x: number, y: number): void;
53
+ rotate(angle: number): void;
54
+ scale(x: number, y: number): void;
55
+ transform(a: number, b: number, c: number, d: number, e: number, f: number): void;
56
+ setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void;
57
+ resetTransform(): void;
58
+ private _multiplyTransform;
59
+ private _drawShape;
60
+ private _renderText;
61
+ private _syncToOffscreen;
62
+ private _applyTextAlignX;
63
+ private parseColor;
64
+ }