2012-05-02 2 views
1

마우스를 끝에서 끝낼 때 선을 그리는 방법을 찾고 있습니다. 예를 들어 나는 DIV가 있고 마우스를 원형으로 움직였습니다. 하지만 마우스를 움직이는 경로에 선을 그려야합니다.마우스를 기반으로 선을 그리는 방법

HTML5 솔루션을 찾고 있지 않습니다. 나는 모든 현대의 브라우저에서도 작동되도록하고 싶다.

도와주세요. 당신은 당신이 당신이 가능한 경우 라파엘은 SVG를 사용하는 http://raphaeljs.com/ JS 라이브러리

, VML을하지 않을 경우 사용할 수 오래된 브라우저를 지원하려면 다음 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

. 기본적으로 IE8 이하를 제외한 모든 브라우저는 SVG를 사용합니다.

+0

Rapheal.js도 IE6를 지원합니까? – Exception

+0

내가 준 링크의 예 페이지입니다. – Adrian

관련 문제