I have a color-wheel picker (which I took a good chunk of code from this library). I'm trying to get the color-wheels cursor to not go out of boundaries. I don't want it going pass the gray border.
I can do the obvious and make the parent div
: overflow:hidden
, but that would just hide the cursor, it wouldn't make it not go pass the boundaries.
I think the relevant variable to edit, is one of the following (in the hsvMove
function, starting on line 39):
var r = currentTargetHeight / 2,
x = e.pageX - startPoint.left - r,
y = e.pageY - startPoint.top - r
How can I get the cursor to not go past the boundaries?
(function(window) {
"use strict"
// Some common use variables
var myColor = new Colors(),
startPoint,
currentTarget,
currentTargetHeight = 0,
PI = Math.PI,
PI2 = PI * 2;
/* ---------------------------------- */
/* ---- HSV-circle color picker ----- */
/* ---------------------------------- */
var colorDiskWrapper = document.getElementById('colorDiskWrapper'),
colorDiskCursor = document.getElementById('colorDiskCursor'),
colorDisk = document.getElementById('colorDisk');
var colorDiscRadius = colorDisk.offsetHeight / 2;
// Create Event Functions
var hsvDown = function(e) { // mouseDown callback
var target = e.target || e.srcElement;
if (e.preventDefault) e.preventDefault();
if (target === colorDiskCursor || target === colorDisk) {
currentTarget = target.parentNode;
} else
return;
startPoint = getOrigin(currentTarget);
currentTargetHeight = currentTarget.offsetHeight;
addEvent(window, 'mousemove', hsvMove);
hsvMove(e);
startRender();
},
hsvMove = function(e) { // mouseMove callback
var r = currentTargetHeight / 2,
x = e.pageX - startPoint.left - r,
y = e.pageY - startPoint.top - r,
h = 360 - ((Math.atan2(y, x) * 180 / PI) + (y < 0 ? 360 : 0)),
s = (Math.sqrt((x * x) + (y * y)) / r) * 100;
myColor.setColor({
h: h,
s: s
}, 'hsv');
},
renderHSVPicker = function(color) { // used in renderCallback of 'new ColorPicker'
var x = Math.cos(PI2 - color.hsv.h * PI2),
y = Math.sin(PI2 - color.hsv.h * PI2),
r = color.hsv.s * colorDiscRadius;
// Position the Cursor
colorDiskCursor.style.left = (x * r + colorDiscRadius) + 'px';
colorDiskCursor.style.top = (y * r + colorDiscRadius) + 'px';
};
addEvent(colorDiskWrapper, 'mousedown', hsvDown); // event delegation
addEvent(window, 'mouseup', function() {
removeEvent(window, 'mousemove', hsvMove);
stopRender();
});
var doRender = function(color) {
renderHSVPicker(color);
},
renderTimer,
startRender = function(oneTime) {
if (oneTime) { // only Colors is instanciated
doRender(myColor.colors);
} else {
renderTimer = window.setInterval(
function() {
doRender(myColor.colors);
// http://stackoverflow.com/questions/2940054/
}, 13); // 1000 / 60); // ~16.666 -> 60Hz or 60fps
}
},
stopRender = function() {
window.clearInterval(renderTimer);
};
/*
Function Helpers
*/
function getOrigin(elm) {
var box = (elm.getBoundingClientRect) ? elm.getBoundingClientRect() : {
top: 0,
left: 0
},
doc = elm && elm.ownerDocument,
body = doc.body,
win = doc.defaultView || doc.parentWindow || window,
docElem = doc.documentElement || body.parentNode,
clientTop = docElem.clientTop || body.clientTop || 0, // border on html or body or both
clientLeft = docElem.clientLeft || body.clientLeft || 0;
return {
left: box.left + (win.pageXOffset || docElem.scrollLeft) - clientLeft,
top: box.top + (win.pageYOffset || docElem.scrollTop) - clientTop
};
}
function addEvent(obj, type, func) {
addEvent.cache = addEvent.cache || {
_get: function(obj, type, func, checkOnly) {
var cache = addEvent.cache[type] || [];
for (var n = cache.length; n--;) {
if (obj === cache[n].obj && '' + func === '' + cache[n].func) {
func = cache[n].func;
if (!checkOnly) {
cache[n] = cache[n].obj = cache[n].func = null;
cache.splice(n, 1);
}
return func;
}
}
},
_set: function(obj, type, func) {
var cache = addEvent.cache[type] = addEvent.cache[type] || [];
if (addEvent.cache._get(obj, type, func, true)) {
return true;
} else {
cache.push({
func: func,
obj: obj
});
}
}
};
if (!func.name && addEvent.cache._set(obj, type, func) || typeof func !== 'function') {
return;
}
if (obj.addEventListener) obj.addEventListener(type, func, false);
else obj.attachEvent('on' + type, func);
}
function removeEvent(obj, type, func) {
if (typeof func !== 'function') return;
if (!func.name) {
func = addEvent.cache._get(obj, type, func) || func;
}
if (obj.removeEventListener) obj.removeEventListener(type, func, false);
else obj.detachEvent('on' + type, func);
}
})(window);
#colorDisk {
background-image: url("http://i.imgur.com/tX5NbWs.png");
width: 350px;
height: 350px;
background-repeat: no-repeat;
cursor: pointer;
}
#colorDiskCursor {
position: absolute;
border: 2px solid black;
border-radius: 50%;
width: 9px;
height: 9px;
cursor: pointer;
}
<div id="colorDiskWrapper">
<div id="colorDisk"></div>
<div id="colorDiskCursor"></div>
</div>
<script src="https://rawgit.com/PitPik/colorPicker/master/colors.js"></script>