]> git.r.bdr.sh - rbdr/r.bdr.sh/blob - jekyll/js/breadsticks.js
2675c0ce0dcb12660f02214c3cde37adaf292296
[rbdr/r.bdr.sh] / jekyll / js / breadsticks.js
1 // App Config
2
3 const kEntrypoint = "breadsticks";
4 const kGap = 50;
5 const kDrawDelay = 100;
6 const kDarkDrawingColor = '#fff';
7 const kLightDrawingColor = '#000';
8
9 /***********************************************
10 * Breadstick generates a matrix of points
11 * and assigns a vector to each entry
12 * and then draws them
13 ***********************************************/
14
15 /*
16 * Generate field of points in which to draw
17 */
18
19 // Updates the field object using a canvas
20
21 const updateFieldFromCanvas = (field, canvas) => {
22 updateFieldFromRect(field, canvas.getBoundingClientRect());
23
24 canvas.width = window.innerWidth;
25 canvas.height = window.innerHeight;
26
27 window.addEventListener('resize', () => {
28 canvas.width = window.innerWidth;
29 canvas.height = window.innerHeight;
30 updateFieldFromRect(field, canvas.getBoundingClientRect());
31 });
32 };
33
34 // Updates a field object using a rect
35
36 const updateFieldFromRect = (field, rect) => {
37 field.width = rect.width;
38 field.height = rect.height;
39 }
40
41 /*
42 * Generate the matrix of vectors
43 */
44
45 // Updates a matrix for a given field using the mouse
46
47
48 const updateFieldMatrixFromMouse = (field, matrix, gap = 50) => {
49 const mousePosition = {
50 x: 0,
51 y: 0
52 };
53
54 fillMatrix(matrix, mousePosition.x, mousePosition.y, field.width, field.height, gap);
55
56 const updateMousePosition = document.addEventListener('mousemove', (event) => {
57 mousePosition.x = event.offsetX;
58 mousePosition.y = event.offsetY;
59 fillMatrix(matrix, mousePosition.x, mousePosition.y, field.width, field.height, gap);
60 });
61 };
62
63 // Gets a matrix by calculating the offset between position and field.
64
65 const fillMatrix = (matrix, x, y, w, h, gap = 50) => {
66 for (let i = 0; i < w / gap; ++i) {
67 matrix[i] = [];
68 for (let j = 0; j < h / gap; ++j) {
69 let targetX = i * gap;
70 let targetY = j * gap;
71 matrix[i][j] = calculateOffsetVector(x, y, targetX, targetY, w, h);
72 }
73 }
74 };
75
76 // Calculates the offset vector of a point
77 const calculateOffsetVector = (sourceX, sourceY, targetX, targetY, w, h) => {
78 const xOffset = targetX - sourceX;
79 const yOffset = targetY - sourceY;
80
81 return {
82 position: {
83 x: targetX,
84 y: targetY
85 },
86 angle: Math.atan2(xOffset, yOffset),
87 magnitude: Math.sqrt(Math.pow(xOffset, 2) + Math.pow(yOffset, 2))
88 };
89 };
90
91
92 /*
93 * Drawing
94 */
95
96 // draw a vector from center
97 const drawVector = (context, i, j, vector) => {
98 const origin = {
99 x: context.canvas.width / 2,
100 y: context.canvas.height / 2
101 };
102 const x = origin.x - vector.magnitude * Math.cos(vector.angle);
103 const y = origin.y - vector.magnitude * Math.sin(vector.angle);
104 context.beginPath();
105 context.moveTo(vector.position.x, vector.position.y);
106 context.lineTo(Math.round(x), Math.round(y));
107 context.stroke();
108 };
109
110 // Gets the color depending on the team
111
112 const getColor = () => {
113 if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
114 return kDarkDrawingColor;
115 }
116
117 return kLightDrawingColor;
118 };
119
120
121 // Draws field on canvas
122
123 const drawFieldMatrixOnCanvas = (matrix, context) => {
124
125 context.strokeStyle = getColor();
126 context.clearRect(0, 0, context.canvas.width, context.canvas.height);
127
128 for (let i = 0; i < matrix.length; ++i) {
129 const row = matrix[i];
130 for (let j = 0; j < row.length; ++j) {
131 const vector = row[j]
132
133 if (vector) {
134 drawVector(context, i, j, vector);
135 }
136 }
137 }
138 };
139
140 /*
141 * Entrypoint
142 */
143
144 const run = () => {
145
146 const field = {
147 width: 0,
148 height: 0
149 };
150 const canvas = document.getElementById(kEntrypoint);
151
152 updateFieldFromCanvas(field, canvas);
153
154 const matrix = [[]];
155 updateFieldMatrixFromMouse(field, matrix, kGap);
156
157 const context = canvas.getContext('2d');
158 const drawFunction = () => {
159 drawFieldMatrixOnCanvas(matrix, context);
160 setTimeout(drawFunction, kDrawDelay);
161 }
162
163 setTimeout(drawFunction, 0);
164 };
165
166 window.addEventListener('load', run);