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);