Fix touch events color picker

This commit is contained in:
Paulus Schoutsen 2016-01-02 12:49:40 -08:00
parent a604a2f527
commit 78c348cb7b
2 changed files with 64 additions and 79 deletions

View File

@ -7,35 +7,21 @@
*/ */
import Polymer from '../polymer'; import Polymer from '../polymer';
/**
* given red, green, blue values, return the equivalent hexidecimal value
* base source: http://stackoverflow.com/a/5624139
*/
function componentToHex(comp) {
const hex = comp.toString(16);
return hex.length === 1 ? '0' + hex : hex;
}
function rgbToHex(color) {
return '#' + componentToHex(color.r) + componentToHex(color.g) +
componentToHex(color.b);
}
export default new Polymer({ export default new Polymer({
is: 'ha-color-picker', is: 'ha-color-picker',
properties: { properties: {
width: {
type: Number,
value: 300,
},
height: {
type: Number,
value: 300,
},
color: { color: {
type: Object, type: Object,
}, },
width: {
type: Number,
},
height: {
type: Number,
},
}, },
listeners: { listeners: {
@ -64,56 +50,45 @@ export default new Polymer({
}, },
onTouchMove(ev) { onTouchMove(ev) {
const touch = ev.touches[0]; if (!this.mouseMoveIsThrottled) {
this.onColorSelect(ev, {x: touch.clientX, y: touch.clientY}); return;
}
this.mouseMoveIsThrottled = false;
this.processColorSelect(ev.touches[0]);
this.async(() => this.mouseMoveIsThrottled = true, 100);
}, },
onMouseMove(ev) { onMouseMove(ev) {
ev.preventDefault(); if (!this.mouseMoveIsThrottled) {
if (this.mouseMoveIsThrottled) { return;
this.mouseMoveIsThrottled = false;
this.onColorSelect(ev);
this.async(() => this.mouseMoveIsThrottled = true, 100);
} }
this.mouseMoveIsThrottled = false;
this.processColorSelect(ev);
this.async(() => this.mouseMoveIsThrottled = true, 100);
}, },
onColorSelect(ev, coords) { processColorSelect(ev) {
if (this.context) { const rect = this.canvas.getBoundingClientRect();
const colorCoords = coords || this.relativeMouseCoordinates(ev);
const data = this.context.getImageData(colorCoords.x, colorCoords.y, 1, 1).data; // boundary check because people can move off-canvas.
if (ev.clientX < rect.left || ev.clientX >= rect.left + rect.width ||
ev.clientY < rect.top || ev.clientY >= rect.top + rect.height) {
return;
}
this.onColorSelect(ev.clientX - rect.left, ev.clientY - rect.top);
},
onColorSelect(x, y) {
const data = this.context.getImageData(x, y, 1, 1).data;
this.setColor({r: data[0], g: data[1], b: data[2]}); this.setColor({r: data[0], g: data[1], b: data[2]});
}
}, },
setColor(rgb) { setColor(rgb) {
// save calculated color this.color = rgb;
this.color = {hex: rgbToHex(rgb), rgb: rgb};
this.fire('colorselected', { this.fire('colorselected', {rgb: this.color});
rgb: this.color.rgb,
hex: this.color.hex,
});
},
/**
* given a mouse click event, return x,y coordinates relative to the clicked target
* @returns object with x, y values
*/
relativeMouseCoordinates(ev) {
let xCoord = 0;
let yCoord = 0;
if (this.canvas) {
const rect = this.canvas.getBoundingClientRect();
xCoord = ev.clientX - rect.left;
yCoord = ev.clientY - rect.top;
}
return {
x: xCoord,
y: yCoord,
};
}, },
ready() { ready() {
@ -122,7 +97,15 @@ export default new Polymer({
this.canvas = this.children[0]; this.canvas = this.children[0];
this.context = this.canvas.getContext('2d'); this.context = this.canvas.getContext('2d');
const colorGradient = this.context.createLinearGradient(0, 0, this.width, 0); this.debounce('drawGradient', () => {
const style = getComputedStyle(this);
const width = parseInt(style.width, 10);
const height = parseInt(style.height, 10);
this.width = width;
this.height = height;
const colorGradient = this.context.createLinearGradient(0, 0, width, 0);
colorGradient.addColorStop(0, 'rgb(255,0,0)'); colorGradient.addColorStop(0, 'rgb(255,0,0)');
colorGradient.addColorStop(0.16, 'rgb(255,0,255)'); colorGradient.addColorStop(0.16, 'rgb(255,0,255)');
colorGradient.addColorStop(0.32, 'rgb(0,0,255)'); colorGradient.addColorStop(0.32, 'rgb(0,0,255)');
@ -131,16 +114,17 @@ export default new Polymer({
colorGradient.addColorStop(0.80, 'rgb(255,255,0)'); colorGradient.addColorStop(0.80, 'rgb(255,255,0)');
colorGradient.addColorStop(1, 'rgb(255,0,0)'); colorGradient.addColorStop(1, 'rgb(255,0,0)');
this.context.fillStyle = colorGradient; this.context.fillStyle = colorGradient;
this.context.fillRect(0, 0, this.width, this.height); this.context.fillRect(0, 0, width, height);
const bwGradient = this.context.createLinearGradient(0, 0, 0, this.height); const bwGradient = this.context.createLinearGradient(0, 0, 0, height);
bwGradient.addColorStop(0, 'rgba(255,255,255,1)'); bwGradient.addColorStop(0, 'rgba(255,255,255,1)');
bwGradient.addColorStop(0.5, 'rgba(255,255,255,0)'); bwGradient.addColorStop(0.5, 'rgba(255,255,255,0)');
bwGradient.addColorStop(0.5, 'rgba(0,0,0,0)'); bwGradient.addColorStop(0.5, 'rgba(0,0,0,0)');
bwGradient.addColorStop(1, 'rgba(0,0,0,1)'); bwGradient.addColorStop(1, 'rgba(0,0,0,1)');
this.context.fillStyle = bwGradient; this.context.fillStyle = bwGradient;
this.context.fillRect(0, 0, this.width, this.height); this.context.fillRect(0, 0, width, height);
}, 100);
}, },
}); });

View File

@ -15,7 +15,8 @@
ha-color-picker { ha-color-picker {
display: block; display: block;
width: 350px; max-width: 350px;
height: 200px;
margin: 0 auto; margin: 0 auto;
max-height: 0px; max-height: 0px;
@ -52,7 +53,7 @@
</paper-slider> </paper-slider>
</div> </div>
<ha-color-picker on-colorselected='colorPicked' width='350' height='200'> <ha-color-picker on-colorselected='colorPicked'>
</ha-color-picker> </ha-color-picker>
</div> </div>
</template> </template>