Javascript 将div定位在精确的光标位置

Javascript 将div定位在精确的光标位置,javascript,html,css,Javascript,Html,Css,我正在使用它,我正在尝试添加一个div作为dragger,而不是将其嵌入画布中。多亏了你,我才使它运转起来 问题是,拖动器离光标有点远。显而易见的解决方案是从拖动器的左和顶位置减去。像这样: dragger.style.left = (currentX + radiusPlusOffset - 13) + 'px'; dragger.style.top = (currentY + radiusPlusOffset - 13) + 'px'; 当我减去13时,另一个问题出现了。如果将拖动器一直拖

我正在使用它,我正在尝试添加一个
div
作为dragger,而不是将其嵌入画布中。多亏了你,我才使它运转起来

问题是,拖动器离光标有点远。显而易见的解决方案是从
拖动器的左
位置减去。像这样:

dragger.style.left = (currentX + radiusPlusOffset - 13) + 'px';
dragger.style.top = (currentY + radiusPlusOffset - 13) + 'px';
当我减去13时,另一个问题出现了。如果将拖动器一直拖动到右侧或底部,则拖动器不会一直拖动。如果将其一直拖到左侧或顶部,它将通过画布的边框

基本上,我试图实现的是让拖动器位于光标指针的准确位置,并且拖动对象不应该经过画布的边界。我怎样才能做到这一点

var b=document.body;
var c=document.getElementsByTagName('canvas')[0];
var a=c.getContext('2d');
var wrapper=document.getElementById('wrapper');
var dragger=document.createElement('div');
dragger.id='dragger';
appendChild(dragger);
包装器。插入前(dragger,c);
document.body.clientWidth;//修复webkit中的错误:http://qfox.nl/weblog/218
(功能(){
//声明常量和变量以帮助缩小
//其中一些是内联的(在带有实际等式的一侧有注释)
var doc=单据;
doc.c=doc.createElement;
b、 a=b.1;
变量宽度=c.宽度=c.高度=400,
标签=b.a(文件c(“p”)),
输入=b.a(文件c(“输入”)),
imageData=a.createImageData(宽度,宽度),
像素=imageData.data,
一百=input.value=input.max=100,
circleOffset=0,
直径=宽度-圆偏移*2,
半径=直径/2,
radiusPlusOffset=半径+圆偏移,
半径平方=半径*半径,
two55=255,
当前Y=100,
currentX=-currentY,
wheelPixel=圆偏移*4*宽度+圆偏移*4;
//数学助手
var math=数学,
PI=math.PI,
PI2=PI*2,
sqrt=math.sqrt,
atan2=数学。atan2;
//设置DOM属性
b、 style.textAlign=“中心”;
label.style.font=“2em快递”;
input.type=“范围”;
//将色轮数据加载到内存中。
对于(y=input.min=0;yradiusSquared?0:two55;
}
}
a、 putImageData(imageData,0,0);
//绑定事件处理程序
input.onchange=重新绘制;
dragger.onmousedown=c.onmousedown=doc.onmouseup=function(e){
//如果这是mouseup事件,则取消绑定mousemove;如果这是mousedown事件,则绑定mousemove
doc.onmousemove=/p/.test(e.type)?0:(重新绘制(e),重新绘制);
}
//处理手动调用+mousemove事件处理程序+输入更改事件处理程序都在一个位置。
函数重画(e){
//仅当由mousemove或mousedown事件触发时,才处理实际更改。
//否则e.pageX将未定义,这将导致结果为NaN,因此它将返回到当前值
currentX=e.pageX-c.offsetLeft-radiusPlusOffset | | currentX;
currentY=e.pageY-c.offsetTop-radiusPlusOffset | | currentY;
//本地作用域,以便编译器缩小名称。将手动删除缩小版本中的“var”关键字。
varθ=atan2(电流y,电流x),
d=电流X*电流X+电流Y*电流Y;
//如果x/y不在圆中,请查找圆心和鼠标点之间的角度:
//从中心以半径的距离以该角度画一条线
//使用圆周上的该点作为可拖动位置
如果(d>半径平方){
currentX=半径*数学cos(θ);
电流y=半径*数学sin(θ);
θ=atan2(电流y,电流x);
d=电流X*电流X+电流Y*电流Y;
}
label.textContent=b.style.background=hsvToRgb(
(θ+π)/PI2,//当前色调(沿圆的度数)
sqrt(d)/半径,//电流饱和(离中间有多近)
input.value/one一百//当前值(input type=“range”滑块值)
)[3];
dragger.style.left=(~~currentX+radiuspluscoffset-13)+'px';
dragger.style.top=(~~currentY+radiuspluscoffset-13)+'px';
//重置为色轮并在当前位置上绘制点。
//绘制当前点。
//我试过长方形、圆形和心形。
/*
//矩形:
a、 fillStyle='#000';
a、 fillRect(currentX+radiusPlusOffset,currentY+radiusPlusOffset,6,6);
*/
//圆圈:
/*a、 beginPath();
a、 strokeStyle='白色';
a、 弧(~~currentX+radiusPlusOffset,~~currentY+radiusPlusOffset,4,0,PI2);
a、 笔划()*/
//心脏:
//a、 font=“1em arial”;
//a、 填充文本(“♥", 电流X+radiusPlusOffset-4,电流Y+radiusPlusOffset+4);
}
//在TinyColor中创建了HSV到RGB转换函数的较短版本
// https://github.com/bgrins/TinyColor/blob/master/tinycolor.js
功能hsvToRgb(h、s、v){
h*=6;
var i=~~h,
f=h-i,
p=v*(1-s),
q=v*(1-f*s),
t=v*(1-(1-f)*s),
mod=i%6,
r=[v,q,p,p,t,v][mod]*two55,
g=[t,v,v,q,p,p][mod]*two55,
b=[p,p,t,v,v,q][mod]*two55;
返回[r,g,b,“rgb(“+~~r+”,“+~~g+”,“+~~b+”);
}
//启动一切
重绘(0);
/*
//只是一个想法,我不得不用一些变化的颜色来启动一切…
//可能没有办法把它压缩到1k,但可能会有很多
dragger.style.left = (~~currentX + radiusPlusOffset - 13) + 'px';
dragger.style.top = (~~currentY + radiusPlusOffset - 13) + 'px';
currentX = e.pageX - c.offsetLeft - radiusPlusOffset -13 || currentX;
currentY = e.pageY - c.offsetTop - radiusPlusOffset -13 || currentY;