-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
95 lines (77 loc) · 2.21 KB
/
index.ts
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
type Complex = {
r: number;
i: number;
};
const complexZero = { r: 0, i: 0 };
function complexAdd(c1: Complex, c2: Complex): Complex {
return {
r: c1.r + c2.r,
i: c1.i + c2.i
};
}
function complexMul(c1: Complex, c2: Complex): Complex {
return {
r: c1.r * c2.r - c1.i * c2.i,
i: c1.r * c2.i + c1.i * c2.r,
};
}
function complexMag(z: Complex): number {
return Math.sqrt(z.i ** 2 + z.r ** 2);
}
type DrawOptions = {
zoom: number;
}
function draw(ctx: CanvasRenderingContext2D, options: DrawOptions) {
const width = ctx.canvas.width;
const height = ctx.canvas.height;
const buf = new Uint8ClampedArray(width * height * 4);
function coords(x: number, y: number): Complex {
return {
r: (x / width * 3 - 2) / options.zoom,
i: (y / height * 2 - 1 - options.zoom * 1) / options.zoom,
};
}
function check(z: Complex): number | null {
let num = complexZero;
for (let i = 0; i < 30; i++) {
num = complexAdd(z, complexMul(num, num));
if (complexMag(num) >= 2.0) {
return i;
}
}
return null;
}
for (let y = 0; y < ctx.canvas.height; y++) {
for (let x = 0; x < ctx.canvas.width; x++) {
const yes = check(coords(x+0.01, y+0.01));
if (yes === null) {
buf[4 * (y * width + x) + 0] = 0;
buf[4 * (y * width + x) + 1] = 0;
buf[4 * (y * width + x) + 2] = 0;
buf[4 * (y * width + x) + 3] = 255;
} else {
buf[4 * (y * width + x) + 0] = yes / 30 * 255;
buf[4 * (y * width + x) + 1] = yes / 50 * 255;
buf[4 * (y * width + x) + 2] = yes / 15 * 255;
buf[4 * (y * width + x) + 3] = 255;
}
}
}
const imageData = new ImageData(buf, width, height);
ctx.putImageData(imageData, 0, 0);
requestAnimationFrame(() => draw(ctx, {
zoom: options.zoom > 357686241040.31244 ? 0.001 : options.zoom * 1.03,
}));
}
function main(canvasSize: number) {
const canvas = document.createElement('canvas');
canvas.width = canvasSize * 3;
canvas.height = canvasSize * 2;
const ctx = canvas.getContext('2d');
if (!ctx) return;
draw(ctx, {
zoom: 0.001,
});
document.body.appendChild(canvas);
}
document.addEventListener('DOMContentLoaded', () => main(100));