2014-05-22 4 views
0

HTML5 캔버스가 중심이 아닌 호의 왼쪽 상단에서 그려지도록하려면 다음 코드를 어떻게 변경합니까?HTML5 Canvas - 왼쪽 상단에서 원을 그립니다.

내가 현재 가지고 :

function drawCircle(e) { 
    var oe = e.originalEvent || e; 

    ctx.beginPath(); 
    ctx.arc(start.x, start.y + 10, oe.pageX - start.x - offset.left, 0, 2 * Math.PI, false); 
    ctx.stroke(); 
    ctx.closePath(); 
} 

나는 다음과 바이올린 (편의를 위해 아래 코드)를이 - 당신이에 그리기 시작하면, 원형이 잘 그려 그러나 당신이 두는 곳의 중심에서 그립니다 당신의 마우스, 바깥 쪽 : http://jsfiddle.net/g4zxp/

왼쪽 위부터 아래로 원을 드래그하고 싶습니다만, 수학을 이해할 수 없습니다! 나는 중심점을 계산하고 계속 변경해야한다는 것을 알고있다.

아이디어가 있으십니까?

감사

코드를 다음과 같이

HTML :

<canvas width="200" height="200"></canvas> 

자바 스크립트/jQuery를 :

$(function() { 
    var $canvas = $('canvas'), 
     canvas = $canvas.get(0), 
     offset = $canvas.offset(), 
     ctx, 
     drawing = false, 
     start = { 
      x: null, 
      y: null 
     }; 

    function init() { 
     if (canvas.getContext) { 
      ctx = canvas.getContext('2d'); 

      ctx.lineJoin = 'round'; 
      ctx.lineCap = 'round'; 
      ctx.strokeStyle = '#000000'; 
      ctx.lineWidth = 5; 
     } 
    } 

    function startDrawing(e) { 
     var oe = e.originalEvent || e; 

     e.preventDefault(); 

     drawing = true; 

     start.x = Math.floor(oe.pageX - offset.left); 
     start.y = Math.floor(oe.pageX - offset.left); 
    } 

    function continueDrawing(e) { 
     e.preventDefault(); 

     if (!drawing) { 
      return; 
     } 

     clearCanvas(); 
     drawCircle(e); 
    } 

    function endDrawing(e) { 
     e.preventDefault(); 
     drawing = false; 
    } 

    function clearCanvas() { 
     ctx.clearRect(0, 0, canvas.width, canvas.height); 
    } 

    function drawCircle(e) { 
     var oe = e.originalEvent || e; 

     ctx.beginPath(); 
     ctx.arc(start.x, start.y + 10, oe.pageX - start.x - offset.left, 0, 2 * Math.PI, false); 
     ctx.stroke(); 
     ctx.closePath(); 
    } 

    $canvas.on('touchstart mousedown', function (e) { 
     startDrawing(e); 
    }); 

    $canvas.on('touchmove mousemove', function (e) { 
     continueDrawing(e); 
    }); 

    $canvas.on('touchend mouseup', function (e) { 
     endDrawing(e); 
    }); 

    init(); 
}); 

답변

2

내가의 "왼쪽 상단을 가정하고 아크 "는 내가 될 아래 다이어그램의 선의 교차점. 이 경우 원의 중심으로부터의 거리는 "상단 왼쪽"에서 sqrt(2 * r^2)의 거리입니다.

하지만 캔버스의 원은 x와 y를 사용하여 배치되므로 어쨌든 대신 사용할 수 있습니다. 수평 라인에 가장 가까운 점의 중심으로부터의 거리와 같이 수직 라인에 가장 가까운 점의 중심으로부터의 거리가이 그 (사람 (0,0) 수단

, R이고) 왼쪽 상단에있는 "왼쪽 상단의"x 위치는 center's x position - r하고 "왼쪽 상단의"y 위치는 수동과 같은 코드를 사용하여 캔버스에서 이것을 계산할 수 있습니다 (oe.pageX - start.x - offset.left = r부터) 너무 짧은

에 대한 center's y position - r 또는 (cX - r, cY - r)입니다 :

var r = oe.pageX - start.x - offset.left; 
ctx.arc(start.x + r, start.y + 10 + r, r, 0, 2 * Math.PI, false); 

Demo. 이것은 잘 작동합니다.

프런트 엔드에서 동일한 형식을 사용하려는 경우 기능을 만들 수 있습니다. 이렇게 보일 겁니다.

function arcTopLeft(x, y, r, a1, a2) { 
    ctx.arc(x + r, y + r, r, a1, a2, false); 
} 
// Called using the same inputs as your original call 
arcTopLeft(start.x, start.y + 10, oe.pageX - start.x - offset.left, 0, 2 * Math.PI, false); 

희망이있었습니다.

+1

그런데 실제로 프로젝트에서 jQuery가 필요하지 않습니다. 당신은 단지 두어 번만 사용하고 바닐라 js로 작성하면 쉽게 쓸 수 있습니다 –

+0

이것은 완벽합니다 - 고마워요! 동의했다. 나는 게으르다. (내 플러그인에 조금 더있어, jQuery를 좀 더 공정하게 사용한다.) 그러나 동의했다. 내가 한 모든 것은 바닐라 JS로 훨씬 더 가볍다. – keldar

+0

와우, 너 너무 멀었다! 훨씬 간단한 대답 버디! 내 대답을 확인하십시오. – WebWanderer

0

좋아, 그래서 거기에이 작업을 수행하기 위해 미친 듯이 간단한 방법은, 당신은 당신의 ctx.arc() 호출에서 오류가 발생한 모든 이잖아 :

ctx.arc(oe.layerX, oe.layerY, Math.abs(oe.pageX - start.x - offset.left), 0, 2 * Math.PI, false); 

또한 절대 값으로 반경을 설정 있도록 앱을 손상시키지 않고 음의 방향으로 원을 그릴 수 있습니다. 내가 당신에게 더 빨리 간다면 좋겠다. 나는이 간단한 대답을 원했을 것이라고 생각했다.

덧붙여서 here is your fiddle은 모두 수정하여 원하는대로 정확하게 수행합니다. 미안 나는 너에게 빨리 가지 않았다!