/ frontend / src / canvas_old.html
canvas_old.html
  1  <!DOCTYPE html>
  2  <html lang="en">
  3    <head>
  4      <meta charset="UTF-8" />
  5      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6      <title>Canvas Pixel Setter with putImageData</title>
  7      <script
  8        src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.7.7/axios.min.js"
  9        integrity="sha512-DdX/YwF5e41Ok+AI81HI8f5/5UsoxCVT9GKYZRIzpLxb8Twz4ZwPPX+jQMwMhNQ9b5+zDEefc+dcvQoPWGNZ3g=="
 10        crossorigin="anonymous"
 11        referrerpolicy="no-referrer"
 12      ></script>
 13      <style>
 14        #myCanvas {
 15          image-rendering: pixelated;
 16        }
 17      </style>
 18    </head>
 19    <body>
 20      <canvas
 21        id="myCanvas"
 22        width="1000"
 23        height="1000"
 24        style="border: 1px solid #000000"
 25      ></canvas>
 26  
 27      <script>
 28        // Get the canvas element and its 2D rendering context
 29        const canvas = document.getElementById("myCanvas");
 30  
 31        /*
 32        let width = (Math.random() * 300) + 700;
 33        let height = 1000000 / width;
 34        let remain = (1000000 % width) > 0;
 35        if (remain) {
 36          height += 1;
 37        }
 38        */
 39        const ctx = canvas.getContext("2d", (willReadFrequently = true));
 40  
 41        // Function to set a pixel at (x, y) with the specified color using putImageData
 42  
 43        function setPixel(x, y, color) {
 44          // Create an ImageData object with a single pixel
 45          const imgData = ctx.createImageData(1, 1);
 46          const data = imgData.data;
 47  
 48          // Parse the color string and set the pixel data
 49          // Assuming color is in the format '#RRGGBB'
 50          const r = parseInt(color.slice(1, 3), 16);
 51          const g = parseInt(color.slice(3, 5), 16);
 52          const b = parseInt(color.slice(5, 7), 16);
 53          const a = 255; // Fully opaque
 54  
 55          // Set the pixel color (R, G, B, A)
 56          data[0] = r;
 57          data[1] = g;
 58          data[2] = b;
 59          data[3] = a;
 60  
 61          // Put the ImageData object onto the canvas at (x, y)
 62          ctx.putImageData(imgData, x, y);
 63        }
 64  
 65        function setPixelAtIndex(index, color) {
 66          const imageData = ctx.getImageData(0, 0, 1000, 1000);
 67          const data = imageData.data;
 68  
 69          let realIndex = index * 4;
 70  
 71          const r = parseInt(color.slice(1, 3), 16);
 72          const g = parseInt(color.slice(3, 5), 16);
 73          const b = parseInt(color.slice(5, 7), 16);
 74          const a = 255; // Fully opaque
 75  
 76          // Set the pixel color (R, G, B, A)
 77          data[realIndex] = r;
 78          data[realIndex + 1] = g;
 79          data[realIndex + 2] = b;
 80          data[realIndex + 3] = a;
 81  
 82          ctx.putImageData(imageData, 0, 0);
 83        }
 84  
 85        // Example usage
 86  
 87        /*
 88        for (let index = 0; index < 500; index++) {
 89          setPixel(500, index, "#AABB00");
 90        }
 91        setPixel(500, 500, "#FF0000"); // Set pixel at (500, 500) to red
 92        setPixel(100, 100, "#00FF00"); // Set pixel at (100, 100) to green
 93        setPixel(900, 900, "#0000FF"); // Set pixel at (900, 900) to blue
 94        */
 95  
 96        function handleCanvasClick(event) {
 97          // Get the bounding rectangle of the canvas
 98          const rect = canvas.getBoundingClientRect();
 99          // Calculate the coordinates of the click relative to the canvas
100          const x = event.clientX - rect.left;
101          const y = event.clientY - rect.top;
102  
103          // Log the coordinates to the console
104          //console.log("Clicked at:", x, y);
105  
106          let index = (y * 1000 + x).toString();
107          //console.log(index);
108          axios.post("/set/" + index).then((d) => {
109            let color;
110            if (d.data == "1") {
111              color = "#000000";
112            } else {
113              color = "#00ff00";
114            }
115  
116            setPixel(x, y, color);
117          });
118  
119          // Example: Set the pixel at the clicked location to black
120        }
121  
122        canvas.addEventListener("click", handleCanvasClick);
123  
124        //loadCanvas();
125        /*
126        axios.post("/set/0").then(() => {
127            //setPixel(x, y, "#000000");
128        });
129        */
130  
131        function loadCanvas() {
132          axios.get("/grid").then(function (response) {
133            // handle success
134            //console.log(response);
135            let data = base64ToArrayBuffer(response.data);
136            //console.log(data);
137            loadInitialCanvasData(data);
138          });
139        }
140  
141        function base64ToArrayBuffer(base64) {
142          var binaryString = atob(base64);
143          var bytes = new Uint8Array(binaryString.length);
144          for (var i = 0; i < binaryString.length; i++) {
145            bytes[i] = binaryString.charCodeAt(i);
146          }
147          return bytes.buffer;
148        }
149  
150        function loadInitialCanvasData(inputData) {
151          let setCount = 0;
152          const imgData = ctx.createImageData(1000, 1000);
153          let byteInputData = new Uint8Array(inputData);
154          const data = imgData.data;
155          let bit_index = 0;
156          let byte_index = 0;
157          for (let i = 0; i < byteInputData.length * 8; i++) {
158            bit_index = i % 8;
159            byte_index = Math.floor(i / 8);
160            let byte_value = byteInputData[byte_index];
161            let is_set = is_bit_set(byte_value, bit_index);
162            let color;
163            if (is_set) {
164              //console.log("Found set", byte_index, bit_index);
165              setCount += 1;
166              color = 0;
167              data[i * 4] = 255; //r
168              data[i * 4 + 1] = 0; //g
169              data[i * 4 + 2] = 0; //b
170            } else {
171              color = 255;
172              data[i * 4] = 255; //r
173              data[i * 4 + 1] = 255; //g
174              data[i * 4 + 2] = 255; //b
175            }
176            data[i * 4 + 3] = 255; //a
177          }
178          //console.log(bit_index);
179          ctx.putImageData(imgData, 0, 0);
180  
181          console.log(`${setCount} pixels set`);
182        }
183  
184        function is_bit_set(byte_value, bit_index) {
185          let mask = 1 << bit_index;
186          return (byte_value & mask) != 0;
187        }
188  
189        let socket = null;
190        function ws() {
191          socket = new WebSocket("/ws");
192          console.log("Connecting");
193  
194          socket.onmessage = (event) => {
195            //console.log(`[message] Данные получены с сервера: ${event.data}`);
196            let data = event.data;
197            data = JSON.parse(data);
198            data.on.forEach((index) => {
199              color = "#ff0000";
200              let y = Math.floor(index / 1000);
201              let x = index % 1000;
202              setPixel(x, y, color);
203            });
204            data.off.forEach((index) => {
205              color = "#ffffff";
206              let y = Math.floor(index / 1000);
207              let x = index % 1000;
208              setPixel(x, y, color);
209            });
210          };
211  
212          socket.onopen = (e) => {
213            console.log("[open] Соединение установлено");
214            loadCanvas();
215          };
216  
217          socket.onclose = (event) => {
218            if (event.wasClean) {
219              console.log(
220                `[close] Соединение закрыто чисто, код=${event.code} причина=${event.reason}`
221              );
222            } else {
223              // например, сервер убил процесс или сеть недоступна
224              // обычно в этом случае event.code 1006
225              console.log("[close] Соединение прервано");
226            }
227          };
228  
229          socket.onerror = (error) => {
230            console.log(`[error]`, error);
231          };
232        }
233  
234        ws();
235      </script>
236    </body>
237  </html>