-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLines.tsx
110 lines (95 loc) · 2.9 KB
/
Lines.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
import { useEffect, useRef } from 'react';
import { Tucunare, mat4, vec4 } from 'tucunare';
import { MAX_CANVAS_SIZE } from '../constants';
export const Lines = () => {
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, 10, 1);
const viewMatrix = mat4.translate(-camera.x, -camera.y, -camera.z);
let rotation = 0;
const windowResized = () => {
resizeCanvas();
tc.resize();
projectionMatrix = mat4.perspectiveAspectRatio(
canvas.width / canvas.height,
75,
0.1,
1000,
);
};
window.onresize = windowResized;
windowResized();
const points: vec4[] = [];
const colors: vec4[] = [];
const height = 10;
const numSegments = 64;
const startColor = new vec4(1, 0, 0, 1);
const endColor = new vec4(0, 0.8, 1, 1);
const current = {
point: new vec4(1, -height / 2, 0, 1),
color: new vec4(),
};
let previousPoint: vec4 | undefined;
let previousColor: vec4 | undefined;
for (let i = 0; i < numSegments; i++) {
current.point = mat4.rotateY(360 / 16).multiplyVec4(current.point);
current.point = mat4
.translate(0, height / numSegments, 0)
.multiplyVec4(current.point);
current.color = startColor.copy().lerp(endColor, i / numSegments);
if (previousPoint && previousColor) {
points.push(previousPoint, current.point);
colors.push(previousColor, current.color);
}
previousPoint = current.point;
previousColor = current.color;
}
const draw = () => {
tc.clear();
const modelMatrix = mat4
.rotateY(rotation)
.multiply(mat4.rotateX(rotation));
const mvp = projectionMatrix.multiply(viewMatrix.multiply(modelMatrix));
tc.drawLines(
{ point: points, color: colors },
(inputs) => {
return {
position: mvp.multiplyVec4(inputs.point as vec4),
outputs: {
color: inputs.color,
},
};
},
(inputs) => inputs.color as vec4,
);
// flush the buffer to the canvas
tc.flush();
rotation = (rotation + 0.5) % 360;
};
const interval = setInterval(draw, 1000 / 60);
return () => clearInterval(interval);
}, []);
return <canvas ref={canvasRef}></canvas>;
};