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';
/**
* 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({
is: 'ha-color-picker',
properties: {
width: {
type: Number,
value: 300,
},
height: {
type: Number,
value: 300,
},
color: {
type: Object,
},
width: {
type: Number,
},
height: {
type: Number,
},
},
listeners: {
@ -64,56 +50,45 @@ export default new Polymer({
},
onTouchMove(ev) {
const touch = ev.touches[0];
this.onColorSelect(ev, {x: touch.clientX, y: touch.clientY});
if (!this.mouseMoveIsThrottled) {
return;
}
this.mouseMoveIsThrottled = false;
this.processColorSelect(ev.touches[0]);
this.async(() => this.mouseMoveIsThrottled = true, 100);
},
onMouseMove(ev) {
ev.preventDefault();
if (this.mouseMoveIsThrottled) {
this.mouseMoveIsThrottled = false;
this.onColorSelect(ev);
this.async(() => this.mouseMoveIsThrottled = true, 100);
if (!this.mouseMoveIsThrottled) {
return;
}
this.mouseMoveIsThrottled = false;
this.processColorSelect(ev);
this.async(() => this.mouseMoveIsThrottled = true, 100);
},
onColorSelect(ev, coords) {
if (this.context) {
const colorCoords = coords || this.relativeMouseCoordinates(ev);
const data = this.context.getImageData(colorCoords.x, colorCoords.y, 1, 1).data;
processColorSelect(ev) {
const rect = this.canvas.getBoundingClientRect();
this.setColor({r: data[0], g: data[1], b: data[2]});
// 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]});
},
setColor(rgb) {
// save calculated color
this.color = {hex: rgbToHex(rgb), rgb: rgb};
this.color = rgb;
this.fire('colorselected', {
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,
};
this.fire('colorselected', {rgb: this.color});
},
ready() {
@ -122,25 +97,34 @@ export default new Polymer({
this.canvas = this.children[0];
this.context = this.canvas.getContext('2d');
const colorGradient = this.context.createLinearGradient(0, 0, this.width, 0);
colorGradient.addColorStop(0, 'rgb(255,0,0)');
colorGradient.addColorStop(0.16, 'rgb(255,0,255)');
colorGradient.addColorStop(0.32, 'rgb(0,0,255)');
colorGradient.addColorStop(0.48, 'rgb(0,255,255)');
colorGradient.addColorStop(0.64, 'rgb(0,255,0)');
colorGradient.addColorStop(0.80, 'rgb(255,255,0)');
colorGradient.addColorStop(1, 'rgb(255,0,0)');
this.context.fillStyle = colorGradient;
this.context.fillRect(0, 0, this.width, this.height);
this.debounce('drawGradient', () => {
const style = getComputedStyle(this);
const width = parseInt(style.width, 10);
const height = parseInt(style.height, 10);
const bwGradient = this.context.createLinearGradient(0, 0, 0, this.height);
bwGradient.addColorStop(0, 'rgba(255,255,255,1)');
bwGradient.addColorStop(0.5, 'rgba(255,255,255,0)');
bwGradient.addColorStop(0.5, 'rgba(0,0,0,0)');
bwGradient.addColorStop(1, 'rgba(0,0,0,1)');
this.width = width;
this.height = height;
this.context.fillStyle = bwGradient;
this.context.fillRect(0, 0, this.width, this.height);
const colorGradient = this.context.createLinearGradient(0, 0, width, 0);
colorGradient.addColorStop(0, 'rgb(255,0,0)');
colorGradient.addColorStop(0.16, 'rgb(255,0,255)');
colorGradient.addColorStop(0.32, 'rgb(0,0,255)');
colorGradient.addColorStop(0.48, 'rgb(0,255,255)');
colorGradient.addColorStop(0.64, 'rgb(0,255,0)');
colorGradient.addColorStop(0.80, 'rgb(255,255,0)');
colorGradient.addColorStop(1, 'rgb(255,0,0)');
this.context.fillStyle = colorGradient;
this.context.fillRect(0, 0, width, height);
const bwGradient = this.context.createLinearGradient(0, 0, 0, height);
bwGradient.addColorStop(0, 'rgba(255,255,255,1)');
bwGradient.addColorStop(0.5, 'rgba(255,255,255,0)');
bwGradient.addColorStop(0.5, 'rgba(0,0,0,0)');
bwGradient.addColorStop(1, 'rgba(0,0,0,1)');
this.context.fillStyle = bwGradient;
this.context.fillRect(0, 0, width, height);
}, 100);
},
});

View File

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