3 const kEntrypoint
= "breadsticks";
5 const kDrawDelay
= 100;
6 const kDarkDrawingColor
= '#fff';
7 const kLightDrawingColor
= '#000';
9 /***********************************************
10 * Breadstick generates a matrix of points
11 * and assigns a vector to each entry
13 ***********************************************/
16 * Generate field of points in which to draw
19 // Updates the field object using a canvas
21 const updateFieldFromCanvas
= (field
, canvas
) => {
22 updateFieldFromRect(field
, canvas
.getBoundingClientRect());
24 canvas
.width
= window
.innerWidth
;
25 canvas
.height
= window
.innerHeight
;
27 window
.addEventListener('resize', () => {
28 canvas
.width
= window
.innerWidth
;
29 canvas
.height
= window
.innerHeight
;
30 updateFieldFromRect(field
, canvas
.getBoundingClientRect());
34 // Updates a field object using a rect
36 const updateFieldFromRect
= (field
, rect
) => {
37 field
.width
= rect
.width
;
38 field
.height
= rect
.height
;
42 * Generate the matrix of vectors
45 // Updates a matrix for a given field using the mouse
48 const updateFieldMatrixFromMouse
= (field
, matrix
, gap
= 50) => {
49 const mousePosition
= {
54 fillMatrix(matrix
, mousePosition
.x
, mousePosition
.y
, field
.width
, field
.height
, gap
);
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
);
63 // Gets a matrix by calculating the offset between position and field.
65 const fillMatrix
= (matrix
, x
, y
, w
, h
, gap
= 50) => {
66 for (let i
= 0; i
< w
/ gap
; ++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
);
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
;
86 angle: Math
.atan2(xOffset
, yOffset
),
87 magnitude: Math
.sqrt(Math
.pow(xOffset
, 2) + Math
.pow(yOffset
, 2))
96 // draw a vector from center
97 const drawVector
= (context
, i
, j
, vector
) => {
99 x: context
.canvas
.width
/ 2,
100 y: context
.canvas
.height
/ 2
102 const x
= origin
.x
- vector
.magnitude
* Math
.cos(vector
.angle
);
103 const y
= origin
.y
- vector
.magnitude
* Math
.sin(vector
.angle
);
105 context
.moveTo(vector
.position
.x
, vector
.position
.y
);
106 context
.lineTo(Math
.round(x
), Math
.round(y
));
110 // Gets the color depending on the team
112 const getColor
= () => {
113 if (window
.matchMedia('(prefers-color-scheme: dark)').matches
) {
114 return kDarkDrawingColor
;
117 return kLightDrawingColor
;
121 // Draws field on canvas
123 const drawFieldMatrixOnCanvas
= (matrix
, context
) => {
125 context
.strokeStyle
= getColor();
126 context
.clearRect(0, 0, context
.canvas
.width
, context
.canvas
.height
);
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
]
134 drawVector(context
, i
, j
, vector
);
150 const canvas
= document
.getElementById(kEntrypoint
);
152 updateFieldFromCanvas(field
, canvas
);
155 updateFieldMatrixFromMouse(field
, matrix
, kGap
);
157 const context
= canvas
.getContext('2d');
158 const drawFunction
= () => {
159 drawFieldMatrixOnCanvas(matrix
, context
);
160 setTimeout(drawFunction
, kDrawDelay
);
163 setTimeout(drawFunction
, 0);
166 window
.addEventListener('load', run
);