diff --git a/colorpicker.js b/colorpicker.js
index e13892c..4976ff2 100644
--- a/colorpicker.js
+++ b/colorpicker.js
@@ -9,9 +9,9 @@
// This HTML snippet is inserted into the innerHTML property of the passed color picker element
// when the no-hassle call to ColorPicker() is used, i.e. ColorPicker(function(hex, hsv, rgb) { ... });
-
+
var colorpickerHTMLSnippet = [
-
+
'
',
'
',
'
',
@@ -20,7 +20,7 @@
'
',
'
',
'
'
-
+
].join('');
/**
@@ -62,7 +62,7 @@
slide = $('svg', { xmlns: 'http://www.w3.org/2000/svg', version: '1.1', width: '100%', height: '100%' },
[
$('defs', {},
- $('linearGradient', { id: 'gradient-hsv', x1: '0%', y1: '100%', x2: '0%', y2: '0%'},
+ $('linearGradient', { id: 'gradient-hsv', x1: '', y1: '', x2: '0%', y2: '0%'},
[
$('stop', { offset: '0%', 'stop-color': '#FF0000', 'stop-opacity': '1' }),
$('stop', { offset: '13%', 'stop-color': '#FF00FF', 'stop-opacity': '1' }),
@@ -122,7 +122,7 @@
'',
''
].join('');
-
+
if (!document.namespaces['v'])
document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');
}
@@ -134,7 +134,7 @@
function hsv2rgb(hsv) {
var R, G, B, X, C;
var h = (hsv.h % 360) / 60;
-
+
C = hsv.v * hsv.s;
X = C * (1 - Math.abs(h % 2 - 1));
R = G = B = hsv.v - C;
@@ -160,7 +160,7 @@
var r = rgb.r;
var g = rgb.g;
var b = rgb.b;
-
+
if (rgb.r > 1 || rgb.g > 1 || rgb.b > 1) {
r /= 255;
g /= 255;
@@ -171,9 +171,9 @@
V = Math.max(r, g, b);
C = V - Math.min(r, g, b);
H = (C == 0 ? null :
- V == r ? (g - b) / C + (g < b ? 6 : 0) :
- V == g ? (b - r) / C + 2 :
- (r - g) / C + 4);
+ V == r ? (g - b) / C + (g < b ? 6 : 0) :
+ V == g ? (b - r) / C + 2 :
+ (r - g) / C + 4);
H = (H % 6) * 60;
S = C == 0 ? 0 : C / V;
return { h: H, s: S, v: V };
@@ -182,12 +182,14 @@
/**
* 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.h = (slideElement.offsetHeight > slideElement.offsetWidth)
+ ? mouse.y / slideElement.offsetHeight * 360 + hueOffset
+ : mouse.x / slideElement.offsetWidth * 360 + hueOffset;
var pickerColor = hsv2rgb({ h: ctx.h, s: 1, v: 1 });
var c = hsv2rgb({ h: ctx.h, s: ctx.s, v: ctx.v });
pickerElement.style.backgroundColor = pickerColor.hex;
@@ -198,12 +200,12 @@
/**
* 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,
+ width = pickerElement.offsetWidth,
height = pickerElement.offsetHeight;
ctx.s = mouse.x / width;
@@ -214,7 +216,7 @@
};
var uniqID = 0;
-
+
/**
* ColorPicker.
* @param {DOMElement} slideElement HSV slide element.
@@ -222,7 +224,7 @@
* @param {Function} callback Called whenever the color is changed provided chosen color in RGB HEX format as the only argument.
*/
function ColorPicker(slideElement, pickerElement, callback) {
-
+
if (!(this instanceof ColorPicker)) return new ColorPicker(slideElement, pickerElement, callback);
this.h = 0;
@@ -234,23 +236,23 @@
var element = slideElement;
element.innerHTML = colorpickerHTMLSnippet;
-
+
this.slideElement = element.getElementsByClassName('slide')[0];
this.pickerElement = element.getElementsByClassName('picker')[0];
var slideIndicator = element.getElementsByClassName('slide-indicator')[0];
var pickerIndicator = element.getElementsByClassName('picker-indicator')[0];
-
+
ColorPicker.fixIndicators(slideIndicator, pickerIndicator);
this.callback = function(hex, hsv, rgb, pickerCoordinate, slideCoordinate) {
ColorPicker.positionIndicators(slideIndicator, pickerIndicator, slideCoordinate, pickerCoordinate);
-
+
pickerElement(hex, hsv, rgb);
};
-
+
} else {
-
+
this.callback = callback;
this.pickerElement = pickerElement;
this.slideElement = slideElement;
@@ -263,20 +265,31 @@
var slideClone = slide.cloneNode(true);
var pickerClone = picker.cloneNode(true);
-
+
var hsvGradient = slideClone.getElementsByTagName('linearGradient')[0];
-
+
var hsvRect = slideClone.getElementsByTagName('rect')[0];
-
+
hsvGradient.id = 'gradient-hsv-' + uniqID;
hsvRect.setAttribute('fill', 'url(#' + hsvGradient.id + ')');
+ if (this.slideElement.offsetHeight > this.slideElement.offsetWidth) {
+
+ hsvGradient.setAttribute('x1', '0%');
+ hsvGradient.setAttribute('y1', '100%');
+
+ } else {
+
+ hsvGradient.setAttribute('x1', '100%');
+ hsvGradient.setAttribute('y1', '0%');
+ }
+
var blackAndWhiteGradients = [pickerClone.getElementsByTagName('linearGradient')[0], pickerClone.getElementsByTagName('linearGradient')[1]];
var whiteAndBlackRects = pickerClone.getElementsByTagName('rect');
-
+
blackAndWhiteGradients[0].id = 'gradient-black-' + uniqID;
blackAndWhiteGradients[1].id = 'gradient-white-' + uniqID;
-
+
whiteAndBlackRects[0].setAttribute('fill', 'url(#' + blackAndWhiteGradients[1].id + ')');
whiteAndBlackRects[1].setAttribute('fill', 'url(#' + blackAndWhiteGradients[0].id + ')');
@@ -284,11 +297,11 @@
this.pickerElement.appendChild(pickerClone);
uniqID++;
-
+
} else {
-
+
this.slideElement.innerHTML = slide;
- this.pickerElement.innerHTML = picker;
+ this.pickerElement.innerHTML = picker;
}
addEventListener(this.slideElement, 'click', slideListener(this, this.slideElement, this.pickerElement));
@@ -301,9 +314,9 @@
function addEventListener(element, event, listener) {
if (element.attachEvent) {
-
+
element.attachEvent('on' + event, listener);
-
+
} else if (element.addEventListener) {
element.addEventListener(event, listener, false);
@@ -317,7 +330,7 @@
* @param {Function} listener Function that will be called whenever mouse is dragged over the element with event object as argument.
*/
function enableDragging(ctx, element, listener) {
-
+
var mousedown = false;
addEventListener(element, 'mousedown', function(evt) { mousedown = true; });
@@ -326,7 +339,7 @@
addEventListener(element, 'mousemove', function(evt) {
if (mousedown) {
-
+
listener(evt);
}
});
@@ -338,21 +351,21 @@
delete rgbHex.hex;
return rgbHex;
};
-
+
ColorPicker.hsv2hex = function(hsv) {
return hsv2rgb(hsv).hex;
};
-
+
ColorPicker.rgb2hsv = rgb2hsv;
ColorPicker.rgb2hex = function(rgb) {
return hsv2rgb(rgb2hsv(rgb)).hex;
};
-
+
ColorPicker.hex2hsv = function(hex) {
return rgb2hsv(ColorPicker.hex2rgb(hex));
};
-
+
ColorPicker.hex2rgb = function(hex) {
return { r: parseInt(hex.substr(1, 2), 16), g: parseInt(hex.substr(3, 2), 16), b: parseInt(hex.substr(5, 2), 16) };
};
@@ -364,29 +377,38 @@
* @param {object} rgb Object of the form: { r: , g: , b: }.
* @param {string} hex String of the form: #RRGGBB.
*/
- function setColor(ctx, hsv, rgb, hex) {
- ctx.h = hsv.h % 360;
- ctx.s = hsv.s;
- ctx.v = hsv.v;
-
- var c = hsv2rgb(ctx);
-
- var mouseSlide = {
- y: (ctx.h * ctx.slideElement.offsetHeight) / 360,
- x: 0 // not important
- };
-
- var pickerHeight = ctx.pickerElement.offsetHeight;
-
- var mousePicker = {
- x: ctx.s * ctx.pickerElement.offsetWidth,
- y: pickerHeight - ctx.v * pickerHeight
- };
-
- ctx.pickerElement.style.backgroundColor = hsv2rgb({ h: ctx.h, s: 1, v: 1 }).hex;
- ctx.callback && ctx.callback(hex || c.hex, { h: ctx.h, s: ctx.s, v: ctx.v }, rgb || { r: c.r, g: c.g, b: c.b }, mousePicker, mouseSlide);
-
- return ctx;
+ function setColor(ctx, hsv, rgb, hex) {
+ ctx.h = hsv.h % 360;
+ ctx.s = hsv.s;
+ ctx.v = hsv.v;
+
+ var c = hsv2rgb(ctx);
+
+ var mouseSlide;
+
+ if (ctx.slideElement.offsetHeight > ctx.slideElement.offsetWidth) {
+ mouseSlide = {
+ y: (ctx.h * ctx.slideElement.offsetHeight) / 360,
+ x: 0 // not important
+ };
+ } else {
+ mouseSlide = {
+ x: (ctx.h * ctx.slideElement.offsetWidth) / 360,
+ y: 0, // not important
+ };
+ }
+
+ var pickerHeight = ctx.pickerElement.offsetHeight;
+
+ var mousePicker = {
+ x: ctx.s * ctx.pickerElement.offsetWidth,
+ y: pickerHeight - ctx.v * pickerHeight
+ };
+
+ ctx.pickerElement.style.backgroundColor = hsv2rgb({ h: ctx.h, s: 1, v: 1 }).hex;
+ ctx.callback && ctx.callback(hex || c.hex, { h: ctx.h, s: ctx.s, v: ctx.v }, rgb || { r: c.r, g: c.g, b: c.b }, mousePicker, mouseSlide);
+
+ return ctx;
};
/**
@@ -396,7 +418,7 @@
ColorPicker.prototype.setHsv = function(hsv) {
return setColor(this, hsv);
};
-
+
/**
* Sets color of the picker in rgb format.
* @param {object} rgb Object of the form: { r: , g: , b: }.
@@ -421,14 +443,18 @@
* @param {object} mousePicker Coordinates of the mouse cursor in the picker area.
*/
ColorPicker.positionIndicators = function(slideIndicator, pickerIndicator, mouseSlide, mousePicker) {
-
+
if (mouseSlide) {
- slideIndicator.style.top = (mouseSlide.y - slideIndicator.offsetHeight/2) + 'px';
+ if (slideIndicator.offsetHeight > slideIndicator.offsetWidth) {
+ slideIndicator.style.top = (mouseSlide.y - slideIndicator.offsetHeight/2) + 'px';
+ } else {
+ slideIndicator.style.left = (mouseSlide.x - slideIndicator.offsetWidth/2) + 'px';
+ }
}
if (mousePicker) {
pickerIndicator.style.top = (mousePicker.y - pickerIndicator.offsetHeight/2) + 'px';
pickerIndicator.style.left = (mousePicker.x - pickerIndicator.offsetWidth/2) + 'px';
- }
+ }
};
/**
diff --git a/colorpicker.min.js b/colorpicker.min.js
index cce312e..69f7f89 100644
--- a/colorpicker.min.js
+++ b/colorpicker.min.js
@@ -1 +1,14 @@
-(function(s,t,u){var v=(s.SVGAngle||t.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';var w=['',''].join('');function mousePosition(a){if(s.event&&s.event.contentOverflow!==u){return{x:s.event.offsetX,y:s.event.offsetY}}if(a.offsetX!==u&&a.offsetY!==u){return{x:a.offsetX,y:a.offsetY}}var b=a.target.parentNode.parentNode;return{x:a.layerX-b.offsetLeft,y:a.layerY-b.offsetTop}}function $(a,b,c){a=t.createElementNS(svgNS,a);for(var d in b)a.setAttribute(d,b[d]);if(Object.prototype.toString.call(c)!='[object Array]')c=[c];var i=0,len=(c[0]&&c.length)||0;for(;i','','','',''].join('');picker=['','','','','','','','
'].join('');if(!t.namespaces['v'])t.namespaces.add('v','urn:schemas-microsoft-com:vml','#default#VML')}function hsv2rgb(a){var R,G,B,X,C;var h=(a.h%360)/60;C=a.v*a.s;X=C*(1-Math.abs(h%2-1));R=G=B=a.v-C;h=~~h;R+=[C,X,0,0,X,C][h];G+=[X,C,C,X,0,0][h];B+=[0,0,X,C,C,X][h];var r=Math.floor(R*255);var g=Math.floor(G*255);var b=Math.floor(B*255);return{r:r,g:g,b:b,hex:"#"+(16777216|b|(g<<8)|(r<<16)).toString(16).slice(1)}}function rgb2hsv(a){var r=a.r;var g=a.g;var b=a.b;if(a.r>1||a.g>1||a.b>1){r/=255;g/=255;b/=255}var H,S,V,C;V=Math.max(r,g,b);C=V-Math.min(r,g,b);H=(C==0?null:V==r?(g-b)/C+(gb.offsetWidth?d.y/b.offsetHeight*360+15:d.x/b.offsetWidth*360+15;var g=l({h:a.h,s:1,v:1}),f=l({h:a.h,s:a.s,v:a.v});c.style.backgroundColor=g.hex;a.callback&&a.callback(f.hex,{h:a.h-15,s:a.s,v:a.v},{r:f.r,g:f.g,b:f.b},n,d)}}function z(a,b){return function(c){c=c||k.event;c=x(c);var d=b.offsetHeight;a.s=c.x/b.offsetWidth;a.v=(d-c.y)/d;d=l(a);a.callback&&a.callback(d.hex,{h:a.h-15,s:a.s,v:a.v},{r:d.r,g:d.g,b:d.b},c)}}function h(a,b,c){if(!(this instanceof
+h))return new h(a,b,c);this.h=0;this.v=this.s=1;if(c)this.callback=c,this.pickerElement=b,this.slideElement=a;else{a.innerHTML='';this.slideElement=a.getElementsByClassName("slide")[0];this.pickerElement=a.getElementsByClassName("picker")[0];var d=a.getElementsByClassName("slide-indicator")[0],g=a.getElementsByClassName("picker-indicator")[0];
+h.fixIndicators(d,g);this.callback=function(a,c,e,f,k){h.positionIndicators(d,g,k,f);b(a,c,e)}}if("SVG"==v){a=r.cloneNode(!0);c=t.cloneNode(!0);var f=a.getElementsByTagName("linearGradient")[0],e=a.getElementsByTagName("rect")[0];f.id="gradient-hsv-"+u;e.setAttribute("fill","url(#"+f.id+")");this.slideElement.offsetHeight>this.slideElement.offsetWidth?(f.setAttribute("x1","0%"),f.setAttribute("y1","100%")):(f.setAttribute("x1","100%"),f.setAttribute("y1","0%"));f=[c.getElementsByTagName("linearGradient")[0],
+c.getElementsByTagName("linearGradient")[1]];e=c.getElementsByTagName("rect");f[0].id="gradient-black-"+u;f[1].id="gradient-white-"+u;e[0].setAttribute("fill","url(#"+f[1].id+")");e[1].setAttribute("fill","url(#"+f[0].id+")");this.slideElement.appendChild(a);this.pickerElement.appendChild(c);u++}else this.slideElement.innerHTML=r,this.pickerElement.innerHTML=t;m(this.slideElement,"click",y(this,this.slideElement,this.pickerElement));m(this.pickerElement,"click",z(this,this.pickerElement));A(this,
+this.slideElement,y(this,this.slideElement,this.pickerElement));A(this,this.pickerElement,z(this,this.pickerElement))}function m(a,b,c){a.attachEvent?a.attachEvent("on"+b,c):a.addEventListener&&a.addEventListener(b,c,!1)}function A(a,b,c){var d=!1;m(b,"mousedown",function(a){d=!0});m(b,"mouseup",function(a){d=!1});m(b,"mouseout",function(a){d=!1});m(b,"mousemove",function(a){d&&c(a)})}function w(a,b,c,d){a.h=b.h%360;a.s=b.s;a.v=b.v;b=l(a);var e;e=a.slideElement.offsetHeight>a.slideElement.offsetWidth?
+{y:a.h*a.slideElement.offsetHeight/360,x:0}:{x:a.h*a.slideElement.offsetWidth/360,y:0};var f=a.pickerElement.offsetHeight,f={x:a.s*a.pickerElement.offsetWidth,y:f-a.v*f};a.pickerElement.style.backgroundColor=l({h:a.h,s:1,v:1}).hex;a.callback&&a.callback(d||b.hex,{h:a.h,s:a.s,v:a.v},c||{r:b.r,g:b.g,b:b.b},f,e);return a}var v=k.SVGAngle||p.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML",t,r;"SVG"==v?(r=e("svg",{xmlns:"http://www.w3.org/2000/svg",version:"1.1",
+width:"100%",height:"100%"},[e("defs",{},e("linearGradient",{id:"gradient-hsv",x1:"",y1:"",x2:"0%",y2:"0%"},[e("stop",{offset:"0%","stop-color":"#FF0000","stop-opacity":"1"}),e("stop",{offset:"13%","stop-color":"#FF00FF","stop-opacity":"1"}),e("stop",{offset:"25%","stop-color":"#8000FF","stop-opacity":"1"}),e("stop",{offset:"38%","stop-color":"#0040FF","stop-opacity":"1"}),e("stop",{offset:"50%","stop-color":"#00FFFF","stop-opacity":"1"}),e("stop",{offset:"63%","stop-color":"#00FF40","stop-opacity":"1"}),
+e("stop",{offset:"75%","stop-color":"#0BED00","stop-opacity":"1"}),e("stop",{offset:"88%","stop-color":"#FFFF00","stop-opacity":"1"}),e("stop",{offset:"100%","stop-color":"#FF0000","stop-opacity":"1"})])),e("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:"url(#gradient-hsv)"})]),t=e("svg",{xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"100%",height:"100%"},[e("defs",{},[e("linearGradient",{id:"gradient-black",x1:"0%",y1:"100%",x2:"0%",y2:"0%"},[e("stop",{offset:"0%","stop-color":"#000000",
+"stop-opacity":"1"}),e("stop",{offset:"100%","stop-color":"#CC9A81","stop-opacity":"0"})]),e("linearGradient",{id:"gradient-white",x1:"0%",y1:"100%",x2:"100%",y2:"100%"},[e("stop",{offset:"0%","stop-color":"#FFFFFF","stop-opacity":"1"}),e("stop",{offset:"100%","stop-color":"#CC9A81","stop-opacity":"0"})])]),e("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:"url(#gradient-white)"}),e("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:"url(#gradient-black)"})])):"VML"==v&&(r='
',
+t='
',
+p.namespaces.v||p.namespaces.add("v","urn:schemas-microsoft-com:vml","#default#VML"));var u=0;h.hsv2rgb=function(a){a=l(a);delete a.hex;return a};h.hsv2hex=function(a){return l(a).hex};h.rgb2hsv=q;h.rgb2hex=function(a){return l(q(a)).hex};h.hex2hsv=function(a){return q(h.hex2rgb(a))};h.hex2rgb=function(a){return{r:parseInt(a.substr(1,2),16),g:parseInt(a.substr(3,2),16),b:parseInt(a.substr(5,2),16)}};h.prototype.setHsv=function(a){return w(this,a)};h.prototype.setRgb=function(a){return w(this,q(a),
+a)};h.prototype.setHex=function(a){return w(this,h.hex2hsv(a),n,a)};h.positionIndicators=function(a,b,c,d){c&&(a.offsetHeight>a.offsetWidth?a.style.top=c.y-a.offsetHeight/2+"px":a.style.left=c.x-a.offsetWidth/2+"px");d&&(b.style.top=d.y-b.offsetHeight/2+"px",b.style.left=d.x-b.offsetWidth/2+"px")};h.fixIndicators=function(a,b){b.style.pointerEvents="none";a.style.pointerEvents="none"};k.ColorPicker=h})(window,window.document);