diff --git a/colorpicker.js b/colorpicker.js index 9f7885f..cd5bba0 100644 --- a/colorpicker.js +++ b/colorpicker.js @@ -4,6 +4,23 @@ */ (function(window, document, undefined) { + function add_on_clicked_mouse_move_listener(element, callback) { + var down = false; + function mouse_down(evt) {down = true; mouse_move(evt);} + function mouse_up(evt) {down = false; evt.preventDefault && evt.preventDefault();} + function mouse_move(evt) {down && callback(mousePosition(evt))} + function attach(element, event_name, callback) { + if (element.attachEvent) { + element.attachEvent('on' + event_name, callback); + } else if (element.addEventListener) { + element.addEventListener(event_name, callback, false); + } + } + attach(element, 'mousedown', mouse_down); + attach(element, 'mousemove', mouse_move); + attach(document, 'mouseup', mouse_up); + } + var type = (window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML"), picker, slide, hueOffset = 15, svgNS = 'http://www.w3.org/2000/svg'; @@ -20,6 +37,7 @@ return { x: evt.offsetX, y: evt.offsetY }; } // Firefox: + evt.preventDefault(); var wrapper = evt.target.parentNode.parentNode; return { x: evt.layerX - wrapper.offsetLeft, y: evt.layerY - wrapper.offsetTop }; } @@ -142,7 +160,7 @@ if (r > 1 || g > 1 || b > 1) { r /= 255; g /= 255; - b /= 255; + b /= 255; } var H, S, V, C; V = Math.max(r, g, b); @@ -156,40 +174,6 @@ return { h: H, s: S, v: V }; } - /** - * Return click event handler for the slider. - * Sets picker background color and calls ctx.callback if provided. - */ - function slideListener(ctx, slideElement, pickerElement) { - return function(evt) { - evt = evt || window.event; - var mouse = mousePosition(evt); - ctx.h = mouse.y / slideElement.offsetHeight * 360 + hueOffset; - ctx.s = ctx.v = 1; - var c = hsv2rgb(ctx.h, 1, 1); - pickerElement.style.backgroundColor = c.hex; - ctx.callback && ctx.callback(c.hex, { h: ctx.h - hueOffset, s: ctx.s, v: ctx.v }, { r: c.r, g: c.g, b: c.b }, undefined, mouse); - } - }; - - /** - * Return click event handler for the picker. - * Calls ctx.callback if provided. - */ - function pickerListener(ctx, pickerElement) { - return function(evt) { - evt = evt || window.event; - var mouse = mousePosition(evt), - width = pickerElement.offsetWidth, - height = pickerElement.offsetHeight; - - ctx.s = mouse.x / width; - ctx.v = (height - mouse.y) / height; - var c = hsv2rgb(ctx.h, ctx.s, ctx.v); - ctx.callback && ctx.callback(c.hex, { h: ctx.h - hueOffset, s: ctx.s, v: ctx.v }, { r: c.r, g: c.g, b: c.b }, mouse); - } - }; - /** * ColorPicker. * @param {DOMElement} slideElement HSV slide element. @@ -198,7 +182,39 @@ */ function ColorPicker(slideElement, pickerElement, callback) { if (!(this instanceof ColorPicker)) return new ColorPicker(slideElement, pickerElement, callback); - + var self = this; + + /** + * Mouse move event handler for the slider. + * Sets picker background color and calls ctx.callback if provided. + */ + + slideMouseMove = function(mouse) { + self.h = mouse.y / self.slideElement.offsetHeight * 360 + hueOffset; + self.s = self.v = 1; + var c = hsv2rgb(self.h, 1, 1); + self.pickerElement.style.backgroundColor = c.hex; + self.callback && self.callback(c.hex, { h: self.h - hueOffset, s: self.s, v: self.v }, { r: c.r, g: c.g, b: c.b }, undefined, mouse); + } + + add_on_clicked_mouse_move_listener(slideElement, slideMouseMove); + + /** + * Mouse move event handler for the picker. + * Calls this.callback if provided. + */ + pickerMouseMove = function(mouse) { + var width = self.pickerElement.offsetWidth, + height = self.pickerElement.offsetHeight; + + self.s = mouse.x / width; + self.v = (height - mouse.y) / height; + var c = hsv2rgb(self.h, self.s, self.v); + self.callback && self.callback(c.hex, { h: self.h - hueOffset, s: self.s, v: self.v }, { r: c.r, g: c.g, b: c.b }, mouse); + } + + add_on_clicked_mouse_move_listener(pickerElement, pickerMouseMove); + this.callback = callback; this.h = 0; this.s = 1; @@ -211,15 +227,7 @@ pickerElement.appendChild(picker.cloneNode(true)); } else { slideElement.innerHTML = slide; - pickerElement.innerHTML = picker; - } - - if (slideElement.attachEvent) { - slideElement.attachEvent('onclick', slideListener(this, slideElement, pickerElement)); - pickerElement.attachEvent('onclick', pickerListener(this, pickerElement)); - } else if (slideElement.addEventListener) { - slideElement.addEventListener('click', slideListener(this, slideElement, pickerElement), false); - pickerElement.addEventListener('click', pickerListener(this, pickerElement), false); + pickerElement.innerHTML = picker; } }; @@ -283,6 +291,8 @@ * @param {object} mousePicker Coordinates of the mouse cursor in the picker area. */ ColorPicker.positionIndicators = function(slideIndicator, pickerIndicator, mouseSlide, mousePicker) { + slideIndicator.style.pointerEvents = "none"; + pickerIndicator.style.pointerEvents = "none"; if (mouseSlide) { pickerIndicator.style.left = 'auto'; pickerIndicator.style.right = '0px';