HTML5의 캔버스는 타원을 그릴 수있는 방법을 직접 제공하지 않습니다. 다음은 몇 가지 드로잉 방법을 요약 한 것입니다. 다양한 방법에는 고유 한 장점과 단점이 있으며 상황에 따라 선택됩니다. 각 방법의 매개 변수는 동일합니다.
컨텍스트는 Canvas의 2D 드로잉 환경 객체입니다.
X는 타원 중심의 수평 좌표입니다.
Y는 타원 중심의 수직 좌표입니다.
A는 타원의 수평 반 축의 길이입니다.
B는 타원의 수직 반 축의 길이입니다.
매개 변수 방정식 방법이 방법은 타원의 파라 메트릭 방정식을 사용하여 타원을 그립니다.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// 함수의 매개 변수 x와 y는 타원의 중심입니다. A와 B는 각각 타원의 수평 반 축입니다.
// 수직 반 축의 길이는 동시에 0이 될 수 없습니다.
//이 방법의 단점은 Linwidth가 더 넓고 타원이 아첨하는 경우입니다.
// 내부 타원의 주요 축 끝은 날카 롭고 매끄럽지 않으며 효율이 낮습니다.
기능 paramellipse (컨텍스트, X, Y, A, B)
{
// MAX는 주요 축 값 A와 B 중 더 큰 것입니다.
// 각주기마다 1/max를 증가시켜 학위 증가를 나타냅니다.
// 이것은 각 루프에 1 픽셀에 가까운 경로 (아크)를 만듭니다.
var step = (a> b)? 1 / A : 1 / B;
context.beginpath ();
context.moveto (x + a, y); // 타원의 왼쪽 끝점에서 그려집니다
for (var i = 0; i <2 * math.pi; i += step)
{
// 매개 변수 방정식은 x = a * cos (i), y = b * sin (i)입니다.
// 매개 변수는 I이며, 정도 (Radian)를 나타냅니다.
context.lineto (x + a * math.cos (i), y + b * math.sin (i));
}
context.closepath ();
Context.Stroke ();
};
균일 압축 방법이 방법은 수학에서 균일 압축 원리를 사용하여 원을 타원으로 균일하게 압축하여 이론적으로 표준 타원을 얻을 수 있습니다. 다음 코드는 일관되지 않은 선 너비에 문제가 있습니다. 해결책은 5 층에서 Simonleung의 의견을 보는 것입니다.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// 메소드는 ARC 메소드를 사용하여 원을 그리며 Scale을 결합하는 것입니다.
// 수평 또는 세로 축 방향으로의 스케일링 (압축조차도)
//이 방법에서 그려진 타원의 가장자리는 메이저가 주요 축의 끝에 가까워지고 주요 축 끝의 선 너비가 정상입니다.
// 가장자리는 마이너 축에 가까워지고, 타원의 평평하고 얇고, 심지어 중단도 발생합니다. 이것은 규모의 결과입니다.
//이 단점은 때때로 링의 3 차원 효과를 표현할 때와 같은 이점입니다 (Planetary Halo)
// 매개 변수 a 또는 b가 0 인 경우이 방법은 적용되지 않습니다.
함수 evencompellipse (컨텍스트, x, y, a, b)
{
context.save ();
// 아크 메소드의 반경 매개 변수로 A와 B의 더 큰 하나를 선택하십시오.
var r = (a> b)? A : B;
var ratiox = a / r; // 수평 축 스케일링 비율
var ratioy = b / r; // 치수 축 스케일링 비율
Context.Scale (ratiox, ratioy); // 스케일링 (심지어 압축)
context.beginpath ();
// 타원의 왼쪽 끝에서 시계 반대 방향을 그립니다
context.moveto ((x + a) / ratiox, y / ratioy);
context.arc (x / ratiox, y / ratioy, r, 0, 2 * math.pi);
context.closepath ();
Context.Stroke ();
Context.Restore ();
};
입방 베 지어 곡선 방법 1타원의 입방 베 지어 곡선 도면은 실제로 그리기에 근사치이며 이론적으로는 근사입니다. 그러나 높은 효율로 인해 컴퓨터 벡터 그래픽에 타원을 그리는 데 종종 사용되지만 특정 이론에 대해서는 명확하지 않습니다. 근사치는 두 제어점의 위치를 선택하는 데 있습니다. 이 방법의 제어점 위치는 혼자서 얻어졌으며 정확도는 정상입니다.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//이 방법은 Linewidth가 더 넓고 타원이 더 평평 할 때도 생성됩니다.
// 장축 끝은 날카 롭고 매끄럽지 않습니다
함수 Bezierellipse1 (Context, X, Y, A, B)
{
// 키는 Beziercurveto에서 두 가지 제어 지점 설정입니다.
//0.5와 0.6은 두 가지 주요 계수입니다 (이 기능의 실험을 위해 얻은)
var ox = 0.5 * a,
OY = 0.6 * b;
context.save ();
Context.Translate (x, y);
context.beginpath ();
// 타원 종단 축의 하단에서 시계 반대 방향으로 그려
context.moveto (0, b);
context.beziercurveto (ox, b, a, oy, a, 0);
context.beziercurveto (a, -oy, ox, -b, 0, -b);
context.beziercurveto (-ox, -b, -a, -oy, -a, 0);
context.beziercurveto (-a, oy, -ox, b, 0, b);
context.closepath ();
Context.Stroke ();
Context.Restore ();
};
입방 베 지어 곡선 방법 2이 방법은 정확도가 높은 Stackoverflow의 게시물로 답장에서 게시물로 변경되며 타원을 그리는 데 일반적으로 사용되는 방법입니다.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//이 방법은 Linewidth가 더 넓고 타원이 아첨 할 때도 생성됩니다.
//, 장축 끝은 날카 롭고 매끄럽지 않습니다.
//이 메소드는 이전 Bessel 메소드보다 정확하지만 효율적인 방법이 약간 덜 정확합니다.
함수 Bezierellipse2 (CTX, X, Y, A, B)
{
var k = .5522848,
ox = a * k, // 수평 제어점 오프셋
oy = b * k; // 수직 제어점 오프셋
ctx.beginpath ();
// 타원의 왼쪽 끝에서 시계 방향으로 4 입방 베 지어 곡선을 그리십시오.
ctx.moveto (x -a, y);
ctx.beziercurveto (x -a, y -oy, x -ox, y -b, x, y -b);
ctx.beziercurveto (x + ox, y -b, x + a, y -oy, x + a, y);
ctx.beziercurveto (x + a, y + oy, x + ox, y + b, x, y + b);
ctx.beziercurveto (x -ox, y + b, x -a, y + oy, x -a, y);
ctx.closepath ();
ctx.stroke ();
};
격자 방법이 방법은 픽셀을 작동하고 그래픽에서 기본 알고리즘을 사용할 수있는 캔버스의 특성에 따라 타원을 그릴 수 있습니다. 예를 들어, 중간 점을 도면 타원 알고리즘 등.
한 가지 예는 정원 친구 인 Doudou의 블로그 게시물, HTML5 Canvas 개선 클래스 (I) -Raster Graphics (1) Midpoint 및 Circle 알고리즘입니다. 이 방법은 비교적 원시적이고 유연하며 효율적이며 정확하지만 타원을 그리는 데 유용한 기능을 실현하는 것이 더 복잡합니다. 예를 들어, 선 너비가 변경되면 알고리즘이 더욱 복잡해집니다. 원을 그리기위한 알고리즘이지만 타원을 그리기위한 알고리즘은 그것과 유사하므로 아래를 참조하십시오.
데모
다음은 래스터 방법 외에 타원 함수를 그리는 몇 가지 데모입니다. 데모 코드는 다음과 같습니다.
<div id = "canvaswrap"style = "배경 : #ffff; 너비 : 600px; 높이 : 600px; 테두리 : 1px solid black;"> </div>
<script type = "text/javaScript"> // <! [cdata [cdata [
var 캔버스,
문맥;
var div = document.getElementById ( "canvaswrap");
div.innerhtml = "";
canvas = document.createElement ( "캔버스");
canvas.style.width = "600px"
canvas.style.height = "600px"
Canvas.width = 600;
Canvas.height = 600;
Context = canvas.getContext ( "2d");
Div.AppendChild (캔버스);
함수 execdraw ()
{
// 크롬에서 라인 너비 문제를 1보다 작거나 같은 경우
context.linewidth = 1.1;
context.strokestyle = "black"
Paramellipse (컨텍스트, 130, 80, 50, 50); //원
paramellipse (컨텍스트, 130, 80, 100, 20); // 타원
Evencompellipse (컨텍스트, 130, 200, 50, 50); //원
Evencompellipse (Context, 130, 200, 100, 20); // Ellipe
Bezierellipse1 (컨텍스트, 470, 80, 50, 50); //원
Bezierellipse1 (컨텍스트, 470, 80, 100, 20); // Ellipe
Bezierellipse2 (컨텍스트, 470, 200, 50, 50); //원
Bezierellipse2 (컨텍스트, 470, 200, 100, 20); // Ellipe
// 유사성 감지 (중복 정도)
Paramellipse (컨텍스트, 300, 450, 250, 50);
Context.strokestyle = "Yellow";
Bezierellipse1 (컨텍스트, 300, 450, 250, 50);
context.strokestyle = "blue";
Bezierellipse2 (컨텍스트, 300, 450, 250, 50);
};
CLEARCAVNAS () 함수
{
Context.ClearRect (0, 0, 600, 600);
};
//]]> </script>
<p>
<버튼 onclick = "execdraw ();" 타입 = "버튼"> 실행 </button>
<버튼 onclick = "clearcanvas ();" 입력 = "버튼"> 청소 </button>
</p>
코드를 성공적으로 실행하려면 HTML5 지원 캔버스를 지원하는 브라우저가 필요합니다.
내가 블로그를 처음 썼을 때가 처음이었고 하루 종일 쉽지 않았습니다! 블로그 파크의 어두운 피부 템플릿에는 삽입 된 코드가 잘 표시되지 않습니다. 코드 형식을 얻기 위해 큰 고통을 겪었습니다!