/ examples / server / static / led_color_picker_example.js
led_color_picker_example.js
  1  // SPDX-FileCopyrightText: 2019 ladyada for Adafruit Industries
  2  //
  3  // SPDX-License-Identifier: MIT
  4  
  5  let canvas = document.getElementById('colorPicker');
  6  let ctx = canvas.getContext("2d");
  7  ctx.width = 300;
  8  ctx.height = 300;
  9  
 10  function drawColorPicker() {
 11      /**
 12       * Color picker inspired by:
 13       * https://medium.com/@bantic/hand-coding-a-color-wheel-with-canvas-78256c9d7d43
 14       */
 15      let radius = 150;
 16      let image = ctx.createImageData(2*radius, 2*radius);
 17      let data = image.data;
 18  
 19      for (let x = -radius; x < radius; x++) {
 20          for (let y = -radius; y < radius; y++) {
 21  
 22          let [r, phi] = xy2polar(x, y);
 23  
 24          if (r > radius) {
 25              // skip all (x,y) coordinates that are outside of the circle
 26              continue;
 27          }
 28  
 29          let deg = rad2deg(phi);
 30  
 31          // Figure out the starting index of this pixel in the image data array.
 32          let rowLength = 2*radius;
 33          let adjustedX = x + radius; // convert x from [-50, 50] to [0, 100] (the coordinates of the image data array)
 34          let adjustedY = y + radius; // convert y from [-50, 50] to [0, 100] (the coordinates of the image data array)
 35          let pixelWidth = 4; // each pixel requires 4 slots in the data array
 36          let index = (adjustedX + (adjustedY * rowLength)) * pixelWidth;
 37  
 38          let hue = deg;
 39          let saturation = r / radius;
 40          let value = 1.0;
 41  
 42          let [red, green, blue] = hsv2rgb(hue, saturation, value);
 43          let alpha = 255;
 44  
 45          data[index] = red;
 46          data[index+1] = green;
 47          data[index+2] = blue;
 48          data[index+3] = alpha;
 49          }
 50      }
 51  
 52      ctx.putImageData(image, 0, 0);
 53  }
 54  
 55  function xy2polar(x, y) {
 56      let r = Math.sqrt(x*x + y*y);
 57      let phi = Math.atan2(y, x);
 58      return [r, phi];
 59  }
 60  
 61  // rad in [-π, π] range
 62  // return degree in [0, 360] range
 63  function rad2deg(rad) {
 64      return ((rad + Math.PI) / (2 * Math.PI)) * 360;
 65  }
 66  
 67    // hue in range [0, 360]
 68    // saturation, value in range [0,1]
 69    // return [r,g,b] each in range [0,255]
 70    // See: https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
 71  function hsv2rgb(hue, saturation, value) {
 72      let chroma = value * saturation;
 73      let hue1 = hue / 60;
 74      let x = chroma * (1- Math.abs((hue1 % 2) - 1));
 75      let r1, g1, b1;
 76      if (hue1 >= 0 && hue1 <= 1) {
 77          ([r1, g1, b1] = [chroma, x, 0]);
 78      } else if (hue1 >= 1 && hue1 <= 2) {
 79          ([r1, g1, b1] = [x, chroma, 0]);
 80      } else if (hue1 >= 2 && hue1 <= 3) {
 81          ([r1, g1, b1] = [0, chroma, x]);
 82      } else if (hue1 >= 3 && hue1 <= 4) {
 83          ([r1, g1, b1] = [0, x, chroma]);
 84      } else if (hue1 >= 4 && hue1 <= 5) {
 85          ([r1, g1, b1] = [x, 0, chroma]);
 86      } else if (hue1 >= 5 && hue1 <= 6) {
 87          ([r1, g1, b1] = [chroma, 0, x]);
 88      }
 89  
 90      let m = value - chroma;
 91      let [r,g,b] = [r1+m, g1+m, b1+m];
 92  
 93      // Change r,g,b values from [0,1] to [0,255]
 94      return [255*r,255*g,255*b];
 95  }
 96  
 97  function onColorPick(event) {
 98      coords = getCursorPosition(canvas, event)
 99      imageData = ctx.getImageData(coords[0],coords[1],1,1)
100      rgbObject = {
101          r: imageData.data[0],
102          g: imageData.data[1],
103          b: imageData.data[2]
104      }
105      console.log(`r: ${rgbObject.r} g: ${rgbObject.g} b: ${rgbObject.b}`);
106      data = JSON.stringify(rgbObject);
107      window.fetch("/ajax/ledcolor", {
108          method: "POST",
109          body: data,
110          headers: {
111              'Content-Type': 'application/json; charset=utf-8',
112          },
113      }).then(response => {
114          console.log("sucess!: " + response)
115      }, error => {
116          console.log("error!: " + error)
117      })
118  }
119  
120  function getCursorPosition(canvas, event) {
121      const rect = canvas.getBoundingClientRect()
122      const x = event.clientX - rect.left
123      const y = event.clientY - rect.top
124      console.log("x: " + x + " y: " + y)
125      return [x,y]
126  }
127  
128  drawColorPicker();
129  canvas.addEventListener('mousedown', onColorPick);