2014-07-14 18 views
1

캔버스 (2 차 곡선 및 베 지어 곡선으로 그린)로 그린면을 채우기 위해 노력하고 있습니다. 첫 번째 베 지어 곡선 후에 moveTo를 사용하여 다음 곡선 (2 차 곡선)을 만들기 전에 곡선의 끝점 (예 : 약간 중복 됨)으로 향하게합니다. 내가 얼굴 전체를 만든 후에, 나는 채우기를 사용했다. 얼굴은 녹색으로 얼굴을 채우지 만 중간에 흰색 삼각형을 남깁니다. 앞서 언급 한 중복 moveTo()를 제거하면 전체 모양이 의도 한대로 녹색으로 채워집니다. 누군가 이것을 설명 할 수 있습니까?HTML5 Canvas | 뉘앙스와 .moveTo() 및 .fillI()

내 생각/시도 : 삼각형의 포인트는 두 개의 교차 곡선 사이의 점과 동일하기 때문에, 내가 먼저 곡선이 접촉하지 않았기 때문에 그것이라고 생각하고, 다시 갔다

  • 그걸 고쳤다.

  • moveTo()는 베 지어 곡선의 끝점 위에 '새 점'을 작성하므로 베 지어 곡선 및 다음 곡선 대신 교차하는 새 점과 다음 곡선이됩니다.

    내가의 moveTo()의 모질라 개발자 네트워크의 캔버스 튜토리얼 설명에보고하고, '()의 moveTo' '.fill()' '인접 곡선 같은 키워드를 사용하여 여기에 검색 :

는 경우 문의 ''인접한 베 지어 곡선 '. this을 찾았지만 정확히 내가 찾던 것이 아니 었습니다.

HTML 코드 :

<!DOCTYPE html> 
<html> 
<head> 
<title>FACE</title> 
</head> 

<body> 
    <canvas id = 'canvas' height = '900' width = '900'></canvas> 
    <script src = 'face.js'></script> 
</body> 
</html> 

자바 스크립트 코드 여기

var canvas = document.getElementById('canvas'); <br> 
var context = canvas.getContext('2d');<br><br> 
function greenHeadFront() 
{ 
    var rightHeadx = 110.5; 
    var rightHeady = 80; 
    var leftHeadx = 40.5; 
    var leftHeady = 80; 

    context.moveTo(leftHeadx, leftHeady); 
    context.bezierCurveTo(leftHeadx+6, leftHeady-40, rightHeadx-6, rightHeady-40, rightHeadx, rightHeady);  //TOP OF HEAD 
    context.moveTo(rightHeadx, rightHeady); 
    context.quadraticCurveTo(115 , 100 , rightHeadx, rightHeady+30);//RIGHT CHEEK 
    context.bezierCurveTo (100 , 114, 129, 152, 75, 131); //RIGHT CHIN 
    context.moveTo(leftHeadx,leftHeady); 
    context.quadraticCurveTo(35, 100, leftHeadx, leftHeady+30);//LEFT CHEEK 
    context.bezierCurveTo(53, 120, 23, 148, 75, 131); //LEFT CHIN 
    context.fillStyle = 'rgb(0,156,0)'; 
    context.fill(); 
    context.stroke(); 
} 

greenHeadFront(); 


은 사전에 감사합니다!

답변

0

첫 번째 일 : 아니요은 하드 코딩 된 상수를 사용합니다. 문제의 원인 일 수 있습니다.
다른 점은 컨텍스트 변환을 사용하여 드로잉 코드를 단순화하는 것을 주저하지 마십시오.
마지막으로, 매개 변수를 이해하기 쉽게 사용하는 경우 코드를 훨씬 쉽게 (다시) 사용할 수 있습니다. 예를 들어 바운딩 상자의 왼쪽 위 x, y 및 너비/높이를 그릴 그림을 제공 할 수 있습니다.

그래서 아래에서는 테스트 코드를 더 명확하게 다시 작성하는 방법을 보여주기 위해 테스트되지 않은 코드를 작성했습니다.
아이디어는 그림의 왼쪽 위 모서리로 번역 한 다음 컨텍스트를 크기 조절하여 나중에 0.0에서 1.0 사이의 좌표 만 사용하여 나중에 그릴 수 있습니다.
다시 말해서 함수에서 상수 이름을 주저하지 말고 나중에 함수 매개 변수로 상수를 선택할 수 있습니다. 당신의 삼각형 문제에 대한 지금

function greenHeadFront(x, y, width, height) 
{ 
    context.save(); 
    context.translate(x,y); 
    context.scale(width, height); 
    // !! required !! 
    context.beginPath(); 
    // now all coordinates are beetween (0,0) (top-left) 
    //  and (1.0,1.0) (bottom-right) 
    var cheekHeight = 0.1 ; 
    context.moveTo(0.5, 1 - cheekHeight); // move to center middle point. 
    context.quadraticCurveTo(??);//RIGHT CHEEK 
    context.bezierCurveTo (??); //RIGHT CHIN 
    context.bezierCurveTo( ??); //TOP OF HEAD 
    context.bezierCurveTo(??); //LEFT CHIN 
    context.quadraticCurveTo(??);//LEFT CHEEK 
    context.fillStyle = 'rgb(0,156,0)'; 
    context.fill(); 
    context.strokeStyle='#000'; 
    context.lineWidth=0.01; 
    context.stroke(); 
    context.strokeRect(0,0,1,1); // for debug 
    context.restore(); 
} 

greenHeadFront(??); 

, 그것은 예상 된 동작입니다 : 당신의 moveTo를 호출 할 때마다, 당신은 새 하위 경로를 만드는, 그래서 당신의 그림은 이제 모두가 채워집니다 여러 하위 경로에서 내장되어 있습니다 fill()을 호출하면 그리고 그 하위 경로는 당신이 채우고 싶은 모든 표면을 덮지는 않습니다.

+0

감사! 나는 그리는 것을 돕기 위해 그리드를 사용하지만 간결함을 위해 여기서 생략했다. – sahaaron

0

캔버스 경로는 경로가 그려지는 방향 (시계 방향 또는 반 시계 방향)에 따라 다릅니다. 그림을 그리는 방법에 대해 little info은 채워진 영역에 영향을줍니다.

또한 조금 관련이 없지만 도형의 시작과 끝을 의미하는 context.beginPath();context.closePath(); 메서드에 대한 호출이 누락되었다고 생각합니다. 희망이 도움이!

+0

감사! 그러나 나는이 지식이이 경우에 어떻게 적용되는지에 대해 여전히 약간 혼란 스럽다 : c 녹색면의 경우, 머리의 상단 (베 지어 곡선)과 얼굴의 모든 오른쪽이 시계 방향 베 지어가 오른쪽으로 가고 얼굴의 오른쪽이 맨 아래로 간다.) 그래서 왜 그 지역 근처에 공백이 있고 왜 공백이 다른 두 점을 연결하는 흰 선이 아닌지 혼란 스럽다 (교차점 시계 방향과 시계 반대 방향의 충돌이있는 곳). – sahaaron

+0

또한 흰색 삼각형의 점 P부터 시작하여 경로의 한면 (시계 방향 또는 시계 반대 방향 경로) 만 교차하도록 직선 경로를 그려서 굴곡 규칙을 적용 해 보았습니다. 0이 아닌 와인딩 번호, 즉 _ 채워야 함을 의미하지만 잘못된 규칙을 적용하고 있으며 링크의이 부분을 명확하게 할 수 있는지 궁금해하고 있습니다. 정말 고마워! 모든 추가 누름 죄송합니다. – sahaaron