2012-05-02 71 views
1

我正在尋找一種方式在鼠標開始繪製線條結束。例如,我有DIV,我已經以循環方式移動鼠標。但是我想要在鼠標移動路徑中繪製一條線。如何根據鼠標移動繪製線條

我不想找任何HTML5解決方案。即使在所有現代瀏覽器中,我都希望它能夠工作。

請幫我解決這個問題。

+2

您需要使用''或SVG。 – SLaks

+0

@SLaks由於所有瀏覽器都不支持SVG和Canvas,我正在尋找替代品。 – Exception

+2

如果你想讓它在所有現代瀏覽器工作,然後使用HTML5 .... – Adrian

回答

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圖紙,但我認爲這是不相關的,你所以我從代碼中省略了。

3

如果你想它的工作在所有現代瀏覽器,然後使用HTML5

如果你想支持舊的瀏覽器,那麼你可以使用http://raphaeljs.com/ JS庫

拉斐爾使用SVG(如果可用),VML如果不是。基本上除了IE8及以下的瀏覽器都會使用SVG。

+0

Rapheal.js是否也支持IE6? – Exception

+0

是我給你的鏈接的首頁。 – Adrian