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