V3.0.0.BETA1

* Version Bump to 3.0.0.BETA1
 * further code changes
 * bugfixes
This commit is contained in:
bpohvoodoo
2019-09-29 13:27:37 +02:00
parent 2adc6707df
commit 341c469b49
29 changed files with 339 additions and 2468 deletions
-6
View File
@@ -1,6 +0,0 @@
[submodule "Arduino/McLighting/data/McLightingUI"]
path = Arduino/McLighting/data/McLightingUI
url = https://github.com/toblum/McLightingUI
[submodule "clients/web/McLightingUI"]
path = clients/web/McLightingUI
url = https://github.com/toblum/McLightingUI
+25 -25
View File
@@ -671,8 +671,6 @@ void setup() {
#if defined(ENABLE_REMOTE)
irrecv.enableIRIn(); // Start the receiver
#endif
snprintf(last_state, sizeof(last_state), "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", mode, ws2812fx_mode, ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue, main_color.white, back_color.red, back_color.green, back_color.blue, back_color.white, xtra_color.red, xtra_color.green, xtra_color.blue,xtra_color.white);
last_state[sizeof(last_state)]= 0x00;
ws2812fx_speed_actual = ws2812fx_speed;
brightness_trans = brightness;
memcpy(hex_colors, hex_colors_trans, sizeof(hex_colors_trans));
@@ -777,6 +775,7 @@ void loop() {
if (mode == SET) {
mode = HOLD;
// Mode
if (ws2812fx_mode != strip->getMode(selected_segment)) { // SET_MODE
#if defined(ENABLE_MQTT)
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK /%i", ws2812fx_mode);
@@ -786,39 +785,33 @@ void loop() {
autoDelay = 0;
strip->setMode(selected_segment, ws2812fx_mode);
}
//Color
/*if (memcmp(hex_colors_trans, strip->getColors(selected_segment), sizeof(hex_colors_trans)) != 0) {
}*/
// Brightness
if (strip->getBrightness() != brightness) {
#if defined(ENABLE_MQTT)
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK %%%i", brightness);
#endif
brightness_trans = brightness;
}
prevmode = SET;
strip->trigger();
}
/*if (mode == SET) {
mode = HOLD;
if (trans_cnt==0) { trans_cnt=1; }
if (!transEffect) { trans_cnt=255; }
convertColorsFade();
prevmode = SET;
}*/
if (mode == SET_SPEED) {
// Speed
if (ws2812fx_speed_actual != ws2812fx_speed) {
#if defined(ENABLE_MQTT)
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK ?%i", ws2812fx_speed);
#endif
mode = prevmode;
prevmode = SET_SPEED;
}
prevmode = SET;
strip->trigger();
}
if (prevmode != mode) {
convertColors();
if (memcmp(hex_colors_trans, strip->getColors(selected_segment), sizeof(hex_colors_trans)) != 0) {
DBG_OUTPUT_PORT.println("Colors not equal!");
if (trans_cnt==0) { trans_cnt=1; }
if (!transEffect) { trans_cnt=255; }
convertColorsFade();
trans_cnt = 1;
}
strip->setSpeed(selected_segment, convertSpeed(ws2812fx_speed_actual));
//strip->setBrightness(brightness_actual);
@@ -873,7 +866,7 @@ void loop() {
}
#endif
if ((mode == HOLD) || ((mode == OFF) && ((strip->getBrightness() == 0) || !transEffect))) {
if ((mode == HOLD) || ((mode == OFF) && (strip->getBrightness() > 0) && transEffect)) {
if (ws2812fx_mode == FX_MODE_CUSTOM_0) {
handleAutoPlay();
}
@@ -882,9 +875,11 @@ void loop() {
}
// Async color transition
if ((trans_cnt > 0) && (trans_cnt < 255)) {
if (memcmp(hex_colors_trans, strip->getColors(selected_segment), sizeof(hex_colors_trans)) != 0) {
if (transEffect) {
if ((trans_cnt > 0) && (trans_cnt < trans_cnt_max)) {
if (colorFadeDelay <= millis()) {
uint32_t hex_colors_actual[3] = {};
if ((transEffect) && (colorFadeDelay <= millis())) {
hex_colors_actual[0] = trans(hex_colors_trans[0], hex_colors[0], trans_cnt);
hex_colors_actual[1] = trans(hex_colors_trans[1], hex_colors[1], trans_cnt);
hex_colors_actual[2] = trans(hex_colors_trans[2], hex_colors[2], trans_cnt);
@@ -893,15 +888,20 @@ void loop() {
colorFadeDelay = millis() + TRANS_COLOR_DELAY;
if (mode == HOLD) strip->trigger();
}
}
if (trans_cnt > 254) {
} else if (trans_cnt >= trans_cnt_max) {
memcpy(hex_colors, hex_colors_trans, sizeof(hex_colors_trans));
strip->setColors(selected_segment, hex_colors);
if (mode == HOLD) strip->trigger();
trans_cnt = 0;
DBG_OUTPUT_PORT.println("Color transition finished!");
}
} else {
memcpy(hex_colors, hex_colors_trans, sizeof(hex_colors_trans));
strip->setColors(selected_segment, hex_colors);
if (mode == HOLD) strip->trigger();
trans_cnt = 0;
}
}
// Async speed transition
if (ws2812fx_speed_actual != ws2812fx_speed) {
if (transEffect) {
+4 -3
View File
@@ -21,11 +21,11 @@ char HOSTNAME[65] = "McLightingRGBW"; // Friedly hostname is configurable just
#define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT must be active
#define MQTT_HOME_ASSISTANT_SUPPORT // If defined, use AMQTT and select Tools -> IwIP Variant -> Higher Bandwidth
#define ENABLE_BUTTON 14 // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control, the value defines the input pin (14 / D5) for switching the LED strip on / off, connect this PIN to ground to trigger button.
#define ENABLE_BUTTON_GY33 12 // If defined, enable button handling code for GY-33 color sensor to scan color. The value defines the input pin (12 / D6) for read color data with RGB sensor, connect this PIN to ground to trigger button.
//#define ENABLE_BUTTON_GY33 12 // If defined, enable button handling code for GY-33 color sensor to scan color. The value defines the input pin (12 / D6) for read color data with RGB sensor, connect this PIN to ground to trigger button.
#if defined(ENABLE_BUTTON_GY33)
#define GAMMA 2.5 // Gamma correction for GY-33 sensor
#endif
//#define ENABLE_REMOTE 13 // If defined, enable Remote Control via TSOP31238. The value defines the input pin (13 / D7) for TSOP31238 Out
#define ENABLE_REMOTE 13 // If defined, enable Remote Control via TSOP31238. The value defines the input pin (13 / D7) for TSOP31238 Out
#define ENABLE_STATE_SAVE 1 // If defined, load saved state on reboot and save state. If set to 0 from EEPROM, if set to 1 from SPIFFS
@@ -38,6 +38,7 @@ char HOSTNAME[65] = "McLightingRGBW"; // Friedly hostname is configurable just
bool transEffect = false; // Experimental: Enable transitions of color, brightness and speed. It does not work properly for all effects.
bool transEffectOverride = false;
uint8_t trans_cnt = 0;
int trans_cnt_max = 0;
unsigned long colorFadeDelay = 0;
unsigned long brightnessFadeDelay = 0;
unsigned long speedFadeDelay = 0;
@@ -140,7 +141,7 @@ uint32_t autoParams[][6] = { // main_color, back_color, xtra_color, speed, mod
#define DBG_OUTPUT_PORT Serial // Set debug output port
// List of all color modes
enum MODE {OFF, HOLD, SET, SET_SPEED, INIT_STRIP};
enum MODE {OFF, HOLD, SET, INIT_STRIP};
MODE mode = SET; // Standard mode that is active when software starts
MODE prevmode = HOLD; // Do not change
@@ -150,7 +150,6 @@ void handleE131(){
}
}
#include <FastLED.h> //https://github.com/FastLED/FastLED
/*
* paste in the Fire2012 code with a small edit at the end which uses the
+47 -49
View File
@@ -17,38 +17,33 @@ void convertColors() {
hex_colors_trans[2] = (uint32_t)(xtra_color.white << 24) | (xtra_color.red << 16) | (xtra_color.green << 8) | xtra_color.blue;
}
void convertColorsFade() {
if ((transEffect) && (trans_cnt > 1) && (trans_cnt < 254)) {
memcpy(hex_colors, strip->getColors(selected_segment), sizeof(strip->getColors(selected_segment)));
DBG_OUTPUT_PORT.println("Color transistion aborted. Restarting...!");
trans_cnt = 1;
} else {
//memcpy(hex_colors, hex_colors_trans, sizeof(hex_colors_trans));
}
}
uint8_t calculateColorTransitionSteps () {
void calculateColorTransitionSteps() {
//compare all colors and calculate steps
int trans_cnt_max = 0;
trans_cnt_max = 0;
int calculate_max[4] = {};
for (uint8_t i=0; i<3; i++){
DBG_OUTPUT_PORT.printf("i: %i\r\n", i);
for (uint8_t j=0; j<4; j++) {
DBG_OUTPUT_PORT.printf("j: %i\r\n", j);
calculate_max[j] = ((hex_colors[i] >> ((3-j)*8)) & 0xFF) - ((hex_colors_trans[i] >> ((3-j)*8)) & 0xFF);
calculate_max[j] = abs(calculate_max[j]);
trans_cnt_max = max(trans_cnt_max, calculate_max[j]);
DBG_OUTPUT_PORT.printf("calcmax: %i %i\r\n", j, calculate_max[j]);
}
}
DBG_OUTPUT_PORT.printf("max: %i\r\n", trans_cnt_max);
return trans_cnt_max;
}
void convertColorsFade() {
if (transEffect) {
if (trans_cnt > 1) {
memcpy(hex_colors, strip->getColors(selected_segment), sizeof(hex_colors));
DBG_OUTPUT_PORT.println("Color transistion aborted. Restarting...!");
trans_cnt = 1;
}
calculateColorTransitionSteps();
}
}
void getArgs() {
if (mode == SET) {
//color wrgb
if (server.arg("rgb") != "") {
uint32_t rgb = (uint32_t) strtoul(server.arg("rgb").c_str(), NULL, 16);
main_color.white = ((rgb >> 24) & 0xFF);
@@ -121,16 +116,15 @@ void getArgs() {
xtra_color.green = constrain(xtra_color.green, 0, 255);
xtra_color.blue = constrain(xtra_color.blue, 0, 255);
xtra_color.white = constrain(xtra_color.white, 0, 255);
}
if (mode == SET || mode == SET_SPEED) {
// Speed
if ((server.arg("s") != "") && (server.arg("s").toInt() >= 0) && (server.arg("s").toInt() <= 255)) {
ws2812fx_speed = constrain(server.arg("s").toInt(), 0, 255);
}
}
if (mode == SET) {
//Mode
if ((server.arg("m") != "") && (server.arg("m").toInt() >= 0) && (server.arg("m").toInt() <= strip->getModeCount())) {
ws2812fx_mode = constrain(server.arg("m").toInt(), 0, strip->getModeCount() - 1);
}
// Brightness
if ((server.arg("c") != "") && (server.arg("c").toInt() >= 0) && (server.arg("c").toInt() <= 100)) {
brightness = constrain((int) server.arg("c").toInt() * 2.55, 0, 255);
} else if ((server.arg("p") != "") && (server.arg("p").toInt() >= 0) && (server.arg("p").toInt() <= 255)) {
@@ -204,9 +198,9 @@ void handleSetAllMode(uint8_t * mypayload) {
void handleSetSingleLED(uint8_t * mypayload, uint8_t firstChar = 0) {
// decode led index
char templed[3];
strncpy (templed, (const char *) &mypayload[firstChar], 2 );
templed[2] = 0x00;
char templed[5];
strncpy (templed, (const char *) &mypayload[firstChar], 4 );
templed[4] = 0x00;
uint8_t led = atoi(templed);
DBG_OUTPUT_PORT.printf("led value: [%i]. Entry threshold: <= [%i] (=> %s)\r\n", led, WS2812FXStripSettings.stripSize, mypayload );
@@ -215,10 +209,10 @@ void handleSetSingleLED(uint8_t * mypayload, uint8_t firstChar = 0) {
char greenhex[3];
char bluehex[3];
char whitehex[3];
strncpy (whitehex, (const char *) &mypayload[2 + firstChar], 2 );
strncpy (redhex, (const char *) &mypayload[4 + firstChar], 2 );
strncpy (greenhex, (const char *) &mypayload[6 + firstChar], 2 );
strncpy (bluehex, (const char *) &mypayload[8 + firstChar], 2 );
strncpy (whitehex, (const char *) &mypayload[4 + firstChar], 2 );
strncpy (redhex, (const char *) &mypayload[6 + firstChar], 2 );
strncpy (greenhex, (const char *) &mypayload[8 + firstChar], 2 );
strncpy (bluehex, (const char *) &mypayload[10 + firstChar], 2 );
whitehex[2] = 0x00;
redhex[2] = 0x00;
greenhex[2] = 0x00;
@@ -260,26 +254,26 @@ void handleSetDifferentColors(uint8_t * mypayload) {
void handleRangeDifferentColors(uint8_t * mypayload) {
uint8_t* nextCommand = 0;
nextCommand = (uint8_t*) strtok((char*) mypayload, "R");
// While there is a range to process R0110<00ff00>
// While there is a range to process R00010010<0000ff00>
while (nextCommand) {
// Loop for each LED.
char startled[4];
char endled[4];
char startled[5];
char endled[5];
char colorval[9];
strncpy ( startled, (const char *) &nextCommand[0], 2 );
startled[3] = 0x00;
strncpy ( endled, (const char *) &nextCommand[2], 2 );
endled[3] = 0x00;
strncpy ( colorval, (const char *) &nextCommand[4], 8 );
strncpy ( startled, (const char *) &nextCommand[0], 4 );
startled[4] = 0x00;
strncpy ( endled, (const char *) &nextCommand[4], 4 );
endled[4] = 0x00;
strncpy ( colorval, (const char *) &nextCommand[8], 8 );
colorval[8] = 0x00;
uint8_t rangebegin = atoi(startled);
uint8_t rangeend = atoi(endled);
DBG_OUTPUT_PORT.printf("Setting RANGE from [%i] to [%i] as color [%s]\r\n", rangebegin, rangeend, colorval);
while ( rangebegin <= rangeend ) {
char rangeData[11];
snprintf(rangeData, sizeof(rangeData), "%02d%s", rangebegin, colorval);
char rangeData[18];
snprintf(rangeData, sizeof(rangeData), "%04d%s", rangebegin, colorval);
rangeData[sizeof(rangeData) - 1] = 0x00;
// Set one LED
handleSetSingleLED((uint8_t*) rangeData, 0);
@@ -472,6 +466,9 @@ void handleSetWS2812FXMode(uint8_t * mypayload) {
if (strcmp((char *) &mypayload[1], "off") == 0) {
mode = OFF;
}
if (strcmp((char *) &mypayload[1], "on") == 0) {
mode = HOLD;
}
}
}
@@ -646,7 +643,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
if (payload[0] == '?') {
uint8_t d = (uint8_t) strtol((const char *) &payload[1], NULL, 10);
ws2812fx_speed = constrain(d, 0, 255);
mode = SET_SPEED;
mode = SET;
Dbg_Prefix(mqtt, num);
DBG_OUTPUT_PORT.printf("Set speed to: [%u]\r\n", ws2812fx_speed);
}
@@ -1059,7 +1056,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght
uint8_t json_speed = constrain((uint8_t) root["speed"], 0, 255);
if (json_speed != ws2812fx_speed) {
ws2812fx_speed = json_speed;
mode = SET_SPEED;
mode = SET;
}
}
@@ -1663,7 +1660,7 @@ void handleRemote() {
mode = OFF;
}
}
if ((mode != AUTO) && (mode != OFF)) {
if (mode == HOLD) {
if (results.value == rmt_commands[BRIGHTNESS_UP]) { //Brightness Up
last_remote_cmd = results.value;
if (brightness + chng <= 255) {
@@ -1678,24 +1675,23 @@ void handleRemote() {
mode = SET;
}
}
}
if ((mode !=AUTO) && (mode != OFF)) {
if ((ws2812fx_mode < 56) || (ws2812fx_mode > 57)) {
if (results.value == rmt_commands[SPEED_UP]) { //Speed Up
last_remote_cmd = results.value;
if (ws2812fx_speed + chng <= 255) {
ws2812fx_speed = ws2812fx_speed + chng;
mode = SET_SPEED;
mode = SET;
}
}
if (results.value == rmt_commands[SPEED_DOWN]) { //Speed down
last_remote_cmd = results.value;
if (ws2812fx_speed - chng >= 0) {
ws2812fx_speed = ws2812fx_speed - chng;
mode = SET_SPEED;
mode = SET;
}
}
}
if (mode == HOLD) {
if ((ws2812fx_mode < 56) || (ws2812fx_mode > 60)) {
if (results.value == rmt_commands[RED_UP]) { //Red Up
last_remote_cmd = results.value;
if (selected_color == 1) {
@@ -1759,7 +1755,7 @@ void handleRemote() {
}
}
}
if (results.value == rmt_commands[GREEN_DOWN]) { //green down
if (results.value == rmt_commands[GREEN_DOWN]) { //Green down
last_remote_cmd = results.value;
if (selected_color == 1) {
if (main_color.green - chng >= 0) {
@@ -1801,7 +1797,7 @@ void handleRemote() {
}
}
}
if (results.value == rmt_commands[BLUE_DOWN]) { //BLUE down
if (results.value == rmt_commands[BLUE_DOWN]) { //Blue down
last_remote_cmd = results.value;
if (selected_color == 1) {
if (main_color.blue - chng >= 0) {
@@ -1876,6 +1872,7 @@ void handleRemote() {
last_remote_cmd = 0;
selected_color = 3;
}
}
} // end of if HOLD
if (results.value == rmt_commands[MODE_UP]) { //Mode Up
last_remote_cmd = results.value;
@@ -1937,6 +1934,7 @@ uint32_t scale_wrgb(uint32_t wrgb, uint8_t level) {
}
uint32_t trans(uint32_t newcolor, uint32_t oldcolor, uint8_t level) {
level = (level * (255/trans_cnt_max));
newcolor = scale_wrgb(newcolor, level);
oldcolor = scale_wrgb(oldcolor, 255-level);
return newcolor + oldcolor;
+3
View File
@@ -184,4 +184,7 @@
* moved Custom Animation 'Gradients' to number 61
* REST-API changes (will be documented soon)
*
* 29 September 2019
* Version Bump to 3.0.0.BETA1
* further code changes
*/
+6 -1
View File
@@ -64,7 +64,12 @@ light:
- "Bicolor Chase"
- "Tricolor Chase"
- "ICU"
- "E131"
- "AutoPlay"
- "Custom WS"
- "TV"
- "E1.31"
- "Fire(2012)"
- "Gradient"
brightness: true
color_temp: true
rgb: true
+2 -2
View File
@@ -22,12 +22,12 @@
"brightness": {
"status": "http://<ESP_HOST>/get_brightness",
"url": "http://<ESP_HOST>/set_brightness?c=%s"
"url": "http://<ESP_HOST>/set?c=%s"
},
"color": {
"status": "http://<ESP_HOST>/get_color",
"url": "http://<ESP_HOST>/all?rgb=%s",
"url": "http://<ESP_HOST>/set?m=0?rgb=%s",
"brightness": true
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.
-4
View File
@@ -1,4 +0,0 @@
## Retired, use:
McLightingHTML from https://github.com/FabLab-Luenen/McLightingHTML
or set #define USE_HTML_MIN_GZ in definitions.h to use the integrated!
-491
View File
@@ -1,491 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<!--Import Google Icon Font-->
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" media="screen,projection" />
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<meta name="mobile-web-app-capable" content="yes">
<meta charset="utf-8"/>
<meta name="mobile-web-app-capable" content="yes">
<title>McLighting (RGBW) v2</title>
</head>
<body>
<nav class="blue light-blueXXX lighten-1XXX" role="navigation" id="mc-nav">
<div class="nav-wrapper container">
<a id="logo-container" href="#" class="brand-logo">McLighting (RGBW) v2</a>
<ul class="right hide-on-med-and-down">
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
</ul>
<ul id="nav-mobile" class="side-nav">
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
</ul>
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
</div>
</nav>
<div class="container mc_pane" id="pane0">
<div class="section">
<div class="row" id="mc-wsloader">
<div class="col">
<div class="preloader-wrapper active">
<div class="spinner-layer spinner-blue-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
</div>
</div>
<div class="row hide" id="mc-wserror">
<div class="col">
<div>Error on websocket connect.</div>
</div>
</div>
</div>
</div>
<div class="container mc_pane hide" id="pane1">
<div class="section">
<div class="row">
<div class="col s12 m6">
<div style="height: 330px; width: 330px;">
<canvas id="myCanvas" width="330" height="330" style="-webkit-user-select: none;-webkit-tap-highlight-color: rgba(0,0,0,0);-moz-user-select:none;"></canvas>
</div>
</div>
<div class="col s12 m6">
<div class="card-panel" id="status">
<div id="status_pos">pick a color</div>
<div id="status_color"></div>
</div>
</div>
<div class="col s12 m6">
<div class="right switch">Auto:<br>
<label>Off
<input id="autoSwitch" type="checkbox"><span class="lever"></span>On
</label>
</div>
</div>
</div>
</div>
</div>
<div class="container mc_pane hide" id="pane2">
<div class="section">
<div class="row">
<form class="col s12">
<div class="row">
<div class="input-field col s12 l4">
<label for="txt_red">Red</label><br/>
<p class="range-field"><input type="range" id="rng_red" min="0" max="255" class="update_colors" /></p>
</div>
<div class="input-field col s12 l4">
<label for="txt_green">Green</label><br/>
<p class="range-field"><input type="range" id="rng_green" min="0" max="255" class="update_colors" /></p>
</div>
<div class="input-field col s12 l4">
<label for="txt_blue">Blue</label><br/>
<p class="range-field"><input type="range" id="rng_blue" min="0" max="255" class="update_colors" /></p>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<label for="txt_white">White</label><br/>
<p class="range-field"><input type="range" id="rng_white" min="0" max="255" class="update_colors" /></p>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<label for="txt_delay">Speed</label><br/>
<p class="range-field"><input type="range" id="rng_delay" min="0" max="255" value="196" class="update_delay" /></p>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<label for="txt_delay">Brightness</label><br/>
<p class="range-field"><input type="range" id="rng_brightness" min="0" max="255" value="196" class="update_brightness" /></p>
</div>
</div>
</form>
</div>
<div class="row">
<div id="modes">
<div class="input-field col s12">
Loading animations...
</div>
</div>
</div>
</div>
</div>
<footer class="page-footer blue">
<div class="footer-copyright">
<div class="container">© 2017
<a class="grey-text text-lighten-4 right" href="https://github.com/toblum/McLighting">Project home</a>
</div>
</div>
</footer>
<style type="text/css">
.btn_grid {
margin: 7px 0;
}
</style>
<!--Import jQuery before materialize.js-->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script type="text/javascript">(function($){
$(function(){
// Settings
var host = window.location.hostname;
//host = "esp8266_02.local";
var ws_url = 'ws://' + host + ':81';
var connection;
var ws_waiting = 0;
// ******************************************************************
// Side navigation
// ******************************************************************
$('.button-collapse').sideNav();
// Navlinks
$('#mc-nav').on('click', '.mc-navlink', function(){
console.log("Navigate to pane: ", $(this).data("pane"));
showPane($(this).data("pane"));
});
function showPane(pane) {
$('.mc_pane').addClass('hide');
$('#' + pane).removeClass('hide');
$('.button-collapse').sideNav('hide');
//if (pane == "pane2") {
// setMainColor();
//}
}
// ******************************************************************
// init()
// ******************************************************************
function init() {
console.log("Connection websockets to:", ws_url);
connection = new WebSocket(ws_url, ['arduino']);
var mode = 0;
var ws2812fx_mode = 0;
$.getJSON("http://" + host + "/status", function(data) {
console.log("status", data);
mode = data.mode;
if (mode == "1") {
// set autoswitch $("#autoSwitch").val('checked');
}
ws2812fx_mode = data.ws2812fx_mode;
$("#rng_delay").val(data.speed);
$("#rng_brightness").val(data.brightness);
$("#rng_white").val(data.color[0]);
$("#rng_red").val(data.color[1]);
$("#rng_green").val(data.color[2]);
$("#rng_blue").val(data.color[3]);
var statusColor = "#" + componentToHex(data.color[1]) + componentToHex(data.color[2]) + componentToHex(data.color[3]);
$('#status').css("backgroundColor", statusColor);
$('#status_color').text(statusColor + "- R=" + data.color[1] + ", G=" + data.color[2] + ", B=" + data.color[3]);
});
// Load modes async
// List of all color modes
// enum MODE {OFF, AUTO, TV, E131, SET_MODE, HOLD, CUSTOM, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW};
$.getJSON("http://" + host + "/get_modes", function(data) {
console.log("modes", data);
var modes_html = "";
data.forEach(function(current_mode){
if (current_mode.mode !== undefined) {
modes_html += '<div class="col s12 m6 l6 btn_grid">';
if ((mode == "5" && current_mode.mode == ws2812fx_mode) || (mode == "0" && current_mode.mode == "off") || (mode == "2" && current_mode.mode == "tv") || (mode == "3" && current_mode.mode == "e131")){
modes_html += '<a class="btn waves-effect waves-light btn_mode red" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
} else {
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
}
modes_html += '<i class="material-icons right">send</i>';
modes_html += '</a>';
modes_html += '</div>';
}
});
$('#modes').html(modes_html);
});
// When the connection is open, send some data to the server
connection.onopen = function () {
//connection.send('Ping'); // Send the message 'Ping' to the server
console.log('WebSocket Open');
showPane('pane1');
};
// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
$('#mc-wsloader').addClass('hide');
$('#mc-wserror').removeClass('hide');
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('WebSocket from server: ' + e.data);
ws_waiting = 0;
};
}
// ******************************************************************
// Modes
// ******************************************************************
$("#pane2").on("click", ".btn_mode", function() {
var mode = $(this).attr("data-mode");
last_mode = mode;
var btn = $(this);
setMode(mode, function() {
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
btn.removeClass("blue").addClass("red");
});
});
$("#pane2").on("click", ".btn_mode_static", function() {
var mode = $(this).attr("data-mode");
var btn = $(this);
wsSendCommand("=" + mode);
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
btn.removeClass("blue").addClass("red");
});
$("#pane2").on("change", ".update_colors", setMainColor);
$("#pane2").on("change", ".update_delay", function() {
var delay = $("#rng_delay").val();
wsSendCommand("?" + delay);
});
$("#pane2").on("change", ".update_brightness", function() {
var brightness = $("#rng_brightness").val();
wsSendCommand("%" + brightness);
});
$("#autoSwitch").on("change", function () {
if ($(this).prop('checked')) {
wsSendCommand("start");
} else {
wsSendCommand("stop");
}
});
function setMode(mode, finish_funtion) {
console.log("Mode: ", mode);
wsSendCommand("/" + mode);
finish_funtion();
}
function setMainColor() {
var white = $("#rng_white").val();
var red = $("#rng_red").val();
var green = $("#rng_green").val();
var blue = $("#rng_blue").val();
var hexColor = componentToHex(white) + componentToHex(red) + componentToHex(green) + componentToHex(blue);
var statusColor = "#" + componentToHex(red) + componentToHex(green) + componentToHex(blue);
wsSetMainColor(hexColor);
$('#status').css("backgroundColor", statusColor);
$('#status_color').text(statusColor + "- R=" + red + ", G=" + green + ", B=" + blue);
}
// ******************************************************************
// WebSocket commands
// ******************************************************************
function wsSendCommand(cmd) {
console.log("Send WebSocket command:", cmd);
if (ws_waiting == 0) {
connection.send(cmd);
ws_waiting++;
} else {
console.log("++++++++ WS call waiting, skip")
}
}
function wsSetAll(hexColor) {
console.log("wsSetAll() Set all colors to:", hexColor);
wsSendCommand("*" + hexColor);
}
function wsSetMainColor(hexColor) {
console.log("wsSetMainColor() Set main colors to:", hexColor);
wsSendCommand("#" + hexColor);
}
// ******************************************************************
// Colorwheel
// ******************************************************************
// this is supposed to work on mobiles (touch) as well as on a desktop (click)
// since we couldn't find a decent one .. this try of writing one by myself
// + google. swiping would be really nice - I will possibly implement it with
// jquery later - or never.
var canvas = document.getElementById("myCanvas");
// FIX: Cancel touch end event and handle click via touchstart
// canvas.addEventListener("touchend", function(e) { e.preventDefault(); }, false);
canvas.addEventListener("touchmove", doTouch, false);
canvas.addEventListener("click", doClick, false);
//canvas.addEventListener("mousemove", doClick, false);
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var innerRadius = canvas.width / 4.5;
var outerRadius = (canvas.width - 10) / 2
//outer border
context.beginPath();
//outer circle
context.arc(centerX, centerY, outerRadius, 0, 2 * Math.PI, false);
//draw the outer border: (gets drawn around the circle!)
context.lineWidth = 4;
context.strokeStyle = '#000000';
context.stroke();
context.closePath();
//fill with beautiful colors
//taken from here: http://stackoverflow.com/questions/18265804/building-a-color-wheel-in-html5
for(var angle=0; angle<=360; angle+=1) {
var startAngle = (angle-2)*Math.PI/180;
var endAngle = angle * Math.PI/180;
context.beginPath();
context.moveTo(centerX, centerY);
context.arc(centerX, centerY, outerRadius, startAngle, endAngle, false);
context.closePath();
context.fillStyle = 'hsl('+angle+', 100%, 50%)';
context.fill();
context.closePath();
}
//inner border
context.beginPath();
//context.arc(centerX, centerY, radius, startAngle, endAngle, counterClockwise);
context.arc(centerX, centerY, innerRadius, 0, 2 * Math.PI, false);
//fill the center
var my_gradient=context.createLinearGradient(0,0,170,0);
my_gradient.addColorStop(0,"black");
my_gradient.addColorStop(1,"white");
context.fillStyle = my_gradient;
context.fillStyle = "white";
context.fill();
//draw the inner line
context.lineWidth = 2;
context.strokeStyle = '#000000';
context.stroke();
context.closePath();
//get Mouse x/y canvas position
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
//comp to Hex
function componentToHex(c) {
//var hex = c.toString(16);
//return hex.length == 1 ? "0" + hex : hex;
return ("0"+(Number(c).toString(16))).slice(-2).toUpperCase();
}
//rgb/rgba to Hex
function rgbToHex(rgb) {
return componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
}
//display the touch/click position and color info
function updateStatus(pos, color) {
//var hexColor = rgbToHex(color);
//wsSetAll(hexColor);
var hexColor = componentToHex(color[0]) + componentToHex(color[1]) + componentToHex(color[2]);
wsSetMainColor(hexColor);
hexColor = "#" + hexColor;
$('#status').css("backgroundColor", hexColor);
$('#status_color').text(hexColor + " - R=" + color[0] + ", G=" + color[1] + ", B=" + color[2]);
$('#status_pos').text("x: " + pos.x + " - y: " + pos.y);
$("#rng_white").val(0);
$("#rng_red").val(color[0]);
$("#rng_green").val(color[1]);
$("#rng_blue").val(color[2]);
}
//handle the touch event
function doTouch(event) {
//to not also fire on click
event.preventDefault();
var el = event.target;
//touch position
var pos = {x: Math.round(event.targetTouches[0].pageX - el.offsetLeft),
y: Math.round(event.targetTouches[0].pageY - el.offsetTop)};
//color
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
updateStatus(pos, color);
}
function doClick(event) {
//click position
var pos = getMousePos(canvas, event);
//color
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
//console.log("click", pos.x, pos.y, color);
updateStatus(pos, color);
//now do sth with the color rgbToHex(color);
//don't do stuff when #000000 (outside circle and lines
}
// ******************************************************************
// main
// ******************************************************************
init();
}); // end of document ready
})(jQuery); // end of jQuery name space</script>
</body>
</html>
-55
View File
@@ -1,55 +0,0 @@
var gulp = require('gulp'),
request = require('request'),
fs = require('fs'),
connect = require('gulp-connect'),
fileinclude = require('gulp-file-include');
var src_dir = "src/";
var build_dir = "build/";
gulp.task('html', function() {
gulp.src(src_dir + '*.htm')
.pipe(fileinclude({
prefix: '@@',
basepath: '@file'
}))
.pipe(gulp.dest('build'))
.pipe(connect.reload());
});
gulp.task('connect', function() {
connect.server({
root: 'build',
livereload: true
});
});
gulp.task('watch', function() {
gulp.watch(src_dir + '*.htm', ['html']);
gulp.watch(src_dir + 'js/*.js', ['html']);
});
gulp.task('upload', ['html'], function() {
var url = 'http://192.168.0.49/edit';
var options = {
url: url,
headers: {
'Content-Type': 'multipart/form-data'
}
};
var r = request.post(options, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
var form = r.form();
form.append('data', fs.createReadStream(__dirname + "/" + build_dir + '/index.htm'), {filename: '/index.htm', contentType: "application/octet-stream"});
});
gulp.task('default', ['html']);
gulp.task('serve', ['watch', 'connect']);
-18
View File
@@ -1,18 +0,0 @@
{
"name": "mc_lighting",
"version": "2.0.0",
"description": "Web client for Mc Lighting",
"main": "index.html",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Tobias Blum",
"license": "MIT",
"dependencies": {
"fs": "0.0.2",
"gulp": "^3.9.1",
"gulp-connect": "^5.0.0",
"gulp-file-include": "^1.0.0",
"request": "^2.72.0"
}
}
-159
View File
@@ -1,159 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<!--Import Google Icon Font-->
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" media="screen,projection" />
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<meta name="mobile-web-app-capable" content="yes">
<meta charset="utf-8"/>
<meta name="mobile-web-app-capable" content="yes">
<title>McLighting (RGBW) v2</title>
</head>
<body>
<nav class="blue light-blueXXX lighten-1XXX" role="navigation" id="mc-nav">
<div class="nav-wrapper container">
<a id="logo-container" href="#" class="brand-logo">McLighting (RGBW) v2</a>
<ul class="right hide-on-med-and-down">
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
</ul>
<ul id="nav-mobile" class="side-nav">
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
</ul>
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
</div>
</nav>
<div class="container mc_pane" id="pane0">
<div class="section">
<div class="row" id="mc-wsloader">
<div class="col">
<div class="preloader-wrapper active">
<div class="spinner-layer spinner-blue-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
</div>
</div>
<div class="row hide" id="mc-wserror">
<div class="col">
<div>Error on websocket connect.</div>
</div>
</div>
</div>
</div>
<div class="container mc_pane hide" id="pane1">
<div class="section">
<div class="row">
<div class="col s12 m6">
<div style="height: 330px; width: 330px;">
<canvas id="myCanvas" width="330" height="330" style="-webkit-user-select: none;-webkit-tap-highlight-color: rgba(0,0,0,0);-moz-user-select:none;"></canvas>
</div>
</div>
<div class="col s12 m6">
<div class="card-panel" id="status">
<div id="status_pos">pick a color</div>
<div id="status_color"></div>
</div>
</div>
<div class="col s12 m6">
<div class="right switch">Auto:<br>
<label>Off
<input id="autoSwitch" type="checkbox"><span class="lever"></span>On
</label>
</div>
</div>
</div>
</div>
</div>
<div class="container mc_pane hide" id="pane2">
<div class="section">
<div class="row">
<form class="col s12">
<div class="row">
<div class="input-field col s12 l4">
<label for="txt_red">Red</label><br/>
<p class="range-field"><input type="range" id="rng_red" min="0" max="255" class="update_colors" /></p>
</div>
<div class="input-field col s12 l4">
<label for="txt_green">Green</label><br/>
<p class="range-field"><input type="range" id="rng_green" min="0" max="255" class="update_colors" /></p>
</div>
<div class="input-field col s12 l4">
<label for="txt_blue">Blue</label><br/>
<p class="range-field"><input type="range" id="rng_blue" min="0" max="255" class="update_colors" /></p>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<label for="txt_white">White</label><br/>
<p class="range-field"><input type="range" id="rng_white" min="0" max="255" class="update_colors" /></p>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<label for="txt_delay">Speed</label><br/>
<p class="range-field"><input type="range" id="rng_delay" min="0" max="255" value="196" class="update_delay" /></p>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<label for="txt_delay">Brightness</label><br/>
<p class="range-field"><input type="range" id="rng_brightness" min="0" max="255" value="196" class="update_brightness" /></p>
</div>
</div>
</form>
</div>
<div class="row">
<div id="modes">
<div class="input-field col s12">
Loading animations...
</div>
</div>
</div>
</div>
</div>
<footer class="page-footer blue">
<div class="footer-copyright">
<div class="container">© 2017
<a class="grey-text text-lighten-4 right" href="https://github.com/toblum/McLighting">Project home</a>
</div>
</div>
</footer>
<style type="text/css">
.btn_grid {
margin: 7px 0;
}
</style>
<!--Import jQuery before materialize.js-->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script type="text/javascript">@@include('js/script.js')</script>
</body>
\ No newline at end of file
</html>
-331
View File
@@ -1,331 +0,0 @@
(function($){
$(function(){
// Settings
var host = window.location.hostname;
//host = "esp8266_02.local";
var ws_url = 'ws://' + host + ':81';
var connection;
var ws_waiting = 0;
// ******************************************************************
// Side navigation
// ******************************************************************
$('.button-collapse').sideNav();
// Navlinks
$('#mc-nav').on('click', '.mc-navlink', function(){
console.log("Navigate to pane: ", $(this).data("pane"));
showPane($(this).data("pane"));
});
function showPane(pane) {
$('.mc_pane').addClass('hide');
$('#' + pane).removeClass('hide');
$('.button-collapse').sideNav('hide');
//if (pane == "pane2") {
// setMainColor();
//}
}
// ******************************************************************
// init()
// ******************************************************************
function init() {
console.log("Connection websockets to:", ws_url);
connection = new WebSocket(ws_url, ['arduino']);
var mode = 0;
var ws2812fx_mode = 0;
$.getJSON("http://" + host + "/status", function(data) {
console.log("status", data);
mode = data.mode;
ws2812fx_mode = data.ws2812fx_mode;
$("#rng_delay").val(data.speed);
$("#rng_brightness").val(data.brightness);
$("#rng_white").val(data.color[0]);
$("#rng_red").val(data.color[1]);
$("#rng_green").val(data.color[2]);
$("#rng_blue").val(data.color[3]);
var statusColor = "#" + componentToHex(data.color[1]) + componentToHex(data.color[2]) + componentToHex(data.color[3]);
$('#status').css("backgroundColor", statusColor);
$('#status_color').text(statusColor + "- R=" + data.color[1] + ", G=" + data.color[2] + ", B=" + data.color[3]);
});
// Load modes async
// List of all color modes
// enum MODE {OFF, AUTO, TV, E131, SET_MODE, HOLD, CUSTOM, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW};
$.getJSON("http://" + host + "/get_modes", function(data) {
console.log("modes", data);
var modes_html = "";
data.forEach(function(current_mode){
if (current_mode.mode !== undefined) {
modes_html += '<div class="col s12 m6 l6 btn_grid">';
if ((mode == "5" && current_mode.mode == ws2812fx_mode) || (mode == "0" && current_mode.mode == "off") || (mode == "2" && current_mode.mode == "tv") || (mode == "3" && current_mode.mode == "e131")){
modes_html += '<a class="btn waves-effect waves-light btn_mode red" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
} else {
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
}
modes_html += '<i class="material-icons right">send</i>';
modes_html += '</a>';
modes_html += '</div>';
}
});
$('#modes').html(modes_html);
});
// When the connection is open, send some data to the server
connection.onopen = function () {
//connection.send('Ping'); // Send the message 'Ping' to the server
console.log('WebSocket Open');
showPane('pane1');
};
// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
$('#mc-wsloader').addClass('hide');
$('#mc-wserror').removeClass('hide');
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('WebSocket from server: ' + e.data);
ws_waiting = 0;
};
}
// ******************************************************************
// Modes
// ******************************************************************
$("#pane2").on("click", ".btn_mode", function() {
var mode = $(this).attr("data-mode");
last_mode = mode;
var btn = $(this);
setMode(mode, function() {
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
btn.removeClass("blue").addClass("red");
});
});
$("#pane2").on("click", ".btn_mode_static", function() {
var mode = $(this).attr("data-mode");
var btn = $(this);
wsSendCommand("=" + mode);
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
btn.removeClass("blue").addClass("red");
});
$("#pane2").on("change", ".update_colors", setMainColor);
$("#pane2").on("change", ".update_delay", function() {
var delay = $("#rng_delay").val();
wsSendCommand("?" + delay);
});
$("#pane2").on("change", ".update_brightness", function() {
var brightness = $("#rng_brightness").val();
wsSendCommand("%" + brightness);
});
$("#autoSwitch").on("change", function () {
if ($(this).prop('checked')) {
wsSendCommand("start");
} else {
wsSendCommand("stop");
}
});
function setMode(mode, finish_funtion) {
console.log("Mode: ", mode);
wsSendCommand("/" + mode);
finish_funtion();
}
function setMainColor() {
var white = $("#rng_white").val();
var red = $("#rng_red").val();
var green = $("#rng_green").val();
var blue = $("#rng_blue").val();
var hexColor = componentToHex(white) + componentToHex(red) + componentToHex(green) + componentToHex(blue);
var statusColor = "#" + componentToHex(red) + componentToHex(green) + componentToHex(blue);
wsSetMainColor(hexColor);
$('#status').css("backgroundColor", statusColor);
$('#status_color').text(statusColor + "- R=" + red + ", G=" + green + ", B=" + blue);
}
// ******************************************************************
// WebSocket commands
// ******************************************************************
function wsSendCommand(cmd) {
console.log("Send WebSocket command:", cmd);
if (ws_waiting == 0) {
connection.send(cmd);
ws_waiting++;
} else {
console.log("++++++++ WS call waiting, skip")
}
}
function wsSetAll(hexColor) {
console.log("wsSetAll() Set all colors to:", hexColor);
wsSendCommand("*" + hexColor);
}
function wsSetMainColor(hexColor) {
console.log("wsSetMainColor() Set main colors to:", hexColor);
wsSendCommand("#" + hexColor);
}
// ******************************************************************
// Colorwheel
// ******************************************************************
// this is supposed to work on mobiles (touch) as well as on a desktop (click)
// since we couldn't find a decent one .. this try of writing one by myself
// + google. swiping would be really nice - I will possibly implement it with
// jquery later - or never.
var canvas = document.getElementById("myCanvas");
// FIX: Cancel touch end event and handle click via touchstart
// canvas.addEventListener("touchend", function(e) { e.preventDefault(); }, false);
canvas.addEventListener("touchmove", doTouch, false);
canvas.addEventListener("click", doClick, false);
//canvas.addEventListener("mousemove", doClick, false);
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var innerRadius = canvas.width / 4.5;
var outerRadius = (canvas.width - 10) / 2
//outer border
context.beginPath();
//outer circle
context.arc(centerX, centerY, outerRadius, 0, 2 * Math.PI, false);
//draw the outer border: (gets drawn around the circle!)
context.lineWidth = 4;
context.strokeStyle = '#000000';
context.stroke();
context.closePath();
//fill with beautiful colors
//taken from here: http://stackoverflow.com/questions/18265804/building-a-color-wheel-in-html5
for(var angle=0; angle<=360; angle+=1) {
var startAngle = (angle-2)*Math.PI/180;
var endAngle = angle * Math.PI/180;
context.beginPath();
context.moveTo(centerX, centerY);
context.arc(centerX, centerY, outerRadius, startAngle, endAngle, false);
context.closePath();
context.fillStyle = 'hsl('+angle+', 100%, 50%)';
context.fill();
context.closePath();
}
//inner border
context.beginPath();
//context.arc(centerX, centerY, radius, startAngle, endAngle, counterClockwise);
context.arc(centerX, centerY, innerRadius, 0, 2 * Math.PI, false);
//fill the center
var my_gradient=context.createLinearGradient(0,0,170,0);
my_gradient.addColorStop(0,"black");
my_gradient.addColorStop(1,"white");
context.fillStyle = my_gradient;
context.fillStyle = "white";
context.fill();
//draw the inner line
context.lineWidth = 2;
context.strokeStyle = '#000000';
context.stroke();
context.closePath();
//get Mouse x/y canvas position
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
//comp to Hex
function componentToHex(c) {
//var hex = c.toString(16);
//return hex.length == 1 ? "0" + hex : hex;
return ("0"+(Number(c).toString(16))).slice(-2).toUpperCase();
}
//rgb/rgba to Hex
function rgbToHex(rgb) {
return componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
}
//display the touch/click position and color info
function updateStatus(pos, color) {
//var hexColor = rgbToHex(color);
//wsSetAll(hexColor);
var hexColor = componentToHex(color[0]) + componentToHex(color[1]) + componentToHex(color[2]);
wsSetMainColor(hexColor);
hexColor = "#" + hexColor;
$('#status').css("backgroundColor", hexColor);
$('#status_color').text(hexColor + " - R=" + color[0] + ", G=" + color[1] + ", B=" + color[2]);
$('#status_pos').text("x: " + pos.x + " - y: " + pos.y);
$("#rng_white").val(0);
$("#rng_red").val(color[0]);
$("#rng_green").val(color[1]);
$("#rng_blue").val(color[2]);
}
//handle the touch event
function doTouch(event) {
//to not also fire on click
event.preventDefault();
var el = event.target;
//touch position
var pos = {x: Math.round(event.targetTouches[0].pageX - el.offsetLeft),
y: Math.round(event.targetTouches[0].pageY - el.offsetTop)};
//color
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
updateStatus(pos, color);
}
function doClick(event) {
//click position
var pos = getMousePos(canvas, event);
//color
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
//console.log("click", pos.x, pos.y, color);
updateStatus(pos, color);
//now do sth with the color rgbToHex(color);
//don't do stuff when #000000 (outside circle and lines
}
// ******************************************************************
// main
// ******************************************************************
init();
}); // end of document ready
})(jQuery); // end of jQuery name space
-4
View File
@@ -1,4 +0,0 @@
## Retired, use:
McLightingHTML from https://github.com/FabLab-Luenen/McLightingHTML
or set #define USE_HTML_MIN_GZ in definitions.h to use the integrated!
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

-466
View File
@@ -1,466 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<!--Import Google Icon Font-->
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" media="screen,projection" />
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<meta name="mobile-web-app-capable" content="yes">
<meta charset="utf-8"/>
<title>McLighting v2</title>
</head>
<body>
<nav class="blue light-blueXXX lighten-1XXX" role="navigation" id="mc-nav">
<div class="nav-wrapper container">
<a id="logo-container" href="#" class="brand-logo">Mc Lighting v2</a>
<ul class="right hide-on-med-and-down">
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
</ul>
<ul id="nav-mobile" class="side-nav">
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
</ul>
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
</div>
</nav>
<div class="container mc_pane" id="pane0">
<div class="section">
<div class="row" id="mc-wsloader">
<div class="col">
<div class="preloader-wrapper active">
<div class="spinner-layer spinner-blue-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
</div>
</div>
<div class="row hide" id="mc-wserror">
<div class="col">
<div>Error on websocket connect.</div>
</div>
</div>
</div>
</div>
<div class="container mc_pane hide" id="pane1">
<div class="section">
<div class="row">
<div class="col s12 m6">
<div style="height: 330px; width: 330px;">
<canvas id="myCanvas" width="330" height="330" style="-webkit-user-select: none;-webkit-tap-highlight-color: rgba(0,0,0,0);-moz-user-select:none;"></canvas>
</div>
</div>
<div class="col s12 m6">
<div class="card-panel" id="status">
<div id="status_pos">pick a color</div>
<div id="status_color"></div>
</div>
</div>
<div class="col s12 m6">
<div class="right switch">Auto:<br>
<label>Off
<input id="autoSwitch" type="checkbox"><span class="lever"></span>On
</label>
</div>
</div>
</div>
</div>
</div>
<div class="container mc_pane hide" id="pane2">
<div class="section">
<div class="row">
<form class="col s12">
<div class="row">
<div class="input-field col s12 l4">
<label for="txt_red">Red</label><br/>
<p class="range-field"><input type="range" id="rng_red" min="0" max="255" class="update_colors" /></p>
</div>
<div class="input-field col s12 l4">
<label for="txt_green">Green</label><br/>
<p class="range-field"><input type="range" id="rng_green" min="0" max="255" class="update_colors" /></p>
</div>
<div class="input-field col s12 l4">
<label for="txt_blue">Blue</label><br/>
<p class="range-field"><input type="range" id="rng_blue" min="0" max="255" class="update_colors" /></p>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<label for="txt_delay">Speed</label><br/>
<p class="range-field"><input type="range" id="rng_delay" min="0" max="255" value="196" class="update_delay" /></p>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<label for="txt_delay">Brightness</label><br/>
<p class="range-field"><input type="range" id="rng_brightness" min="0" max="255" value="196" class="update_brightness" /></p>
</div>
</div>
</form>
</div>
<div class="row">
<div class="col s12 m6 l6 btn_grid">
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="off">OFF
<i class="material-icons right">send</i>
</a>
</div>
<div class="col s12 m6 l6 btn_grid">
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="tv">TV
<i class="material-icons right">send</i>
</a>
</div>
<div id="modes">
<div class="input-field col s12">
Loading animations...
</div>
</div>
</div>
</div>
</div>
<footer class="page-footer blue">
<div class="footer-copyright">
<div class="container">© 2017
<a class="grey-text text-lighten-4 right" href="https://github.com/toblum/McLighting">Project home</a>
</div>
</div>
</footer>
<style type="text/css">
.btn_grid {
margin: 7px 0;
}
</style>
<!--Import jQuery before materialize.js-->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script type="text/javascript">(function($){
$(function(){
// Settings
var host = window.location.hostname;
//host = "esp8266_02.local";
var ws_url = 'ws://' + host + ':81';
var connection;
var ws_waiting = 0;
// ******************************************************************
// Side navigation
// ******************************************************************
$('.button-collapse').sideNav();
// Navlinks
$('#mc-nav').on('click', '.mc-navlink', function(){
console.log("Navigate to pane: ", $(this).data("pane"));
showPane($(this).data("pane"));
});
function showPane(pane) {
$('.mc_pane').addClass('hide');
$('#' + pane).removeClass('hide');
$('.button-collapse').sideNav('hide');
if (pane == "pane2") {
setMainColor();
}
}
// ******************************************************************
// init()
// ******************************************************************
function init() {
console.log("Connection websockets to:", ws_url);
connection = new WebSocket(ws_url, ['arduino']);
// Load modes async
$.getJSON("http://" + host + "/get_modes", function(data) {
//console.log("modes", data);
var modes_html = "";
data.forEach(function(current_mode){
if (current_mode.mode !== undefined) {
modes_html += '<div class="col s12 m6 l6 btn_grid">';
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
modes_html += '<i class="material-icons right">send</i>';
modes_html += '</a>';
modes_html += '</div>';
}
});
$('#modes').html(modes_html);
});
// When the connection is open, send some data to the server
connection.onopen = function () {
//connection.send('Ping'); // Send the message 'Ping' to the server
console.log('WebSocket Open');
showPane('pane1');
};
// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
$('#mc-wsloader').addClass('hide');
$('#mc-wserror').removeClass('hide');
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('WebSocket from server: ' + e.data);
ws_waiting = 0;
};
}
// ******************************************************************
// Modes
// ******************************************************************
$("#pane2").on("click", ".btn_mode", function() {
var mode = $(this).attr("data-mode");
last_mode = mode;
var btn = $(this);
setMode(mode, function() {
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
btn.removeClass("blue").addClass("red");
});
});
$("#pane2").on("click", ".btn_mode_static", function() {
var mode = $(this).attr("data-mode");
var btn = $(this);
wsSendCommand("=" + mode);
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
btn.removeClass("blue").addClass("red");
});
$("#pane2").on("change", ".update_colors", setMainColor);
$("#pane2").on("change", ".update_delay", function() {
var delay = $("#rng_delay").val();
wsSendCommand("?" + delay);
});
$("#pane2").on("change", ".update_brightness", function() {
var brightness = $("#rng_brightness").val();
wsSendCommand("%" + brightness);
});
$("#autoSwitch").on("change", function () {
if ($(this).prop('checked')) {
wsSendCommand("start");
} else {
wsSendCommand("stop");
}
});
function setMode(mode, finish_funtion) {
console.log("Mode: ", mode);
wsSendCommand("/" + mode);
finish_funtion();
}
function setMainColor() {
var red = $("#rng_red").val();
var green = $("#rng_green").val();
var blue = $("#rng_blue").val();
var mainColorHex = componentToHex(red) + componentToHex(green) + componentToHex(blue);
wsSetMainColor(mainColorHex);
}
// ******************************************************************
// WebSocket commands
// ******************************************************************
function wsSendCommand(cmd) {
console.log("Send WebSocket command:", cmd);
if (ws_waiting == 0) {
connection.send(cmd);
ws_waiting++;
} else {
console.log("++++++++ WS call waiting, skip")
}
}
function wsSetAll(hexColor) {
console.log("wsSetAll() Set all colors to:", hexColor);
wsSendCommand("*" + hexColor);
}
function wsSetMainColor(hexColor) {
console.log("wsSetMainColor() Set main colors to:", hexColor);
wsSendCommand("#" + hexColor);
}
// ******************************************************************
// Colorwheel
// ******************************************************************
// this is supposed to work on mobiles (touch) as well as on a desktop (click)
// since we couldn't find a decent one .. this try of writing one by myself
// + google. swiping would be really nice - I will possibly implement it with
// jquery later - or never.
var canvas = document.getElementById("myCanvas");
// FIX: Cancel touch end event and handle click via touchstart
// canvas.addEventListener("touchend", function(e) { e.preventDefault(); }, false);
canvas.addEventListener("touchmove", doTouch, false);
canvas.addEventListener("click", doClick, false);
//canvas.addEventListener("mousemove", doClick, false);
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var innerRadius = canvas.width / 4.5;
var outerRadius = (canvas.width - 10) / 2
//outer border
context.beginPath();
//outer circle
context.arc(centerX, centerY, outerRadius, 0, 2 * Math.PI, false);
//draw the outer border: (gets drawn around the circle!)
context.lineWidth = 4;
context.strokeStyle = '#000000';
context.stroke();
context.closePath();
//fill with beautiful colors
//taken from here: http://stackoverflow.com/questions/18265804/building-a-color-wheel-in-html5
for(var angle=0; angle<=360; angle+=1) {
var startAngle = (angle-2)*Math.PI/180;
var endAngle = angle * Math.PI/180;
context.beginPath();
context.moveTo(centerX, centerY);
context.arc(centerX, centerY, outerRadius, startAngle, endAngle, false);
context.closePath();
context.fillStyle = 'hsl('+angle+', 100%, 50%)';
context.fill();
context.closePath();
}
//inner border
context.beginPath();
//context.arc(centerX, centerY, radius, startAngle, endAngle, counterClockwise);
context.arc(centerX, centerY, innerRadius, 0, 2 * Math.PI, false);
//fill the center
var my_gradient=context.createLinearGradient(0,0,170,0);
my_gradient.addColorStop(0,"black");
my_gradient.addColorStop(1,"white");
context.fillStyle = my_gradient;
context.fillStyle = "white";
context.fill();
//draw the inner line
context.lineWidth = 2;
context.strokeStyle = '#000000';
context.stroke();
context.closePath();
//get Mouse x/y canvas position
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
//comp to Hex
function componentToHex(c) {
//var hex = c.toString(16);
//return hex.length == 1 ? "0" + hex : hex;
return ("0"+(Number(c).toString(16))).slice(-2).toUpperCase();
}
//rgb/rgba to Hex
function rgbToHex(rgb) {
return componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
}
//display the touch/click position and color info
function updateStatus(pos, color) {
var hexColor = rgbToHex(color);
wsSetAll(hexColor);
hexColor = "#" + hexColor;
$('#status').css("backgroundColor", hexColor);
$('#status_color').text(hexColor + " - R=" + color[0] + ", G=" + color[1] + ", B=" + color[2]);
$('#status_pos').text("x: " + pos.x + " - y: " + pos.y);
$("#rng_red").val(color[0]);
$("#rng_green").val(color[1]);
$("#rng_blue").val(color[2]);
}
//handle the touch event
function doTouch(event) {
//to not also fire on click
event.preventDefault();
var el = event.target;
//touch position
var pos = {x: Math.round(event.targetTouches[0].pageX - el.offsetLeft),
y: Math.round(event.targetTouches[0].pageY - el.offsetTop)};
//color
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
updateStatus(pos, color);
}
function doClick(event) {
//click position
var pos = getMousePos(canvas, event);
//color
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
//console.log("click", pos.x, pos.y, color);
updateStatus(pos, color);
//now do sth with the color rgbToHex(color);
//don't do stuff when #000000 (outside circle and lines
}
// ******************************************************************
// main
// ******************************************************************
init();
}); // end of document ready
})(jQuery); // end of jQuery name space</script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.
-55
View File
@@ -1,55 +0,0 @@
var gulp = require('gulp'),
request = require('request'),
fs = require('fs'),
connect = require('gulp-connect'),
fileinclude = require('gulp-file-include');
var src_dir = "src/";
var build_dir = "build/";
gulp.task('html', function() {
gulp.src(src_dir + '*.htm')
.pipe(fileinclude({
prefix: '@@',
basepath: '@file'
}))
.pipe(gulp.dest('build'))
.pipe(connect.reload());
});
gulp.task('connect', function() {
connect.server({
root: 'build',
livereload: true
});
});
gulp.task('watch', function() {
gulp.watch(src_dir + '*.htm', ['html']);
gulp.watch(src_dir + 'js/*.js', ['html']);
});
gulp.task('upload', ['html'], function() {
var url = 'http://192.168.0.49/edit';
var options = {
url: url,
headers: {
'Content-Type': 'multipart/form-data'
}
};
var r = request.post(options, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
var form = r.form();
form.append('data', fs.createReadStream(__dirname + "/" + build_dir + '/index.htm'), {filename: '/index.htm', contentType: "application/octet-stream"});
});
gulp.task('default', ['html']);
gulp.task('serve', ['watch', 'connect']);
@@ -5,8 +5,8 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="mobile-web-app-capable" content="yes">
<link rel="shortcut icon" href="https://cdn.rawgit.com/toblum/McLightingUI/1346e334/material/McLightingLogo/favicon.ico" type="image/x-icon" />
<link rel="apple-touch-icon" href="https://cdn.rawgit.com/toblum/McLightingUI/1346e334/material/McLightingLogo/apple-touch-icon.png">
<link rel="shortcut icon" href="https://raw.githubusercontent.com/FabLab-Luenen/McLighting/master/Arduino/McLighting/data/favicon.ico" type="image/x-icon" />
<link rel="apple-touch-icon" href="https://raw.githubusercontent.com/FabLab-Luenen/McLighting/master/Arduino/McLighting/apple-touch-icon.png">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons">
<style>
* {
@@ -912,34 +912,25 @@ input[type=number], label{
<input type="number" id="speedNum">
<input value="255" type="range" min="0" max="255" id="speed">
</div>
<div style="display:inline-flex; margin-top:12px;">
<label class="switch">
<input type="checkbox" id="autoplay" onclick="toggleAutoplay(this.checked);">
<span id="autoplaybgcolor" class="slider round"></span>
</label><div id="autoplayLbl" style="margin:auto 8px;font-size:18px;">autoplay</div>
</div>
</div>
</div>
</div>
<div id="message" class="container hidden" style="text-align: left;">
<div class="layout row wrap">
<div class="flex xs12" id="wsmessageLbl" style="text-align: left;"><p>wsMessage</p>
<div id="wsmessageLbl" style="text-align: left;"><p>wsMessage</p>
<input type="text" id="wsmessage" style="border: 2px solid #aaaaaa; border-radius: 6px; width:100%;" />
</div>
</div>
</div>
</div>
</div>
<div class="container" style="text-align: center;"><div id="modes" class="layout row wrap"></div></div>
<div id="settings" class="container hidden" style="text-align: center;">
<div class="layout row wrap">
<div class="flex xs12 sm4"><p>selectLanguage</p>
<select id="language" class="custom-select"></select>
</div>
<div class="flex xs12 sm4"><p>showAutoplay</p>
<div class="flex xs12 sm4"><p>transitionEffects</p>
<div style="display:inline-flex;">
<label class="switch">
<input type="checkbox" id="set-autoplay">
<span id="setautoplaybgcolor" class="slider round"></span>
<input type="checkbox" id="set-transitionEffects">
<span id="settransitionEffectsbgcolor" class="slider round"></span>
</label>
</div>
</div>
@@ -1010,7 +1001,7 @@ input[type=number], label{
</div>
<footer id="footer" style="height: 32px;">
<div><a href="https://github.com/toblum/McLighting/" id="footer-link" target="_blank">Project home</a> - © 2018</div> <div class="spacer"></div>
<div><a href="https://github.com/FabLab-Luenen/McLighting" id="footer-link" target="_blank">Project home</a> - © 2019</div> <div class="spacer"></div>
<button id="settings-open" type="button" class="btn btn--bottom btn__content"><i aria-hidden="true" class="icon material-icons">settings</i></button>
</footer>
</div>
@@ -1031,7 +1022,7 @@ var language = {
en: {
lang_name: "English",
title: "McLighting",
name: "Mc Lighting UI (RGBW)",
name: "McLightingUI V3(RGBW)",
connected: "connected",
disconnected: "disconnected",
reconnect: "Reconnect",
@@ -1052,7 +1043,6 @@ var language = {
white: "White",
not_greater: "cannot enter numbers greater than 255",
not_less: "cannot enter numbers less than 0",
autoplay: "Autoplay",
wsMessage: "Websocket Message:",
selectLanguage: "Select Language:",
selectHostname: "Hostname:",
@@ -1077,7 +1067,7 @@ var language = {
selectPicker: "Select color picker:",
circle: "Circle",
wheel: "Wheel",
showAutoplay: "Show Autoplay:",
transitionEffects: "Transition Effects:",
disableRGBW: "activate RGBW",
slaveNodes: "Additional McLighting Slave Nodes (\";\" seperated)",
saveSettings: " Save Settings",
@@ -1088,7 +1078,7 @@ var language = {
nl: {
lang_name: "Nederlands",
title: "McLighting",
name: "Mc Lighting UI (RGBW)",
name: "McLightingUI V3(RGBW)",
connected: "verbonden",
disconnected: "niet verbonden",
reconnect: "Verbind opnieuw",
@@ -1109,7 +1099,6 @@ var language = {
white: "Wit",
not_greater: "Geen nummers hoger dan 255",
not_less: "Geen nummers lager dan 0",
autoplay: "Autoplay",
wsMessage: "Websocket message:",
selectLanguage: "Selecteer Taal:",
selectHostname: "Hostname:",
@@ -1134,7 +1123,7 @@ var language = {
selectPicker: "Selecteer Kleur kiezer:",
circle: "Cirkel",
wheel: "Wiel",
showAutoplay: "Autoplay tonen:",
transitionEffects: "Overgangseffecten:",
disableRGBW: "RGBW activeren",
slaveNodes: "Additionele McLighting modules (\";\" gescheiden)",
saveSettings: " Instellingen opslaan",
@@ -1145,7 +1134,7 @@ var language = {
de: {
lang_name: "Deutsch",
title: "McLighting",
name: "Mc Lighting UI (RGBW)",
name: "McLightingUI V3(RGBW)",
connected: "verbunden",
disconnected: "getrennt",
reconnect: "Wieder verbinden",
@@ -1166,7 +1155,6 @@ var language = {
white: "Weiß",
not_greater: "Akzeptiere keine Nummern größer 255",
not_less: "Akzeptiere keine Nummern kleiner 0",
autoplay: "Autoplay",
wsMessage: "Websocket Message:",
selectLanguage: "Sprache auswählen:",
selectHostname: "Hostname:",
@@ -1191,7 +1179,7 @@ var language = {
selectPicker: "Farbwahltyp auswählen:",
circle: "Kreis",
wheel: "Rad",
showAutoplay: "Autoplay anzeigen:",
transitionEffects: "Übergangseffekte:",
disableRGBW: "RGBW aktivieren",
slaveNodes: "weitere McLighting Slave Nodes (\";\" getrennt)",
saveSettings: " Einstellungen speichern",
@@ -1285,7 +1273,6 @@ var settings = {
theme_btnsel: "#FF0000",
visibility: [],
picker_type: "wheel",
autoplay: true,
slave_nodes: ""
};
var config = {
@@ -1299,6 +1286,7 @@ var config = {
ws_pin: 0,
ws_fxopt: 0,
enable_rgbw: false,
transitionEffects: true
};
var data = {
mode: 0,
@@ -1567,6 +1555,7 @@ function getConfig() {
}
if (typeof res.ws_pin !== "undefined") config.ws_pin = res.ws_pin;
if (typeof res.ws_fxopt !== "undefined") config.ws_fxopt = res.ws_fxopt;
if (typeof res.transEffect !== "undefined") config.transitionEffects = res.transEffect;
}
} else {
console.error(e);
@@ -1678,21 +1667,6 @@ function toggle(mode, el) {
//console.log("Hidden items: " + settings.visibility);
}
function toggleAutoplay(status) {
var message = (status) ? "start" : "stop";
ws_send(message);
if (!status) {
document.getElementById("autoplay").checked = false;
document.getElementById("autoplaybgcolor").style.backgroundColor = "";
ws_send("$");
} else {
document.getElementById("autoplay").checked = true;
data.mode = 1;
document.getElementById("autoplaybgcolor").style.backgroundColor = settings.theme_btn;
select_active_button();
}
};
function onSelectColNum(colnum) {
data.color_num = colnum;
console.log("selected color:" + colnum);
@@ -1737,49 +1711,42 @@ function initSettings() {
hostname.addEventListener('change', ()=>{
config.hostname = hostname.value;
ws_send("Ch" + config.hostname);
ws_send("C");
});
var mqtt_host = document.getElementById("mqtt_host");
mqtt_host.value = config.mqtt_host;
mqtt_host.addEventListener('change', ()=>{
config.mqtt_host = mqtt_host.value;
ws_send("Cmh" + config.mqtt_host);
ws_send("C");
});
var mqtt_port = document.getElementById("mqtt_port");
mqtt_port.value = config.mqtt_port;
mqtt_port.addEventListener('change', ()=>{
config.mqtt_port = mqtt_port.value;
ws_send("Cmp" + config.mqtt_port);
ws_send("C");
});
var mqtt_user = document.getElementById("mqtt_user");
mqtt_user.value = config.mqtt_user;
mqtt_user.addEventListener('change', ()=>{
config.mqtt_user = mqtt_user.value;
ws_send("Cmu" + config.mqtt_user);
ws_send("C");
});
var mqtt_pass = document.getElementById("mqtt_pass");
mqtt_pass.value = config.mqtt_pass;
mqtt_pass.addEventListener('change', ()=>{
config.mqtt_pass = mqtt_pass.value;
ws_send("Cmw" + config.mqtt_pass);
ws_send("C");
});
var count = document.getElementById("selectcount");
count.value = config.ws_cnt;
count.addEventListener('change', ()=>{
config.ws_cnt = count.value;
ws_send("Csc" + config.ws_cnt);
ws_send("C");
});
var pin = document.getElementById("selectpin");
pin.value = config.ws_pin;
pin.addEventListener('change', ()=>{
config.ws_pin = pin.value;
ws_send("Csp" + config.ws_pin);
ws_send("C");
});
var rgbo = document.getElementById("selectrgbo");
for (var code in selectrgbo) {
@@ -1792,8 +1759,6 @@ function initSettings() {
rgbo.addEventListener('change', ()=>{
config.ws_rgbo = rgbo.value;
ws_send("Csr" + config.ws_rgbo);
ws_send("C");
});
var optrev = document.getElementById("selectoptrev");
for (var code in selectoptrev) {
@@ -1806,7 +1771,6 @@ function initSettings() {
optrev.addEventListener('change', ()=>{
config.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value;
ws_send("Cso" + config.ws_fxopt);
ws_send("C");
});
var optfade = document.getElementById("selectoptfade");
for (var code in selectoptfade) {
@@ -1819,7 +1783,6 @@ function initSettings() {
optfade.addEventListener('change', ()=>{
config.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value;
ws_send("Cso" + config.ws_fxopt);
ws_send("C");
});
var optgamma = document.getElementById("selectoptgamma");
for (var code in selectoptgamma) {
@@ -1832,7 +1795,6 @@ function initSettings() {
optgamma.addEventListener('change', ()=>{
config.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value;
ws_send("Cso" + config.ws_fxopt);
ws_send("C");
});
var optsize = document.getElementById("selectoptsize");
for (var code in selectoptsize) {
@@ -1845,7 +1807,6 @@ function initSettings() {
optsize.addEventListener('change', ()=>{
config.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value;
ws_send("Cso" + config.ws_fxopt);
ws_send("C");
});
slavenodes.value = settings.slave_nodes;
lang.addEventListener('change', ()=>{
@@ -1858,18 +1819,16 @@ function initSettings() {
settings.picker_type = (picker.checked) ? "circle" : "wheel";
redrawColorPicker();
});
var setautoplay = document.getElementById("set-autoplay");
setautoplay.checked = settings.autoplay;
if (!setautoplay.checked) autoplay.parentNode.parentNode.style.visibility = "hidden";
setautoplay.addEventListener('change', ()=>{
settings.autoplay = setautoplay.checked;
var play = document.getElementById("autoplay").parentNode.parentNode;
if (setautoplay.checked) {
play.style.visibility = "visible";
document.getElementById("setautoplaybgcolor").style.backgroundColor = settings.theme_btn;
var settransitionEffects = document.getElementById("set-transitionEffects");
settransitionEffects.checked = config.transitionEffects;
settransitionEffects.addEventListener('change', ()=>{
config.transitionEffects = settransitionEffects.checked;
if (settransitionEffects.checked) {
document.getElementById("settransitionEffectsbgcolor").style.backgroundColor = settings.theme_btn;
ws_send("Ce1");
} else {
play.style.visibility = "hidden";
document.getElementById("setautoplaybgcolor").style.backgroundColor = "";
document.getElementById("settransitionEffectsbgcolor").style.backgroundColor = "";
ws_send("Ce0");
}
});
var colmain = document.getElementById("color-main");
@@ -1908,7 +1867,6 @@ function initSettings() {
for (var i = 0; i < icons.length; i++) {
icons[i].style.color = (yiq >= 125) ? '#222' : '#EEE';
}
document.getElementById("autoplayLbl").style.color = (yiq >= 125) ? '#111' : '#EEE';
document.getElementById("wsmessageLbl").style.color = (yiq >= 125) ? '#111' : '#EEE';
document.getElementById("redNum").style.color = (yiq >= 125) ? '#111' : '#EEE';
document.getElementById("greenNum").style.color = (yiq >= 125) ? '#111' : '#EEE';
@@ -1924,8 +1882,7 @@ function initSettings() {
settings.theme_btn = colbtn.value;
document.getElementById("settings-save").style.backgroundColor = settings.theme_btn;
document.getElementById("pickerbgcolor").style.backgroundColor = settings.theme_btn;
if (setautoplay.checked) document.getElementById("setautoplaybgcolor").style.backgroundColor = settings.theme_btn;
if (document.getElementById("autoplay").checked) document.getElementById("autoplaybgcolor").style.backgroundColor = settings.theme_btn;
if (settransitionEffects.checked) document.getElementById("settransitionEffectsbgcolor").style.backgroundColor = settings.theme_btn;
select_active_button();
});
var colbtns = document.getElementById("color-btnsel");
@@ -2255,62 +2212,54 @@ function select_active_button() {
for (i = 0; i < btns.length; i++) {
btns[i].style.backgroundColor = settings.theme_btn;
}
if (data.mode != 1) document.getElementById("autoplay").checked = false;
if (data.mode != 4) {
if (data.mode != 1 || (data.mode === 1 && data.ws2812fx_mode !== 57)) { // CUSTOM WS MODE
wsmess = document.getElementById("message");
var arr = wsmess.className.split(" ");
if (arr.indexOf("hidden") === -1) {
wsmess.className += " hidden";
}
}
if (data.mode >= 5) {
if (data.mode >= 1) {
document.getElementById(data.ws2812fx_mode).style.backgroundColor = settings.theme_btnsel;
disable_modebuttons(false);
disable_color_selection(false);
disable_bright_selection(false);
disable_speed_selection(false);
} else {
if (data.mode == 0) {
document.getElementById("off").style.backgroundColor = settings.theme_btnsel;
disable_modebuttons(false);
disable_color_selection(true);
disable_bright_selection(true);
disable_speed_selection(true);
} else {
if (data.mode == 1) { // AUTO
document.getElementById("autoplay").checked = true;
disable_modebuttons(true);
disable_color_selection(true);
disable_bright_selection(true);
disable_speed_selection(true);
} else {
if (data.mode == 2) {
document.getElementById("tv").style.backgroundColor = settings.theme_btnsel;
disable_modebuttons(false);
disable_color_selection(true);
disable_bright_selection(false);
disable_speed_selection(false);
} else {
if (data.mode == 3) {
document.getElementById("e131").style.backgroundColor = settings.theme_btnsel;
if (data.ws2812fx_mode === 56) { // AUTOPLAY
disable_modebuttons(false);
disable_color_selection(true);
disable_bright_selection(false);
disable_speed_selection(true);
} else {
if (data.mode == 4) {
document.getElementById("custom").style.backgroundColor = settings.theme_btnsel;
} else if (data.ws2812fx_mode === 57) { //CUSTOM_WS
wsmess = document.getElementById("message");
wsmess.className = wsmess.className.replace(/\b hidden\b/g, "");
disable_modebuttons(false);
disable_color_selection(true);
disable_bright_selection(false);
disable_speed_selection(true);
} else if (data.ws2812fx_mode === 58) { //TV
disable_modebuttons(false);
disable_color_selection(true);
disable_bright_selection(false);
disable_speed_selection(false);
} else if (data.ws2812fx_mode === 59) { //E1.31
disable_modebuttons(false);
disable_color_selection(true);
disable_bright_selection(false);
disable_speed_selection(true);
} else if (data.ws2812fx_mode === 60) { //Fire2012
disable_modebuttons(false);
disable_color_selection(true);
disable_bright_selection(false);
disable_speed_selection(false);
} else {
disable_modebuttons(false);
disable_color_selection(false);
disable_bright_selection(false);
disable_speed_selection(false);
}
}
}
}
}
} else if (data.mode === 0) {
document.getElementById("off").style.backgroundColor = settings.theme_btnsel;
disable_modebuttons(false);
disable_color_selection(true);
disable_bright_selection(true);
disable_speed_selection(true);
}
}
@@ -2332,24 +2281,14 @@ function disable_modebuttons(status) {
}
function set_mode(mode_id) {
if (document.getElementById("autoplay").checked == true) toggleAutoplay(false);
if (Number.isInteger(mode_id)) {
data.mode = 5;
data.mode = 1;
data.ws2812fx_mode = mode_id;
} else {
// For named modes
if (mode_id == "off") {
data.mode = 0;
}
if (mode_id == "tv") {
data.mode = 2;
}
if (mode_id == "e131") {
data.mode = 3;
}
if (mode_id == "custom") {
data.mode = 4;
}
}
select_active_button();
ws_send("/" + mode_id);
Binary file not shown.
-18
View File
@@ -1,18 +0,0 @@
{
"name": "mc_lighting",
"version": "2.0.0",
"description": "Web client for Mc Lighting",
"main": "index.html",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Tobias Blum",
"license": "MIT",
"dependencies": {
"fs": "0.0.2",
"gulp": "^3.9.1",
"gulp-connect": "^5.0.0",
"gulp-file-include": "^1.0.0",
"request": "^2.72.0"
}
}
-162
View File
@@ -1,162 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<!--Import Google Icon Font-->
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" media="screen,projection" />
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<meta name="mobile-web-app-capable" content="yes">
<meta charset="utf-8"/>
<title>McLighting v2</title>
</head>
<body>
<nav class="blue light-blueXXX lighten-1XXX" role="navigation" id="mc-nav">
<div class="nav-wrapper container">
<a id="logo-container" href="#" class="brand-logo">Mc Lighting v2</a>
<ul class="right hide-on-med-and-down">
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
</ul>
<ul id="nav-mobile" class="side-nav">
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
</ul>
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
</div>
</nav>
<div class="container mc_pane" id="pane0">
<div class="section">
<div class="row" id="mc-wsloader">
<div class="col">
<div class="preloader-wrapper active">
<div class="spinner-layer spinner-blue-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
</div>
</div>
<div class="row hide" id="mc-wserror">
<div class="col">
<div>Error on websocket connect.</div>
</div>
</div>
</div>
</div>
<div class="container mc_pane hide" id="pane1">
<div class="section">
<div class="row">
<div class="col s12 m6">
<div style="height: 330px; width: 330px;">
<canvas id="myCanvas" width="330" height="330" style="-webkit-user-select: none;-webkit-tap-highlight-color: rgba(0,0,0,0);-moz-user-select:none;"></canvas>
</div>
</div>
<div class="col s12 m6">
<div class="card-panel" id="status">
<div id="status_pos">pick a color</div>
<div id="status_color"></div>
</div>
</div>
<div class="col s12 m6">
<div class="right switch">Auto:<br>
<label>Off
<input id="autoSwitch" type="checkbox"><span class="lever"></span>On
</label>
</div>
</div>
</div>
</div>
</div>
<div class="container mc_pane hide" id="pane2">
<div class="section">
<div class="row">
<form class="col s12">
<div class="row">
<div class="input-field col s12 l4">
<label for="txt_red">Red</label><br/>
<p class="range-field"><input type="range" id="rng_red" min="0" max="255" class="update_colors" /></p>
</div>
<div class="input-field col s12 l4">
<label for="txt_green">Green</label><br/>
<p class="range-field"><input type="range" id="rng_green" min="0" max="255" class="update_colors" /></p>
</div>
<div class="input-field col s12 l4">
<label for="txt_blue">Blue</label><br/>
<p class="range-field"><input type="range" id="rng_blue" min="0" max="255" class="update_colors" /></p>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<label for="txt_delay">Speed</label><br/>
<p class="range-field"><input type="range" id="rng_delay" min="0" max="255" value="196" class="update_delay" /></p>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<label for="txt_delay">Brightness</label><br/>
<p class="range-field"><input type="range" id="rng_brightness" min="0" max="255" value="196" class="update_brightness" /></p>
</div>
</div>
</form>
</div>
<div class="row">
<div class="col s12 m6 l6 btn_grid">
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="off">OFF
<i class="material-icons right">send</i>
</a>
</div>
<div class="col s12 m6 l6 btn_grid">
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="tv">TV
<i class="material-icons right">send</i>
</a>
</div>
<div id="modes">
<div class="input-field col s12">
Loading animations...
</div>
</div>
</div>
</div>
</div>
<footer class="page-footer blue">
<div class="footer-copyright">
<div class="container">© 2017
<a class="grey-text text-lighten-4 right" href="https://github.com/toblum/McLighting">Project home</a>
</div>
</div>
</footer>
<style type="text/css">
.btn_grid {
margin: 7px 0;
}
</style>
<!--Import jQuery before materialize.js-->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script type="text/javascript">@@include('js/script.js')</script>
</body>
</html>
-305
View File
@@ -1,305 +0,0 @@
(function($){
$(function(){
// Settings
var host = window.location.hostname;
//host = "esp8266_02.local";
var ws_url = 'ws://' + host + ':81';
var connection;
var ws_waiting = 0;
// ******************************************************************
// Side navigation
// ******************************************************************
$('.button-collapse').sideNav();
// Navlinks
$('#mc-nav').on('click', '.mc-navlink', function(){
console.log("Navigate to pane: ", $(this).data("pane"));
showPane($(this).data("pane"));
});
function showPane(pane) {
$('.mc_pane').addClass('hide');
$('#' + pane).removeClass('hide');
$('.button-collapse').sideNav('hide');
if (pane == "pane2") {
setMainColor();
}
}
// ******************************************************************
// init()
// ******************************************************************
function init() {
console.log("Connection websockets to:", ws_url);
connection = new WebSocket(ws_url, ['arduino']);
// Load modes async
$.getJSON("http://" + host + "/get_modes", function(data) {
//console.log("modes", data);
var modes_html = "";
data.forEach(function(current_mode){
if (current_mode.mode !== undefined) {
modes_html += '<div class="col s12 m6 l6 btn_grid">';
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
modes_html += '<i class="material-icons right">send</i>';
modes_html += '</a>';
modes_html += '</div>';
}
});
$('#modes').html(modes_html);
});
// When the connection is open, send some data to the server
connection.onopen = function () {
//connection.send('Ping'); // Send the message 'Ping' to the server
console.log('WebSocket Open');
showPane('pane1');
};
// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
$('#mc-wsloader').addClass('hide');
$('#mc-wserror').removeClass('hide');
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('WebSocket from server: ' + e.data);
ws_waiting = 0;
};
}
// ******************************************************************
// Modes
// ******************************************************************
$("#pane2").on("click", ".btn_mode", function() {
var mode = $(this).attr("data-mode");
last_mode = mode;
var btn = $(this);
setMode(mode, function() {
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
btn.removeClass("blue").addClass("red");
});
});
$("#pane2").on("click", ".btn_mode_static", function() {
var mode = $(this).attr("data-mode");
var btn = $(this);
wsSendCommand("=" + mode);
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
btn.removeClass("blue").addClass("red");
});
$("#pane2").on("change", ".update_colors", setMainColor);
$("#pane2").on("change", ".update_delay", function() {
var delay = $("#rng_delay").val();
wsSendCommand("?" + delay);
});
$("#pane2").on("change", ".update_brightness", function() {
var brightness = $("#rng_brightness").val();
wsSendCommand("%" + brightness);
});
$("#autoSwitch").on("change", function () {
if ($(this).prop('checked')) {
wsSendCommand("start");
} else {
wsSendCommand("stop");
}
});
function setMode(mode, finish_funtion) {
console.log("Mode: ", mode);
wsSendCommand("/" + mode);
finish_funtion();
}
function setMainColor() {
var red = $("#rng_red").val();
var green = $("#rng_green").val();
var blue = $("#rng_blue").val();
var mainColorHex = componentToHex(red) + componentToHex(green) + componentToHex(blue);
wsSetMainColor(mainColorHex);
}
// ******************************************************************
// WebSocket commands
// ******************************************************************
function wsSendCommand(cmd) {
console.log("Send WebSocket command:", cmd);
if (ws_waiting == 0) {
connection.send(cmd);
ws_waiting++;
} else {
console.log("++++++++ WS call waiting, skip")
}
}
function wsSetAll(hexColor) {
console.log("wsSetAll() Set all colors to:", hexColor);
wsSendCommand("*" + hexColor);
}
function wsSetMainColor(hexColor) {
console.log("wsSetMainColor() Set main colors to:", hexColor);
wsSendCommand("#" + hexColor);
}
// ******************************************************************
// Colorwheel
// ******************************************************************
// this is supposed to work on mobiles (touch) as well as on a desktop (click)
// since we couldn't find a decent one .. this try of writing one by myself
// + google. swiping would be really nice - I will possibly implement it with
// jquery later - or never.
var canvas = document.getElementById("myCanvas");
// FIX: Cancel touch end event and handle click via touchstart
// canvas.addEventListener("touchend", function(e) { e.preventDefault(); }, false);
canvas.addEventListener("touchmove", doTouch, false);
canvas.addEventListener("click", doClick, false);
//canvas.addEventListener("mousemove", doClick, false);
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var innerRadius = canvas.width / 4.5;
var outerRadius = (canvas.width - 10) / 2
//outer border
context.beginPath();
//outer circle
context.arc(centerX, centerY, outerRadius, 0, 2 * Math.PI, false);
//draw the outer border: (gets drawn around the circle!)
context.lineWidth = 4;
context.strokeStyle = '#000000';
context.stroke();
context.closePath();
//fill with beautiful colors
//taken from here: http://stackoverflow.com/questions/18265804/building-a-color-wheel-in-html5
for(var angle=0; angle<=360; angle+=1) {
var startAngle = (angle-2)*Math.PI/180;
var endAngle = angle * Math.PI/180;
context.beginPath();
context.moveTo(centerX, centerY);
context.arc(centerX, centerY, outerRadius, startAngle, endAngle, false);
context.closePath();
context.fillStyle = 'hsl('+angle+', 100%, 50%)';
context.fill();
context.closePath();
}
//inner border
context.beginPath();
//context.arc(centerX, centerY, radius, startAngle, endAngle, counterClockwise);
context.arc(centerX, centerY, innerRadius, 0, 2 * Math.PI, false);
//fill the center
var my_gradient=context.createLinearGradient(0,0,170,0);
my_gradient.addColorStop(0,"black");
my_gradient.addColorStop(1,"white");
context.fillStyle = my_gradient;
context.fillStyle = "white";
context.fill();
//draw the inner line
context.lineWidth = 2;
context.strokeStyle = '#000000';
context.stroke();
context.closePath();
//get Mouse x/y canvas position
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
//comp to Hex
function componentToHex(c) {
//var hex = c.toString(16);
//return hex.length == 1 ? "0" + hex : hex;
return ("0"+(Number(c).toString(16))).slice(-2).toUpperCase();
}
//rgb/rgba to Hex
function rgbToHex(rgb) {
return componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
}
//display the touch/click position and color info
function updateStatus(pos, color) {
var hexColor = rgbToHex(color);
wsSetAll(hexColor);
hexColor = "#" + hexColor;
$('#status').css("backgroundColor", hexColor);
$('#status_color').text(hexColor + " - R=" + color[0] + ", G=" + color[1] + ", B=" + color[2]);
$('#status_pos').text("x: " + pos.x + " - y: " + pos.y);
$("#rng_red").val(color[0]);
$("#rng_green").val(color[1]);
$("#rng_blue").val(color[2]);
}
//handle the touch event
function doTouch(event) {
//to not also fire on click
event.preventDefault();
var el = event.target;
//touch position
var pos = {x: Math.round(event.targetTouches[0].pageX - el.offsetLeft),
y: Math.round(event.targetTouches[0].pageY - el.offsetTop)};
//color
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
updateStatus(pos, color);
}
function doClick(event) {
//click position
var pos = getMousePos(canvas, event);
//color
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
//console.log("click", pos.x, pos.y, color);
updateStatus(pos, color);
//now do sth with the color rgbToHex(color);
//don't do stuff when #000000 (outside circle and lines
}
// ******************************************************************
// main
// ******************************************************************
init();
}); // end of document ready
})(jQuery); // end of jQuery name space