2016-07-21 3 views
0

나는 큰 원의 바깥 둘레 주위에 점을 마우스로 드래그하려고 시도하고 그 점을 그 바깥 쪽 둘레의 둘레 주위에 두꺼운 선을 표시하는 것처럼 보입니다. 나는 점 뒤에있는 바깥 쪽 선을 긋는 것 외에는 모든 것을 얻을 수 있습니다. 나는 많은 아이디어를 연구하고 내 자신의 많은 시도했지만 라인은 여전히 ​​"발견"결과를 생성합니다. 여기 내가 시도하고있는 것을 보여주는 이미지가 있습니다. MounseDrag Scribed Line 제 질문을 읽어 주셔서 감사합니다. :-)캔버스에서 원형 선을 그을음

<script type="text/javascript"> 
    var canvas1 = document.getElementById("canvas1"), 
     canvas2 = document.getElementById("canvas2"), 
     c1 = canvas1.getContext("2d"), 
     c2 = canvas2.getContext("2d"), 
     dot = 7, 
     started = false, 
     width = 350, 
     height = 350, 
     radians = 0, 
     cRad = 165, // Circle Radius 
     cord = {mX:0, mY:0, csX:0, snY:0, x:0, y:0}, 
     init = function(){ 
     cord.mX = 0; 
     cord.mY = 0; 
     cord.csX = width /2 + cRad; 
     cord.snY = height /2; 
     cord.x = width /2; 
     cord.y = height /2; 
     }; 

    init(); 
    canvas1.width = width; 
    canvas1.height = height; 
    canvas2.width = width; 
    canvas2.height = height; 
    canvas1.addEventListener("mousemove", function(event) { 
    cord.mX = event.clientX - canvas1.offsetLeft; 
    cord.mY = event.clientY - canvas1.offsetTop; 
    }); 

    canvas1.addEventListener("mousedown", function(event) { 
    if (started) { 
     started = false; 
    } else { 
     started = true; 
     render(); 
    }; 
    }); 

    function update() { 
    radians = Math.atan2(cord.mY - width/2, cord.mX - height/2); 
    cord.csX = width/2 - Math.cos(radians) * cRad * -1; 
    cord.snY = height/2 - Math.sin(radians) * cRad * -1; 
    }; 

    function outerTheta() { 
    c2.beginPath(); 
    c2.arc(cord.csX, cord.snY, 3, 0, Math.PI * 2); 
    c2.closePath(); 
    c2.fillStyle = "#000"; 
    c2.fill(); 
    }; 

    function render() { 
    c1.clearRect(0, 0, width, height); 
    c1.beginPath(); 
    c1.moveTo(cord.x, cord.y); 
    c1.lineTo(cord.csX, cord.snY); 
    c1.lineWidth = 3; 
    c1.strokeStyle = "#000"; 
    c1.stroke(); 

    c1.beginPath(); //<---------------------------------- Drag-Dot 
    c1.arc(cord.csX, cord.snY, dot, 0, Math.PI * 2); 
    c1.closePath(); 
    c1.fillStyle = "#000"; 
    c1.fill(); 

    if(started){ 
     update(); 
     outerTheta(); 
     requestAnimationFrame(render); 
    }; 
    }; 
    render(); 
</script> 

답변

2

브라우저는 마우스가 움직이는 것처럼 빠르게 애니메이션을 순환시킬 수 없습니다. 마우스를 천천히 움직이면 각 애니메이션 사이클에서 그려지는 점들이 겹치고 원은 실선을가집니다. 마우스를 빨리 움직이면 점들이 겹치지 않아서 "점 찍기"가됩니다.

그리기 프로그램의 작동 방식에주의를 기울이면 "펜"도구가 연속 선을 그어주는 것을 볼 수 있습니다. 도구를 사용하는 동안 마우스를 빠르게 움직이면 연속 선은 마우스가 빠르게 움직이는 동안 컴퓨터가 포착 할 수 있었던 각 지점에서 늘어나는 선 세그먼트로 구성됩니다. 선분 애니메이션주기 동안 각 촬영 지점 사이에 뻗어 있도록

내가 프로그램을 수정 : https://jsfiddle.net/17hvw5pp

