我正在寻找一种在鼠标开始结束时划一条线的方法。例如,我有DIV,我已经以圆形方式移动鼠标。但我希望在鼠标移动的路径中绘制一条线。
我不是在寻找任何HTML5解决方案。我希望它甚至可以在所有现代浏览器中使用。
请帮我解决这个问题。
答案 0 :(得分:3)
如果您希望它适用于所有现代浏览器,请使用HTML5
如果您想支持旧浏览器,那么您可以使用http://raphaeljs.com/ JS库
Raphael使用SVG(如果可用),否则使用VML。基本上除IE8及以下版本的每个浏览器都将使用SVG。
答案 1 :(得分:1)
我在8年前写过一些东西,6年前修改过它并现在检查它 - 仍在工作。它是通过点击屏幕上的两个点绘制线条,但可以改为鼠标移动而不需要调整。
它采用纯JavaScript,实质上是将像素大小的图像附加到文档中。
我会在这里写下代码。请注意它很老,在工作时,可能不是最好的做法。
var PIXEL_PATH="http://i.stack.imgur.com/QXTrN.gif";
var ST_LINE=1;
var ST_CIRCLE=2;
var strImageData="";
var strUserInput="";
var strImageName="";
var iPointsCount=0;
var iNumCalls=0;
var loadComplete=false;
var arrLines=new Array();
var arrRedo=new Array();
var strPoints="";
var arrImages;
var objWin;
var INFINITY=-999999;
var iLastX=INFINITY, iLastY=INFINITY;
var drawStyle=ST_LINE;
var arrPoints=new Array();
var iCurrentImage=0;
var blnLineFinished=true;
var blnLoading=true;
var strCurrentPoints="";
document.onclick = DocumentClick;
document.onkeyup = DocumentKeyup;
self.onload=Init;
function Init()
{
DrawPoint(0, 0);
CommitDraw();
}
function DrawImage()
{
var x1, x2, y1, y2;
var iStep=12;
blnLoading = true;
for (j=0; j<document.images.length; j++)
document.images[j].style.visibility = "hidden";
if (objWin)
objWin.close();
arrLines = new Array();
arrRedo = new Array();
document.forms[0].redo.disabled = true;
iLastX=INFINITY;
iLastY=INFINITY;
DrawPoint(0, 0);
CommitDraw();
if ((strImageData.length % 12) != 0)
iStep = 13;
for (i=0; i<strImageData.length; i+=iStep)
{
drawStyle = (iStep == 12)?ST_LINE:ToNumber(strImageData.substr(i, 1));
x1 = ToNumber(strImageData.substr(i+iStep-12, 3));
y1 = ToNumber(strImageData.substr(i+iStep-12+3, 3));
x2 = ToNumber(strImageData.substr(i+iStep-12+6, 3));
y2 = ToNumber(strImageData.substr(i+iStep-12+9, 3));
Line(x1, y1, x2, y2);
}
return true;
}
function Random()
{
event.cancelBubble = true;
var x1, x2, x1_old;
var y1, y2, y1_old;
var z=0;
if (drawStyle == ST_CIRCLE)
{
x1=Rnd(document.body.clientWidth-100)+100;
y1=Rnd(document.body.clientHeight-100)+100;
x2 = x1+MIN(ABS(x1-100), ABS(document.body.clientWidth-100-x1));
y2 = y1+MIN(ABS(y1-100), ABS(document.body.clientHeight-100-y1));
x1_old = x1;
y1_old = y1;
while ((R(x1, y1, x2, y2) >= ABS(x2-x1_old)) || (R(x1, y1, x2, y2) >= ABS(y2-y1_old)))
{
x1 += (ABS(x1-100) > ABS(document.body.clientWidth-100-x1))?-1:1;
y1 += (ABS(y1-100) > ABS(document.body.clientHeight-100-y1))?-1:1;
z++;
if (z >= 100)
break;
}
}
else
{
x1=Rnd(document.body.clientWidth-30)+30;
y1=Rnd(document.body.clientHeight-30)+30;
x2=Rnd(document.body.clientWidth-30)+30;
y2=Rnd(document.body.clientHeight-30)+30;
}
ClearLastPoint();
Line(x1, y1, x2, y2);
arrRedo = new Array();
document.forms[0].redo.disabled = true;
return true;
}
function ToNumber(str) {return (str*(-1)*(-1));}
function Rnd(num) {return parseInt(Math.random()*num);}
function DocumentClick()
{
var iCurX=window.event.x, iCurY=window.event.y;
// blnLoading=false;
if ((iLastX != INFINITY )&&(iLastY != INFINITY))
{
Line(iLastX, iLastY, iCurX, iCurY);
if (drawStyle != ST_CIRCLE)
{iLastX = iCurX; iLastY = iCurY;}
}
else
{
iLastX = iCurX;
iLastY = iCurY;
}
arrRedo = new Array();
document.forms[0].redo.disabled = true;
return true;
}
function DocumentKeyup()
{
if (document.forms[0].all("load"))
return false;
strUserInput += String.fromCharCode(self.event.keyCode);
if (strUserInput.toLowerCase().indexOf("shadow")>=0)
{
var objInput=document.createElement("INPUT");
objInput.name = objInput.id = "load";
objInput.type = "button";
objInput.value = "Load";
objInput.onclick = Load;
document.forms[0].appendChild(objInput);
return true;
}
if (strUserInput.length > 999)
strUserInput.length = "";
return false
}
function Line(x1, y1, x2, y2)
{
arrLines[arrLines.length] = drawStyle+AddZeros(x1, 3)+AddZeros(y1, 3)+
AddZeros(x2, 3)+AddZeros(y2, 3);
blnLineFinished = false;
strCurrentPoints = "";
document.forms[0].undo.disabled = false;
arrPoints = new Array();
iCurrentImage = 0;
if (!blnLoading)
{
divMsg.style.visibility = "visible";
divMsg.style.left = x1+"px";
divMsg.style.top = y1+"px";
}
arrImages=new Array();
if (drawStyle == ST_CIRCLE)
return Circle(x1, y1, x2, y2);
if (x1 == x2)
{
for (y=MIN(y1, y2); y<=MAX(y1, y2); y++)
DrawPoint(x1, y);
return EndLine();
}
if (ABS((x2-x1))>=ABS((y2-y1)))
{
for (x=MIN(x1, x2); x<=MAX(x1, x2); x++)
DrawPoint(x, Y(x, x1, y1, x2, y2));
return EndLine();
}
else
{
for (y=MIN(y1, y2); y<=MAX(y1, y2); y++)
DrawPoint(X(y, x1, y1, x2, y2), y);
return EndLine();
}
}
function Circle(x1, y1, x2, y2)
{
var y, x, r=R(x1, y1, x2, y2);
var iFirst=(x1-r);
var iLast=(x1+r);
var iFirst2=(y1-r);
var iLast2=(y1+r);
for (x=iFirst; x<=iLast; x++)
{
y = Y2(r, x, x1, y1);
DrawPoint(X2(r, y, x1, y1), y);
DrawPoint(X3(r, y, x1, y1), y);
y = Y3(r, x, x1, y1);
DrawPoint(X2(r, y, x1, y1), y);
DrawPoint(X3(r, y, x1, y1), y);
}
for (y=iFirst2; y<=iLast2; y++)
{
x = X2(r, y, x1, y1);
DrawPoint(x, Y2(r, x, x1, y1));
DrawPoint(x, Y3(r, x, x1, y1));
x = X3(r, y, x1, y1);
DrawPoint(x, Y2(r, x, x1, y1));
DrawPoint(x, Y3(r, x, x1, y1));
}
iLastX=INFINITY;
iLastY=INFINITY;
return EndLine();
}
function R(x1, y1, x2, y2)
{
return Math.sqrt(((x2-x1)*(x2-x1))+((y2-y1)*(y2-y1)));
}
function EndLine()
{
CommitDraw();
strPoints = strPoints.substr(0, strPoints.length-1)+"|";
HideMessage();
if (!blnLoading)
divPointsCount.innerHTML = "0";
}
function HideMessage()
{
if (blnLineFinished)
{
divMsg.style.visibility = "hidden"; return true;
}
setTimeout("HideMessage();", 100);
}
function Y(x, x1, y1, x2, y2)
{
return (((y2-y1)/(x2-x1))*(x-x1))+y1;
}
function X(y, x1, y1, x2, y2)
{
return (((x2-x1)/(y2-y1))*(y-y1))+x1;
}
function Y2(r, x, x0, y0)
{
return (y0+Math.sqrt(ABS((r*r)-((x-x0)*(x-x0)))));
}
function X2(r, y, x0, y0)
{
return (x0+Math.sqrt(ABS((r*r)-((y-y0)*(y-y0)))));
}
function Y3(r, x, x0, y0)
{
return (y0-Math.sqrt(ABS((r*r)-((x-x0)*(x-x0)))));
}
function X3(r, y, x0, y0)
{
return (x0-Math.sqrt(ABS((r*r)-((y-y0)*(y-y0)))));
}
function ABS(n) {return (n>=0)?n:(n*-1);}
function MAX(a1, a2) {return (a1>=a2)?a1:a2;}
function MIN(a1, a2) {return (a1<=a2)?a1:a2;}
function AddZeros(iNumber, iZeros)
{
var strZeros="";
for (j=0; j<iZeros; j++)
strZeros += "0";
return (strZeros.substr(0, iZeros-(iNumber+"").length)+iNumber+"");
}
function DrawPoint(x, y)
{
if (PointExists(parseInt(x), parseInt(y)))
return false;
iPointsCount++;
var objImage=document.createElement("IMG");
objImage.id = "i"+iPointsCount;
objImage.name = "i"+iPointsCount;
objImage.src = PIXEL_PATH;
objImage.width = objImage.height = 1;
objImage.border = 0;
objImage.style.position = "absolute";
objImage.style.top = parseInt(y)+"px";
objImage.style.left = parseInt(x)+"px";
strCurrentPoints += parseInt(x)+","+parseInt(y)+"|";
arrPoints[arrPoints.length] = objImage;
// document.body.appendChild(objImage);
strPoints += "i"+iPointsCount+",";
return true;
}
function CommitDraw()
{
if (iCurrentImage >= arrPoints.length)
{
blnLineFinished = true; return true;
}
if (blnLoading)
{
for (iCurrentImage=0; iCurrentImage<arrPoints.length; iCurrentImage++)
document.body.appendChild(arrPoints[iCurrentImage]);
blnLineFinished = true;
}
else
{
document.body.appendChild(arrPoints[iCurrentImage]);
iCurrentImage++;
divPointsCount.innerHTML = (parseInt(divPointsCount.innerHTML)+1)+"";
setTimeout("CommitDraw();", 1);
}
}
function PointExists(x, y)
{
return (strCurrentPoints.indexOf(parseInt(x)+","+parseInt(y)+"|")>=0);
}
function GetImageData()
{
var strAns="";
for (k=0; k<arrLines.length; k++)
strAns += arrLines[k];
return strAns;
}
function Undo()
{
event.cancelBubble=true;
if (arrLines.length>0)
ClearLastLine();
arrRedo[arrRedo.length] = arrLines[arrLines.length-1];
document.forms[0].redo.disabled = false;
var arrTemp=new Array();
for (i=0; i<arrLines.length-1; i++)
arrTemp[i] = arrLines[i];
arrLines = arrTemp;
document.forms[0].undo.disabled = (arrLines.length == 0);
if ((drawStyle == ST_CIRCLE)||(arrLines.length == 0))
{
iLastX=INFINITY;
iLastY=INFINITY;
}
else
{
iLastX=parseInt(document.getElementById("i"+iPointsCount).style.left);
iLastY=parseInt(document.getElementById("i"+iPointsCount).style.top);
}
}
function Redo()
{
event.cancelBubble=true;
if (arrRedo.length == 0)
return false;
var strLine=arrRedo[arrRedo.length-1];
drawStyle = ToNumber(strLine.substr(0, 1));
var x1=ToNumber(strLine.substr(1, 3));
var y1=ToNumber(strLine.substr(4, 3));
var x2=ToNumber(strLine.substr(7, 3));
var y2=ToNumber(strLine.substr(10, 3));
Line(x1, y1, x2, y2);
var arrTemp=new Array();
for (i=0; i<arrRedo.length-1; i++)
arrTemp[i] = arrRedo[i];
arrRedo = arrTemp;
document.forms[0].redo.disabled = (arrRedo.length == 0);
if (drawStyle == ST_CIRCLE)
{
iLastX=INFINITY;
iLastY=INFINITY;
}
else
{
iLastX = x2;
iLastY = y2;
}
}
function ClearLastLine()
{
var strToClear="";
//alert("points: "+strPoints);
for (j=strPoints.length-2; (j>=0)&&(strPoints.charAt(j) != "|"); j--)
strToClear += strPoints.charAt(j);
strPoints = strPoints.substr(0, strPoints.length-strToClear.length-1);
var strTmp="";
for (k=strToClear.length-1; k>=0; k--)
strTmp += strToClear.charAt(k);
strToClear = strTmp;
var arrTmp=strToClear.split(",");
iPointsCount -= arrTmp.length;
for (i=0; i<arrTmp.length; i++)
document.body.removeChild(document.getElementById(arrTmp[i]));
}
function ClearLastPoint()
{
iLastX=INFINITY;
iLastY=INFINITY;
event.cancelBubble=true;
}
function ToggleShape(a)
{
event.cancelBubble=true;
if (drawStyle == ST_CIRCLE)
{
a.value = "Circle";
drawStyle = ST_LINE;
return ClearLastPoint();
}
if (drawStyle == ST_LINE)
{
a.value = "Line";
drawStyle = ST_CIRCLE;
return ClearLastPoint();
}
return false;
}
它伴随着这样的HTML:
<form>
<input name="clear" id="clear" type=button value="*" onclick="ClearLastPoint();" />
<input name="undo" id="undo" type=button value="Undo" onclick="Undo();" DISABLED />
<input name="redo" id="redo" type=button value="Redo" onclick="Redo();" DISABLED />
<input name="random" id="random" type=button value="Random" onclick="Random();" />
<input name="circle" id="circle" type=button value="Circle" onclick="ToggleShape(this);" />
</form>
您可以在this fiddle在线查看。 它使用单个像素图像,您可以下载它here。 (右键单击并选择另存为)
最初它还支持将绘图保存到服务器并使用经典ASP加载已保存的图形,但我认为它与您无关,所以我在代码中省略了它。