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.md +376 -0
- package/README_zh.md +375 -0
- package/dist/gradient.d.ts +21 -0
- package/dist/gradient.js +137 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.js +409 -0
- package/dist/renderer.d.ts +55 -0
- package/dist/renderer.js +871 -0
- package/dist/shapes.d.ts +9 -0
- package/dist/shapes.js +165 -0
- package/dist/types.d.ts +23 -0
- package/dist/types.js +1 -0
- package/package.json +32 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import { triangulateRect, triangulateArc, triangulateFillPath, triangulateStrokePath, arcToPoints, cubicBezierPoints, quadraticBezierPoints, } from './shapes.js';
|
|
2
|
+
import { WebGLRenderer } from './renderer.js';
|
|
3
|
+
import { Gradient } from './gradient.js';
|
|
4
|
+
const NAMED_COLORS = {
|
|
5
|
+
black: [0, 0, 0, 1], white: [1, 1, 1, 1], red: [1, 0, 0, 1],
|
|
6
|
+
green: [0, 0.502, 0, 1], blue: [0, 0, 1, 1], yellow: [1, 1, 0, 1],
|
|
7
|
+
cyan: [0, 1, 1, 1], magenta: [1, 0, 1, 1], orange: [1, 0.647, 0, 1],
|
|
8
|
+
gray: [0.502, 0.502, 0.502, 1], grey: [0.502, 0.502, 0.502, 1],
|
|
9
|
+
transparent: [0, 0, 0, 0],
|
|
10
|
+
};
|
|
11
|
+
export default class Canvas2gl {
|
|
12
|
+
renderer;
|
|
13
|
+
pathCommands = [];
|
|
14
|
+
pathPoints = [];
|
|
15
|
+
pathSubpaths = [];
|
|
16
|
+
pathClosed = false;
|
|
17
|
+
texCache = new WeakMap();
|
|
18
|
+
_offscreen = document.createElement('canvas');
|
|
19
|
+
_offCtx = this._offscreen.getContext('2d');
|
|
20
|
+
_transform = new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]);
|
|
21
|
+
_stateStack = [];
|
|
22
|
+
fillStyle = '#000000';
|
|
23
|
+
strokeStyle = '#000000';
|
|
24
|
+
lineWidth = 1;
|
|
25
|
+
globalAlpha = 1;
|
|
26
|
+
globalCompositeOperation = 'source-over';
|
|
27
|
+
font = '10px sans-serif';
|
|
28
|
+
textAlign = 'start';
|
|
29
|
+
textBaseline = 'alphabetic';
|
|
30
|
+
direction = 'inherit';
|
|
31
|
+
letterSpacing = '0px';
|
|
32
|
+
currentX = 0;
|
|
33
|
+
currentY = 0;
|
|
34
|
+
subStartIdx = 0;
|
|
35
|
+
constructor(canvas) {
|
|
36
|
+
this.renderer = new WebGLRenderer(canvas);
|
|
37
|
+
}
|
|
38
|
+
beginPath() {
|
|
39
|
+
this.pathCommands = [];
|
|
40
|
+
this.pathPoints = [];
|
|
41
|
+
this.pathSubpaths = [];
|
|
42
|
+
this.pathClosed = false;
|
|
43
|
+
this.currentX = 0;
|
|
44
|
+
this.currentY = 0;
|
|
45
|
+
this.subStartIdx = 0;
|
|
46
|
+
}
|
|
47
|
+
moveTo(x, y) {
|
|
48
|
+
if (this.pathPoints.length > this.subStartIdx) {
|
|
49
|
+
this.pathSubpaths.push(this.pathPoints.slice(this.subStartIdx));
|
|
50
|
+
}
|
|
51
|
+
this.subStartIdx = this.pathPoints.length;
|
|
52
|
+
this.pathCommands.push({ type: 'moveTo', x, y });
|
|
53
|
+
this.pathPoints.push({ x, y });
|
|
54
|
+
this.currentX = x;
|
|
55
|
+
this.currentY = y;
|
|
56
|
+
}
|
|
57
|
+
lineTo(x, y) {
|
|
58
|
+
this.pathCommands.push({ type: 'lineTo', x, y });
|
|
59
|
+
this.pathPoints.push({ x, y });
|
|
60
|
+
this.currentX = x;
|
|
61
|
+
this.currentY = y;
|
|
62
|
+
}
|
|
63
|
+
arc(cx, cy, radius, startAngle, endAngle, anticlockwise = false) {
|
|
64
|
+
this.pathCommands.push({
|
|
65
|
+
type: 'arc', cx, cy, radius, startAngle, endAngle, anticlockwise,
|
|
66
|
+
});
|
|
67
|
+
const endX = cx + radius * Math.cos(endAngle);
|
|
68
|
+
const endY = cy + radius * Math.sin(endAngle);
|
|
69
|
+
this.pathPoints.push({ x: endX, y: endY });
|
|
70
|
+
this.currentX = endX;
|
|
71
|
+
this.currentY = endY;
|
|
72
|
+
}
|
|
73
|
+
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {
|
|
74
|
+
this.pathCommands.push({
|
|
75
|
+
type: 'bezierCurveTo', cp1x, cp1y, cp2x, cp2y, x, y,
|
|
76
|
+
});
|
|
77
|
+
const pts = cubicBezierPoints(this.currentX, this.currentY, cp1x, cp1y, cp2x, cp2y, x, y);
|
|
78
|
+
for (const p of pts)
|
|
79
|
+
this.pathPoints.push(p);
|
|
80
|
+
this.currentX = x;
|
|
81
|
+
this.currentY = y;
|
|
82
|
+
}
|
|
83
|
+
quadraticCurveTo(cpx, cpy, x, y) {
|
|
84
|
+
this.pathCommands.push({
|
|
85
|
+
type: 'quadraticCurveTo', x, y,
|
|
86
|
+
cp1x: cpx, cp1y: cpy,
|
|
87
|
+
});
|
|
88
|
+
const pts = quadraticBezierPoints(this.currentX, this.currentY, cpx, cpy, x, y);
|
|
89
|
+
for (const p of pts)
|
|
90
|
+
this.pathPoints.push(p);
|
|
91
|
+
this.currentX = x;
|
|
92
|
+
this.currentY = y;
|
|
93
|
+
}
|
|
94
|
+
rect(x, y, w, h) {
|
|
95
|
+
this.pathCommands.push({ type: 'rect', rx: x, ry: y, rw: w, rh: h });
|
|
96
|
+
}
|
|
97
|
+
fillRect(x, y, w, h) {
|
|
98
|
+
const verts = triangulateRect(x, y, w, h);
|
|
99
|
+
this._drawShape(flattenVerts(verts), this.fillStyle);
|
|
100
|
+
}
|
|
101
|
+
strokeRect(x, y, w, h) {
|
|
102
|
+
const pts = [
|
|
103
|
+
{ x, y }, { x: x + w, y },
|
|
104
|
+
{ x: x + w, y: y + h }, { x, y: y + h },
|
|
105
|
+
];
|
|
106
|
+
const verts = triangulateStrokePath(pts, this.lineWidth, true);
|
|
107
|
+
this._drawShape(flattenVerts(verts), this.strokeStyle);
|
|
108
|
+
}
|
|
109
|
+
closePath() {
|
|
110
|
+
this.pathClosed = true;
|
|
111
|
+
if (this.pathPoints.length > this.subStartIdx) {
|
|
112
|
+
this.pathSubpaths.push(this.pathPoints.slice(this.subStartIdx));
|
|
113
|
+
this.subStartIdx = this.pathPoints.length;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
fill() {
|
|
117
|
+
const allVerts = [];
|
|
118
|
+
for (const cmd of this.pathCommands) {
|
|
119
|
+
switch (cmd.type) {
|
|
120
|
+
case 'rect':
|
|
121
|
+
allVerts.push(...triangulateRect(cmd.rx, cmd.ry, cmd.rw, cmd.rh));
|
|
122
|
+
break;
|
|
123
|
+
case 'arc':
|
|
124
|
+
allVerts.push(...triangulateArc(cmd.cx, cmd.cy, cmd.radius, cmd.startAngle, cmd.endAngle, cmd.anticlockwise));
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (const sub of this.pathSubpaths) {
|
|
129
|
+
if (sub.length >= 3) {
|
|
130
|
+
allVerts.push(...triangulateFillPath(sub));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (allVerts.length > 0) {
|
|
134
|
+
const verts = flattenVerts(allVerts);
|
|
135
|
+
this._drawShape(verts, this.fillStyle);
|
|
136
|
+
}
|
|
137
|
+
this.beginPath();
|
|
138
|
+
}
|
|
139
|
+
stroke() {
|
|
140
|
+
const allVerts = [];
|
|
141
|
+
for (const cmd of this.pathCommands) {
|
|
142
|
+
switch (cmd.type) {
|
|
143
|
+
case 'rect': {
|
|
144
|
+
const { rx: x, ry: y, rw: w, rh: h } = cmd;
|
|
145
|
+
const pts = [
|
|
146
|
+
{ x: x, y: y }, { x: x + w, y: y },
|
|
147
|
+
{ x: x + w, y: y + h }, { x: x, y: y + h },
|
|
148
|
+
];
|
|
149
|
+
allVerts.push(...triangulateStrokePath(pts, this.lineWidth, true));
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case 'arc': {
|
|
153
|
+
const pts = arcToPoints(cmd.cx, cmd.cy, cmd.radius, cmd.startAngle, cmd.endAngle, cmd.anticlockwise);
|
|
154
|
+
allVerts.push(...triangulateStrokePath(pts, this.lineWidth, false));
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (this.pathPoints.length > this.subStartIdx) {
|
|
160
|
+
this.pathSubpaths.push(this.pathPoints.slice(this.subStartIdx));
|
|
161
|
+
}
|
|
162
|
+
for (const sub of this.pathSubpaths) {
|
|
163
|
+
if (sub.length >= 2) {
|
|
164
|
+
allVerts.push(...triangulateStrokePath(sub, this.lineWidth, this.pathClosed));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (allVerts.length > 0) {
|
|
168
|
+
const verts = flattenVerts(allVerts);
|
|
169
|
+
this._drawShape(verts, this.strokeStyle);
|
|
170
|
+
}
|
|
171
|
+
this.beginPath();
|
|
172
|
+
}
|
|
173
|
+
clearRect(x, y, w, h) {
|
|
174
|
+
this.renderer.clearRect(x, y, w, h);
|
|
175
|
+
}
|
|
176
|
+
clear() {
|
|
177
|
+
this.renderer.clear();
|
|
178
|
+
}
|
|
179
|
+
getImageData(sx, sy, sw, sh) {
|
|
180
|
+
const pixels = this.renderer.readPixels(sx, sy, sw, sh);
|
|
181
|
+
return new ImageData(new Uint8ClampedArray(pixels), sw, sh);
|
|
182
|
+
}
|
|
183
|
+
createLinearGradient(x0, y0, x1, y1) {
|
|
184
|
+
return new Gradient(x0, y0, x1, y1);
|
|
185
|
+
}
|
|
186
|
+
resize() {
|
|
187
|
+
this.renderer.resize();
|
|
188
|
+
}
|
|
189
|
+
drawImage(source, ...args) {
|
|
190
|
+
let sx, sy, sw, sh;
|
|
191
|
+
let dx, dy, dw, dh;
|
|
192
|
+
if (args.length === 2) {
|
|
193
|
+
[dx, dy] = args;
|
|
194
|
+
dw = getSourceWidth(source);
|
|
195
|
+
dh = getSourceHeight(source);
|
|
196
|
+
sx = 0;
|
|
197
|
+
sy = 0;
|
|
198
|
+
sw = dw;
|
|
199
|
+
sh = dh;
|
|
200
|
+
}
|
|
201
|
+
else if (args.length === 4) {
|
|
202
|
+
[dx, dy, dw, dh] = args;
|
|
203
|
+
sx = 0;
|
|
204
|
+
sy = 0;
|
|
205
|
+
sw = getSourceWidth(source);
|
|
206
|
+
sh = getSourceHeight(source);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
[sx, sy, sw, sh, dx, dy, dw, dh] = args;
|
|
210
|
+
}
|
|
211
|
+
let tex = this.texCache.get(source);
|
|
212
|
+
if (!tex) {
|
|
213
|
+
tex = this.renderer.createTexture(source);
|
|
214
|
+
this.texCache.set(source, tex);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
this.renderer.updateTexture(tex, source);
|
|
218
|
+
}
|
|
219
|
+
this.renderer.drawTexture(tex, sx, sy, sw, sh, dx, dy, dw, dh, getSourceWidth(source), getSourceHeight(source), this.globalAlpha, this.globalCompositeOperation, this._transform);
|
|
220
|
+
}
|
|
221
|
+
fillText(text, x, y, maxWidth) {
|
|
222
|
+
this._renderText(text, x, y, maxWidth, false);
|
|
223
|
+
}
|
|
224
|
+
strokeText(text, x, y, maxWidth) {
|
|
225
|
+
this._renderText(text, x, y, maxWidth, true);
|
|
226
|
+
}
|
|
227
|
+
measureText(text) {
|
|
228
|
+
this._syncToOffscreen();
|
|
229
|
+
return this._offCtx.measureText(text);
|
|
230
|
+
}
|
|
231
|
+
save() {
|
|
232
|
+
const transformCopy = new Float32Array(9);
|
|
233
|
+
transformCopy.set(this._transform);
|
|
234
|
+
this._stateStack.push({
|
|
235
|
+
transform: transformCopy,
|
|
236
|
+
fillStyle: this.fillStyle,
|
|
237
|
+
strokeStyle: this.strokeStyle,
|
|
238
|
+
lineWidth: this.lineWidth,
|
|
239
|
+
globalAlpha: this.globalAlpha,
|
|
240
|
+
globalCompositeOperation: this.globalCompositeOperation,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
restore() {
|
|
244
|
+
if (this._stateStack.length > 0) {
|
|
245
|
+
const saved = this._stateStack.pop();
|
|
246
|
+
const transformCopy = new Float32Array(9);
|
|
247
|
+
transformCopy.set(saved.transform);
|
|
248
|
+
this._transform = transformCopy;
|
|
249
|
+
this.fillStyle = saved.fillStyle;
|
|
250
|
+
this.strokeStyle = saved.strokeStyle;
|
|
251
|
+
this.lineWidth = saved.lineWidth;
|
|
252
|
+
this.globalAlpha = saved.globalAlpha;
|
|
253
|
+
this.globalCompositeOperation = saved.globalCompositeOperation;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
translate(x, y) {
|
|
257
|
+
this._multiplyTransform(new Float32Array([1, 0, 0, 0, 1, 0, x, y, 1]));
|
|
258
|
+
}
|
|
259
|
+
rotate(angle) {
|
|
260
|
+
const c = Math.cos(angle);
|
|
261
|
+
const s = Math.sin(angle);
|
|
262
|
+
this._multiplyTransform(new Float32Array([c, -s, 0, s, c, 0, 0, 0, 1]));
|
|
263
|
+
}
|
|
264
|
+
scale(x, y) {
|
|
265
|
+
this._multiplyTransform(new Float32Array([x, 0, 0, 0, y, 0, 0, 0, 1]));
|
|
266
|
+
}
|
|
267
|
+
transform(a, b, c, d, e, f) {
|
|
268
|
+
this._multiplyTransform(new Float32Array([a, b, 0, c, d, 0, e, f, 1]));
|
|
269
|
+
}
|
|
270
|
+
setTransform(a, b, c, d, e, f) {
|
|
271
|
+
this._transform = new Float32Array([a, b, 0, c, d, 0, e, f, 1]);
|
|
272
|
+
}
|
|
273
|
+
resetTransform() {
|
|
274
|
+
this._transform = new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]);
|
|
275
|
+
}
|
|
276
|
+
_multiplyTransform(m) {
|
|
277
|
+
const a = this._transform;
|
|
278
|
+
const result = new Float32Array(9);
|
|
279
|
+
for (let i = 0; i < 3; i++) {
|
|
280
|
+
for (let j = 0; j < 3; j++) {
|
|
281
|
+
result[i * 3 + j] = m[i * 3 + 0] * a[0 * 3 + j] + m[i * 3 + 1] * a[1 * 3 + j] + m[i * 3 + 2] * a[2 * 3 + j];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
this._transform = result;
|
|
285
|
+
}
|
|
286
|
+
_drawShape(verts, colorOrGradient) {
|
|
287
|
+
if (colorOrGradient instanceof Gradient) {
|
|
288
|
+
this.renderer.drawGradient(verts, colorOrGradient, this.globalCompositeOperation, this._transform);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
this.renderer.draw(verts, this.parseColor(colorOrGradient), this.globalCompositeOperation, this._transform);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
_renderText(text, x, y, maxWidth, stroke) {
|
|
295
|
+
this._syncToOffscreen();
|
|
296
|
+
const ctx = this._offCtx;
|
|
297
|
+
const metrics = ctx.measureText(text);
|
|
298
|
+
const padding = 2;
|
|
299
|
+
const baselineOffY = metrics.fontBoundingBoxAscent + padding;
|
|
300
|
+
const totalH = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent + 2 * padding;
|
|
301
|
+
const w = Math.ceil(metrics.width + 2 * padding);
|
|
302
|
+
const h = Math.ceil(Math.max(totalH, 1));
|
|
303
|
+
if (w <= 0 || h <= 0)
|
|
304
|
+
return;
|
|
305
|
+
const dpr = window.devicePixelRatio || 1;
|
|
306
|
+
this._offscreen.width = Math.ceil(w * dpr);
|
|
307
|
+
this._offscreen.height = Math.ceil(h * dpr);
|
|
308
|
+
this._syncToOffscreen();
|
|
309
|
+
ctx.save();
|
|
310
|
+
ctx.scale(dpr, dpr);
|
|
311
|
+
const args = [text, padding, baselineOffY];
|
|
312
|
+
if (maxWidth !== undefined)
|
|
313
|
+
args.push(maxWidth);
|
|
314
|
+
ctx.fillText(...args);
|
|
315
|
+
if (stroke)
|
|
316
|
+
ctx.strokeText(...args);
|
|
317
|
+
ctx.restore();
|
|
318
|
+
const drawX = x - padding;
|
|
319
|
+
const drawY = y - baselineOffY;
|
|
320
|
+
const adjustedX = this._applyTextAlignX(drawX, metrics);
|
|
321
|
+
this.drawImage(this._offscreen, adjustedX, drawY, w, h);
|
|
322
|
+
}
|
|
323
|
+
_syncToOffscreen() {
|
|
324
|
+
const ctx = this._offCtx;
|
|
325
|
+
ctx.font = this.font;
|
|
326
|
+
ctx.fillStyle = this.fillStyle instanceof Gradient ? this.fillStyle.toCanvasGradient(ctx) : this.fillStyle;
|
|
327
|
+
ctx.strokeStyle = this.strokeStyle instanceof Gradient ? this.strokeStyle.toCanvasGradient(ctx) : this.strokeStyle;
|
|
328
|
+
ctx.lineWidth = this.lineWidth;
|
|
329
|
+
ctx.globalAlpha = this.globalAlpha;
|
|
330
|
+
ctx.textAlign = 'left';
|
|
331
|
+
ctx.textBaseline = this.textBaseline;
|
|
332
|
+
ctx.letterSpacing = this.letterSpacing;
|
|
333
|
+
ctx.direction = this.direction;
|
|
334
|
+
}
|
|
335
|
+
_applyTextAlignX(x, metrics) {
|
|
336
|
+
const w = metrics.width;
|
|
337
|
+
const isRTL = this.direction === 'rtl';
|
|
338
|
+
switch (this.textAlign) {
|
|
339
|
+
case 'center': return x - w / 2;
|
|
340
|
+
case 'end': return isRTL ? x : x - w;
|
|
341
|
+
case 'right': return x - w;
|
|
342
|
+
case 'start': return isRTL ? x - w : x;
|
|
343
|
+
default: return x;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
parseColor(color) {
|
|
347
|
+
const trimmed = color.trim().toLowerCase();
|
|
348
|
+
if (trimmed in NAMED_COLORS) {
|
|
349
|
+
const c = NAMED_COLORS[trimmed];
|
|
350
|
+
return [c[0], c[1], c[2], c[3] * this.globalAlpha];
|
|
351
|
+
}
|
|
352
|
+
const hex = trimmed.match(/^#([0-9a-f]{3,8})$/);
|
|
353
|
+
if (hex) {
|
|
354
|
+
const h = hex[1];
|
|
355
|
+
if (h.length === 3) {
|
|
356
|
+
return [
|
|
357
|
+
parseInt(h[0] + h[0], 16) / 255,
|
|
358
|
+
parseInt(h[1] + h[1], 16) / 255,
|
|
359
|
+
parseInt(h[2] + h[2], 16) / 255,
|
|
360
|
+
this.globalAlpha,
|
|
361
|
+
];
|
|
362
|
+
}
|
|
363
|
+
if (h.length === 6) {
|
|
364
|
+
return [
|
|
365
|
+
parseInt(h.slice(0, 2), 16) / 255,
|
|
366
|
+
parseInt(h.slice(2, 4), 16) / 255,
|
|
367
|
+
parseInt(h.slice(4, 6), 16) / 255,
|
|
368
|
+
this.globalAlpha,
|
|
369
|
+
];
|
|
370
|
+
}
|
|
371
|
+
if (h.length === 8) {
|
|
372
|
+
return [
|
|
373
|
+
parseInt(h.slice(0, 2), 16) / 255,
|
|
374
|
+
parseInt(h.slice(2, 4), 16) / 255,
|
|
375
|
+
parseInt(h.slice(4, 6), 16) / 255,
|
|
376
|
+
parseInt(h.slice(6, 8), 16) / 255 * this.globalAlpha,
|
|
377
|
+
];
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
const rgb = trimmed.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+)\s*)?\)$/);
|
|
381
|
+
if (rgb) {
|
|
382
|
+
return [
|
|
383
|
+
parseInt(rgb[1], 10) / 255,
|
|
384
|
+
parseInt(rgb[2], 10) / 255,
|
|
385
|
+
parseInt(rgb[3], 10) / 255,
|
|
386
|
+
(rgb[4] ? parseFloat(rgb[4]) : 1) * this.globalAlpha,
|
|
387
|
+
];
|
|
388
|
+
}
|
|
389
|
+
return [0, 0, 0, this.globalAlpha];
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
function flattenVerts(verts) {
|
|
393
|
+
const arr = new Float32Array(verts.length * 2);
|
|
394
|
+
for (let i = 0; i < verts.length; i++) {
|
|
395
|
+
arr[i * 2] = verts[i].x;
|
|
396
|
+
arr[i * 2 + 1] = verts[i].y;
|
|
397
|
+
}
|
|
398
|
+
return arr;
|
|
399
|
+
}
|
|
400
|
+
function getSourceWidth(source) {
|
|
401
|
+
if (source instanceof HTMLVideoElement)
|
|
402
|
+
return source.videoWidth;
|
|
403
|
+
return source.width;
|
|
404
|
+
}
|
|
405
|
+
function getSourceHeight(source) {
|
|
406
|
+
if (source instanceof HTMLVideoElement)
|
|
407
|
+
return source.videoHeight;
|
|
408
|
+
return source.height;
|
|
409
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Gradient } from './gradient.js';
|
|
2
|
+
export declare class WebGLRenderer {
|
|
3
|
+
private gl;
|
|
4
|
+
private canvas;
|
|
5
|
+
private program;
|
|
6
|
+
private buffer;
|
|
7
|
+
private aPosition;
|
|
8
|
+
private uResolution;
|
|
9
|
+
private uColor;
|
|
10
|
+
private uTransform;
|
|
11
|
+
private texProgram;
|
|
12
|
+
private texBuffer;
|
|
13
|
+
private aTexCoords;
|
|
14
|
+
private uTexResolution;
|
|
15
|
+
private uTexture;
|
|
16
|
+
private uTexAlpha;
|
|
17
|
+
private uTexTransform;
|
|
18
|
+
private screenTex;
|
|
19
|
+
private srcTex;
|
|
20
|
+
private screenW;
|
|
21
|
+
private screenH;
|
|
22
|
+
private mulProgram;
|
|
23
|
+
private aMulPosition;
|
|
24
|
+
private aMulTexCoords;
|
|
25
|
+
private uMulResolution;
|
|
26
|
+
private uSrcTexture;
|
|
27
|
+
private uDstTexture;
|
|
28
|
+
private uMulTransform;
|
|
29
|
+
private gradProgram;
|
|
30
|
+
private aGradPosition;
|
|
31
|
+
private uGradResolution;
|
|
32
|
+
private uGradTransform;
|
|
33
|
+
private uGradP0;
|
|
34
|
+
private uGradP1;
|
|
35
|
+
private uGradTex;
|
|
36
|
+
private uGradAlpha;
|
|
37
|
+
constructor(canvas: HTMLCanvasElement);
|
|
38
|
+
resize(): void;
|
|
39
|
+
clear(): void;
|
|
40
|
+
readPixels(x: number, y: number, w: number, h: number): Uint8Array;
|
|
41
|
+
private captureScreen;
|
|
42
|
+
private drawScreenTexture;
|
|
43
|
+
private drawCompositeShader;
|
|
44
|
+
private _drawShaderComposite;
|
|
45
|
+
private _drawTextureShaderComposite;
|
|
46
|
+
draw(vertices: Float32Array, color: [number, number, number, number], compositeOp: string, transform: Float32Array): void;
|
|
47
|
+
drawGradient(vertices: Float32Array, gradient: Gradient, compositeOp: string, transform: Float32Array): void;
|
|
48
|
+
private drawGradientFBO;
|
|
49
|
+
createTexture(source: TexImageSource): WebGLTexture;
|
|
50
|
+
updateTexture(tex: WebGLTexture, source: TexImageSource): void;
|
|
51
|
+
drawTexture(texture: WebGLTexture, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number, texW: number, texH: number, alpha: number, compositeOp: string, transform: Float32Array): void;
|
|
52
|
+
clearRect(x: number, y: number, w: number, h: number): void;
|
|
53
|
+
private createProgram;
|
|
54
|
+
private compileShader;
|
|
55
|
+
}
|