var canvas1 = document.getElementById("canvas1"), 
     canvas2 = document.getElementById("canvas2"),    
     c1 = canvas1.getContext("2d"), 
     c2 = canvas2.getContext("2d"), 
     dot = 7, 
     started = false, 
     width = 350, 
     height = 350, 
     radians = 0, 
     cRad = 165, // Circle Radius 
     cord = {mX:0, mY:0, csX:0, snY:0, x:0, y:0}, 
     init = function(){ 
     cord.mX = 0; 
     cord.mY = 0; 
     cord.csX = width /2 + cRad; 
     cord.snY = height /2; 
     cord.lastCSX = cord.csX; 
     cord.lastSNY = cord.snY; 
     cord.x = width /2; 
     cord.y = height /2;   
     }; 

    canvas1.style.position="absolute"; 
    canvas2.style.position="absolute"; 

    init(); 
    canvas1.width = width; 
    canvas1.height = height; 
    canvas2.width = width; 
    canvas2.height = height; 
    canvas1.addEventListener("mousemove", function(event) { 
    cord.mX = event.clientX - canvas1.offsetLeft; 
    cord.mY = event.clientY - canvas1.offsetTop; 
    }); 

    canvas1.addEventListener("mousedown", function(event) { 
    if (started) { 
     started = false; 
    } else { 
     started = true; 
     render(); 
    }; 
    }); 

    function update() { 
    radians = Math.atan2(cord.mY - width/2, cord.mX - height/2);  
    cord.csX = width/2 - Math.cos(radians) * cRad * -1; 
    cord.snY = height/2 - Math.sin(radians) * cRad * -1; 
    }; 

    function outerTheta() { 
    //draw a line from the last known coordinate to the new known coordinate 
    c2.beginPath(); 
    c2.moveTo(cord.lastCSX, cord.lastSNY); 
    c2.lineTo(cord.csX, cord.snY); 
    c2.lineWidth=5; 
    c2.strokeStyle="#000"; 
    c2.stroke(); 
    cord.lastCSX = cord.csX; 
    cord.lastSNY = cord.snY; 

    c2.beginPath(); 
    c2.arc(cord.csX, cord.snY, 3, 0, Math.PI * 2); 
    c2.closePath(); 
    c2.fillStyle = "#000"; 
    c2.fill(); 
    }; 

    function render() { 
    c1.clearRect(0, 0, width, height); 
    c1.beginPath(); 
    c1.moveTo(cord.x, cord.y); 
    c1.lineTo(cord.csX, cord.snY); 
    c1.lineWidth = 3; 
    c1.strokeStyle = "#000"; 
    c1.stroke(); 

    c1.beginPath(); //<---------------------------------- Drag-Dot 
    c1.arc(cord.csX, cord.snY, dot, 0, Math.PI * 2); 
    c1.closePath(); 
    c1.fillStyle = "#000"; 
    c1.fill(); 

    if(started){ 
     update(); 
     outerTheta(); 
     requestAnimationFrame(render); 
    }; 
    }; 
    render(); 

이 잘 작동,하지만 완벽하게

: 마우스를 이동하면 신속하게, 선분이 원을 가로 지르는 코드가되어이 효과가 사라집니다.

나는 두 알려진 점 사이의 호를 그리는 프로그램을 수정하려고 시도 :

https://jsfiddle.net/17hvw5pp/1/

어느 방향에 대해 그려 아크 기능이 혼동되기 때문에이 구현도 좋지 않은 것을 알 수 있습니다 부분 원은 단지 두 개의 라디안 좌표를 기반으로합니다. 쿼터니온 수학을 사용하면이 문제가 해결됩니다.

https://en.wikipedia.org/wiki/Quaternion

그러나이 프로젝트에 도입하고자하는 많은 합병증을 할 수있다.

+0

데모의 경우 외부 Fiddles가 아닌 Stackoverflow의 내부 [Snippets] (https://blog.stackoverflow.com/2014/09/introducing-runnable-javascript-css-and-html-code-snippets/)를 사용하십시오. :-) – markE

+0

시간을 내서 도와 주셔서 감사합니다. 정보. 당신이 제공 한 것은 나를 위해 매우 눈을 뜨고 있습니다. 나는 명백한 무엇인가 놓치고 있었지만. 나는 문제가 실제로 해결하기가 어렵다는 것을 알 수 있으며 이것은 매우 도움이 될 것입니다. 나는 그걸 좀 더 연구하고 내가 그걸로 할 수있는 것을 보게 될 것이다. 다시 한 번 고마워! –

관련 문제