diff --git a/app/components/bridge-controls.js b/app/components/bridge-controls.js
index 8898105..04e607e 100644
--- a/app/components/bridge-controls.js
+++ b/app/components/bridge-controls.js
@@ -107,7 +107,7 @@ export default Em.Component.extend({
},
tabList: ["Lights", "Music"],
- selectedTab: 0,
+ selectedTab: 1,
tabData: function(){
var tabData = [], selectedTab = this.get('selectedTab');
diff --git a/app/components/color-picker.js b/app/components/color-picker.js
new file mode 100644
index 0000000..63c27b0
--- /dev/null
+++ b/app/components/color-picker.js
@@ -0,0 +1,66 @@
+import Em from 'ember';
+
+export default Em.Component.extend({
+ classNames:['colorpicker'],
+
+ // https://dzone.com/articles/creating-your-own-html5
+ didInsertElement: function(){
+ // handle color changes
+ var self = this,
+ canvas = Em.$('#picker')[0].getContext('2d'),
+ image = new Image();
+
+ image.src ='assets/images/colorwheel.png';
+ image.onload = function () {
+ canvas.drawImage(image, 0, 0, image.width, image.height); // draw the image on the canvas
+ };
+ },
+
+ // http://www.developers.meethue.com/documentation/color-conversions-rgb-xy
+ rgbToXy: function(red, green, blue){
+ var X, Y, Z, x, y;
+
+ // normalize
+ red = Number((red/255).toFixed(2));
+ green = Number((green/255).toFixed(2));
+ blue = Number((blue/255).toFixed(2));
+
+ // gamma correction
+ red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92);
+ green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92);
+ blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92);
+
+ // RGB to XYZ
+ X = red * 0.664511 + green * 0.154324 + blue * 0.162028;
+ Y = red * 0.283881 + green * 0.668433 + blue * 0.047685;
+ Z = red * 0.000088 + green * 0.072310 + blue * 0.986039;
+
+ x = X / (X + Y + Z);
+ y = Y / (X + Y + Z);
+
+ return [x,y];
+ },
+
+ xyTorgb: function(x, y){
+ var r, g, b, X, Y, Z, activeLights = this.get('activeLights'), lightsData = this.get('lightsData');
+
+ z = 1 - x - y;
+ Y = lightsData[activeLights[0]].state.bri;
+ X = (Y / y) * x;
+ Z = (Y / y) * z;
+
+ r = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
+ g = -X * 0.707196 + Y * 1.655397 + Z * 0.036152;
+ b = X * 0.051713 - Y * 0.121364 + Z * 1.011530;
+
+ r = r <= 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math.pow(r, (1.0 / 2.4)) - 0.055;
+ g = g <= 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math.pow(g, (1.0 / 2.4)) - 0.055;
+ b = b <= 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math.pow(b, (1.0 / 2.4)) - 0.055;
+
+ r = Math.floor(r * 255);
+ g = Math.floor(g * 255);
+ b = Math.floor(b * 255);
+
+ return [r, g, b];
+ }
+});
diff --git a/app/components/controls/light-control.js b/app/components/controls/light-control.js
index 7b39e79..f2f8c94 100644
--- a/app/components/controls/light-control.js
+++ b/app/components/controls/light-control.js
@@ -12,18 +12,6 @@ export default Em.Component.extend({
isShowingColorPicker: false,
- didInsertElement: function(){
- // handle color changes
- var self = this,
- canvas = $('#picker')[0].getContext('2d'),
- image = new Image();
-
- image.src ='assets/images/colorwheel.png';
- image.onload = function () {
- canvas.drawImage(image, 0, 0, image.width, image.height); // draw the image on the canvas
- };
- },
-
actions: {
clickLight: function(){
console.log('clickLight');
diff --git a/app/components/light-group.js b/app/components/light-group.js
index caebac4..48f694f 100644
--- a/app/components/light-group.js
+++ b/app/components/light-group.js
@@ -44,6 +44,12 @@ export default Em.Component.extend({
}
},
+ didInsertElement: function() {
+ if(this.get('lightsData')){
+ this.onLightsDataChange();
+ }
+ },
+
// list of all the lights in the hue system
onLightsDataChange: function(){
if(!this.get('isHovering')){
diff --git a/app/styles/app.scss b/app/styles/app.scss
index b035fab..1c33f6b 100644
--- a/app/styles/app.scss
+++ b/app/styles/app.scss
@@ -28,6 +28,10 @@ body {
position: static;
}
+.relative {
+ position: relative;
+}
+
#settings {
cursor: pointer;
position: absolute;
@@ -62,7 +66,7 @@ body {
}
.appSettingsItem:hover {
- background: darken(white, 10%);
+ background: darken(white, 20%);
}
.settingsItem.on md-icon.md-default-theme {
@@ -188,20 +192,19 @@ md-list-item .md-no-style {
}
.colorpicker {
- background-color: #222222;
- border-radius: 5px 5px 5px 5px;
- box-shadow: 2px 2px 2px #444444;
+ padding: 10px;
+ background: rgba(0, 0, 0, 0.6);
+ box-shadow: 5px 10px 15px 5px rgba(0, 0, 0, 0.3);
color: #FFFFFF;
- font-size: 12px;
+ z-index: 2;
position: absolute;
- width: 460px;
+ width: 220px;
+ right: 6px;
+ top: -6px;
}
#picker {
cursor: crosshair;
- float: left;
- margin: 10px;
- border: 0;
}
// LIGHT GROUP
@@ -239,7 +242,8 @@ md-slider.md-default-theme .md-thumb:after {
.lightGroup {
margin: 0 auto 0 auto;
.tooltip.top {
- margin-top: 8px;
+ margin-top: -10px;
+ margin-left: -3px;
}
}
@@ -271,7 +275,8 @@ md-slider.md-default-theme .md-thumb:after {
left: 6px;
}
.tooltip.top {
- margin-top: -10px;
+ margin-top: 6px;
+ margin-left: -5px;
}
}
diff --git a/app/templates/components/color-picker.hbs b/app/templates/components/color-picker.hbs
new file mode 100644
index 0000000..48e41a2
--- /dev/null
+++ b/app/templates/components/color-picker.hbs
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/templates/components/controls/light-control.hbs b/app/templates/components/controls/light-control.hbs
index 931a95a..a9ee892 100644
--- a/app/templates/components/controls/light-control.hbs
+++ b/app/templates/components/controls/light-control.hbs
@@ -19,12 +19,12 @@
{{paper-icon icon="color-lens"}}
Color
{{#paper-button raised=true class="color" action="toggleColorpicker"}}{{/paper-button}}
- {{#if isShowingColorPicker}}
-
-
-
- {{/if}}
{{/paper-item}}
+
+ {{#if isShowingColorPicker}}
+ {{color-picker lightsData=lightsData activeLights=activeLights}}
+ {{/if}}
+
{{#paper-item class="item"}}
{{paper-icon icon="flare"}}
diff --git a/ember-cli-build.js b/ember-cli-build.js
index cbf157b..f00946c 100644
--- a/ember-cli-build.js
+++ b/ember-cli-build.js
@@ -7,7 +7,6 @@ module.exports = function(defaults) {
});
app.import('vendor/dancer.js');
- app.import('vendor/colorpicker.js');
app.import('bower_components/bootstrap-sass/assets/javascripts/bootstrap/tooltip.js');
app.import('bower_components/JavaScript-ID3-Reader/dist/id3-minimized.js');
app.import('bower_components/jquery-mousewheel/jquery.mousewheel.js');
diff --git a/public/assets/images/colorwheel.png b/public/assets/images/colorwheel.png
index 7bf9424..3d6d114 100644
Binary files a/public/assets/images/colorwheel.png and b/public/assets/images/colorwheel.png differ
diff --git a/tests/integration/components/color-picker-test.js b/tests/integration/components/color-picker-test.js
new file mode 100644
index 0000000..fb1d925
--- /dev/null
+++ b/tests/integration/components/color-picker-test.js
@@ -0,0 +1,26 @@
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('color-picker', 'Integration | Component | color picker', {
+ integration: true
+});
+
+test('it renders', function(assert) {
+ assert.expect(2);
+
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.on('myAction', function(val) { ... });
+
+ this.render(hbs`{{color-picker}}`);
+
+ assert.equal(this.$().text().trim(), '');
+
+ // Template block usage:
+ this.render(hbs`
+ {{#color-picker}}
+ template block text
+ {{/color-picker}}
+ `);
+
+ assert.equal(this.$().text().trim(), 'template block text');
+});
diff --git a/vendor/colorpicker.js b/vendor/colorpicker.js
deleted file mode 100644
index 71ddc9b..0000000
--- a/vendor/colorpicker.js
+++ /dev/null
@@ -1,152 +0,0 @@
-//https://github.com/bgrins/colorwheel-1k/tree/gh-pages
-(function() {
-
- // Declare constants and variables to help with minification
- // Some of these are inlined (with comments to the side with the actual equation)
- var doc = document;
- doc.c = doc.createElement;
- b.a = b.appendChild;
-
- var width = c.width = c.height = 400,
- label = b.a(doc.c("p")),
- input = b.a(doc.c("input")),
- imageData = a.createImageData(width, width),
- pixels = imageData.data,
- oneHundred = input.value = input.max = 100,
- circleOffset = 10,
- diameter = 380, //width-circleOffset*2,
- radius = 190, //diameter / 2,
- radiusPlusOffset = 200, //radius + circleOffset
- radiusSquared = radius * radius,
- two55 = 255,
- currentY = oneHundred,
- currentX = -currentY,
- wheelPixel = 16040; // circleOffset*4*width+circleOffset*4;
-
- // Math helpers
- var math = Math,
- PI = math.PI,
- PI2 = PI * 2,
- sqrt = math.sqrt,
- atan2 = math.atan2;
-
- // Setup DOM properties
- b.style.textAlign="center";
- label.style.font = "2em courier";
- input.type = "range";
-
- // Load color wheel data into memory.
- for (y = input.min = 0; y < width; y++) {
- for (x = 0; x < width; x++) {
- var rx = x - radius,
- ry = y - radius,
- d = rx * rx + ry * ry,
- rgb = hsvToRgb(
- (atan2(ry, rx) + PI) / PI2, // Hue
- sqrt(d) / radius, // Saturation
- 1 // Value
- );
-
- // Print current color, but hide if outside the area of the circle
- pixels[wheelPixel++] = rgb[0];
- pixels[wheelPixel++] = rgb[1];
- pixels[wheelPixel++] = rgb[2];
- pixels[wheelPixel++] = d > radiusSquared ? 0 : two55;
- }
- }
-
- // Bind Event Handlers
- input.onchange = redraw;
- c.onmousedown = doc.onmouseup = function(e) {
- // Unbind mousemove if this is a mouseup event, or bind mousemove if this a mousedown event
- doc.onmousemove = /p/.test(e.type) ? 0 : (redraw(e), redraw);
- }
-
- // Handle manual calls + mousemove event handler + input change event handler all in one place.
- function redraw(e) {
-
- // Only process an actual change if it is triggered by the mousemove or mousedown event.
- // Otherwise e.pageX will be undefined, which will cause the result to be NaN, so it will fallback to the current value
- currentX = e.pageX - c.offsetLeft - radiusPlusOffset || currentX;
- currentY = e.pageY - c.offsetTop - radiusPlusOffset || currentY;
-
- // Scope these locally so the compiler will minify the names. Will manually remove the 'var' keyword in the minified version.
- var theta = atan2(currentY, currentX),
- d = currentX * currentX + currentY * currentY;
-
- // If the x/y is not in the circle, find angle between center and mouse point:
- // Draw a line at that angle from center with the distance of radius
- // Use that point on the circumference as the draggable location
- if (d > radiusSquared) {
- currentX = radius * math.cos(theta);
- currentY = radius * math.sin(theta);
- theta = atan2(currentY, currentX);
- d = currentX * currentX + currentY * currentY;
- }
-
- label.textContent = b.style.background = hsvToRgb(
- (theta + PI) / PI2, // Current hue (how many degrees along the circle)
- sqrt(d) / radius, // Current saturation (how close to the middle)
- input.value / oneHundred // Current value (input type="range" slider value)
- )[3];
-
- // Reset to color wheel and draw a spot on the current location.
- a.putImageData(imageData, 0, 0);
-
- // Draw the current spot.
- // I have tried a rectangle, circle, and heart shape.
- /*
- // Rectangle:
- a.fillStyle = '#000';
- a.fillRect(currentX+radiusPlusOffset,currentY+radiusPlusOffset, 6, 6);
- */
- /*
- // Circle:
- a.beginPath();
- a.strokeStyle = '#000';
- a.arc(~~currentX+radiusPlusOffset,~~currentY+radiusPlusOffset, 4, 0, PI2);
- a.stroke();
- */
-
- // Heart:
- a.font = "1em arial";
- a.fillText("♥", currentX+radiusPlusOffset-4,currentY+radiusPlusOffset+4);
-
- }
-
- // Created a shorter version of the HSV to RGB conversion function in TinyColor
- // https://github.com/bgrins/TinyColor/blob/master/tinycolor.js
- function hsvToRgb(h, s, v) {
- h*=6;
- var i = ~~h,
- f = h - i,
- p = v * (1 - s),
- q = v * (1 - f * s),
- t = v * (1 - (1 - f) * s),
- mod = i % 6,
- r = [v, q, p, p, t, v][mod] * two55,
- g = [t, v, v, q, p, p][mod] * two55,
- b = [p, p, t, v, v, q][mod] * two55;
-
- return [r, g, b, "rgb("+ ~~r + "," + ~~g + "," + ~~b + ")"];
- }
-
- // Kick everything off
- redraw(0);
-
- /*
- // Just an idea I had to kick everything off with some changing colors…
- // Probably no way to squeeze this into 1k, but it could probably be a lot smaller than this:
- currentX = currentY = 1;
- var interval = setInterval(function() {
- currentX--;
- currentY*=1.05;
- redraw(0)
- }, 7);
-
- setTimeout(function() {
- clearInterval(interval)
- }, 700)
- */
-
-})();