-
Notifications
You must be signed in to change notification settings - Fork 0
/
Points.tsx
118 lines (102 loc) · 3.13 KB
/
Points.tsx
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
import { useEffect, useRef } from 'react';
import { Tucunare, mat4, vec4, randomFloat } from 'tucunare';
import { MAX_CANVAS_SIZE } from '../constants';
export const Points = () => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
if (!canvasRef.current) {
return;
}
const canvas = canvasRef.current;
const context = canvas.getContext('2d');
if (!context) {
return;
}
const resizeCanvas = () => {
canvas.width =
window.innerWidth < MAX_CANVAS_SIZE
? window.innerWidth
: MAX_CANVAS_SIZE;
canvas.height =
window.innerHeight < MAX_CANVAS_SIZE
? window.innerHeight
: MAX_CANVAS_SIZE;
};
resizeCanvas();
const tc = new Tucunare(canvas);
tc.setClearColor(0, 0, 0, 1);
let projectionMatrix: mat4;
const camera = new vec4(0, 0, 100, 1);
const viewMatrix = mat4.translate(-camera.x, -camera.y, -camera.z);
let innerRotation = 0;
let outerRotation = 0;
const windowResized = () => {
resizeCanvas();
tc.resize();
projectionMatrix = mat4.perspectiveAspectRatio(
canvas.width / canvas.height,
75,
0.1,
1000,
);
};
window.onresize = windowResized;
windowResized();
const inner: vec4[] = [];
const outer: vec4[] = [];
const outerRadius = 50;
const innerRadius = 20;
const numInnerPoints = 200;
const numOuterPoints = 1000;
const totalPoints = numInnerPoints + numOuterPoints;
const innerColor = new vec4(1, 1, 1, 1);
const outerColor = new vec4(1, 0, 0, 1);
for (let i = 0; i < totalPoints; i++) {
let radius: number;
let points: vec4[];
if (i < numInnerPoints) {
radius = innerRadius;
points = inner;
} else {
radius = outerRadius;
points = outer;
}
let point = new vec4(0, 0, radius, 1);
point = mat4.rotateX(randomFloat(0, 360)).multiplyVec4(point);
point = mat4.rotateY(randomFloat(0, 360)).multiplyVec4(point);
point = mat4.rotateZ(randomFloat(0, 360)).multiplyVec4(point);
points.push(point);
}
const draw = () => {
tc.clear();
const mvMatrix = projectionMatrix.multiply(viewMatrix);
const mvpOuter = mvMatrix.multiply(mat4.rotateY(outerRotation));
const mvpInner = mvMatrix.multiply(mat4.rotateY(innerRotation));
// draw outer points
tc.drawPoints(
{ point: outer },
(input) => ({
position: mvpOuter.multiplyVec4(input.point as vec4),
outputs: {},
}),
() => outerColor,
);
// draw inner points
tc.drawPoints(
{ point: inner },
(input) => ({
position: mvpInner.multiplyVec4(input.point as vec4),
outputs: {},
}),
() => innerColor,
);
// flush the buffer to the canvas
tc.flush();
outerRotation = (outerRotation + 0.1) % 360;
innerRotation = (innerRotation + 1) % 360;
};
const interval = setInterval(draw, 1000 / 60);
return () => clearInterval(interval);
}, []);
return <canvas ref={canvasRef}></canvas>;
};