>웹 프론트엔드 >H5 튜토리얼 >캔버스 API, 인기 있는 캔버스 기본 사항 (2)

캔버스 API, 인기 있는 캔버스 기본 사항 (2)

黄舟
黄舟원래의
2017-03-16 13:45:231653검색

위에서 선 그리기, 직사각형 그리기, 텍스트 쓰기에 대해 이야기했습니다. 아직 읽지 않으셨다면 나가서 왼쪽으로 돌아가세요. 여기에서 자세히 알아보고, 다음에는 좀 더 복잡한 속성과 메서드를 살펴보겠습니다.

이야기하기 전에 먼저 복습하고 싶은 부분이 있는데, 위에서 언급하지 않은 속성도 있으니 먼저 삼각형을 그려보겠습니다!

위 내용을 읽어보면 영리한 젊은이는 분명 삼각형이 너무 단순하고 직선보다 한 점이 더 많은 것이라고 생각할 것이기 때문에 젊은이가 그것을 시작했습니다:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.stroke();


아 왜 다중선이냐구요? 삼각형은 점 3개만 있는거 아닌가요? 닫히지 않아서 그런 걸까요? 그럼 한 가지만 더 덧붙이겠습니다:

아아아아아

하하, 나도 당신만큼 재치가 있어요! 이 아이디어는 실제로 올바른 솔루션입니다. 삼각형은 매우 간단합니다. 실제로 3개의 점만 필요한 또 다른 방법이 있습니다.

closePath()는 path

닫혀 있으면 시작입니다. 일반적으로 쌍으로 되어 있습니다.

beginPath() 시작 경로

이 살아있는 보물 쌍의 사용법은 다음과 같습니다. 일반적으로:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.lineTo(50,50);
ctx.stroke();

로드진을 먼저 시작하고, 그 안에 그리고 싶은 내용을 적고, 로드진을 끝내세요. 이는 봉인된 상자와 같습니다. 그리는 과정에서 스타일 오염을 방지하세요. 오염시키는 방법을 모르시나요? 자, 아래를 보세요:

ctx.beginPath();

ctx.closePath();

그림에 표시된 대로 원래 첫 번째 삼각형의 색상을 빨간색으로, 두 번째 삼각형의 색상을 녹색으로 하고 싶었지만 이제 결과는 모두 녹색이고 선명합니다. 동급생 눈도 봤는데 첫 번째 삼각형이 두 가지 색을 띠고 있는 것 같고, 색깔도 두 개의 삼각형이 겹쳐진 것 같은 느낌이 드네요. 좋아, 바꿔보자. 지금 보고 있다:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
//第一个三角
ctx.strokeStyle='red';
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.lineTo(50,50);
ctx.stroke();
//第二个三角
ctx.strokeStyle='green';
ctx.moveTo(150,50);
ctx.lineTo(200,100);
ctx.lineTo(150,200);
ctx.lineTo(150,50);
ctx.stroke();

첫 번째 삼각형이나 두 번째 삼각형의 왼쪽을 그리지 말고 살펴보자:

첫 번째 삼각형 one 삼각형은 더 이상 이중 색상을 갖지 않습니다. 한 번은 빨간색으로, 한 번은 녹색으로 그려졌습니다. 이후의 색상도 이전 색상을 오염시켰습니다. 이것은 우리가 원하는 것이 아닙니다.

그럼 살아있는 보물 한 쌍을 사용해 살펴보겠습니다.

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
//第一个三角
ctx.strokeStyle='red';
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.lineTo(50,50);
//ctx.stroke();
//第二个三角
ctx.strokeStyle='green';
ctx.moveTo(150,50);
ctx.lineTo(200,100);
ctx.lineTo(150,200);
//ctx.lineTo(150,50);
ctx.stroke();

이것이 우리가 원하는 것입니다. 당신은 당신의 것을 가지고 놀고 나는 서로 방해하지 않고 내 것을 가지고 놀아요. 삼각형 점 3개만 있으면 됩니다. B 자랑하세요. 점 4개를 사용하고 계시군요.) 아, 그렇군요.

closePath() 메소드는 현재 지점에서 시작점까지의 경로를 생성한다는 의미입니다. 즉, 이 메소드를 사용하면 BeginPath 위치로 브러시를 이동할 수 있다는 것입니다. ()이므로 캔버스를 종료하므로 이 이론에 따르면 삼각형을 그릴 때 세 번째 점까지 그릴 때 closePath() 메서드를 사용하여 브러시를 시작점으로 되돌린 다음 선을 그립니다. 닫혔나요? 효과를 볼까요:

으아아아아

봐, 폴리라인이 아닌 포인트가 3개밖에 없잖아? 나중에 얘기할 팬차트나 불규칙한 그래픽에도 이 스킬을 쓸 수 있잖아!

그냥 선이 모두 하나의 픽셀이고 Sun Wukong의 황금 몽둥이와 같을 수는 없으며 더 작아야 합니다. 허, 누가 그런 말을 했어? 내 손에 마법 무기가 있으니 넌 무적이야!

나의 마법 무기는:

lineWidth는 현재 선 너비를 설정하거나 반환합니다.
사용 방법
? 형님이 황금테를 주셨네요:

으르르

금테, 크, 크, 크, 크, 크, 하하하~~
에흠, 진지하게, 이 아티팩트로 우리 선 굵기를 수정할 수 있어요 속이 빈 삼각형이나 속이 빈 직사각형과 같은 와이어프레임과 선의 경우 물론 속이 빈 텍스트에 대해서는 묻지 마세요~
선에 대해서는 두 가지 다른 속성이 있습니다.
lineJoin 코너 유형 두 선이 교차하는 위치
매개변수:
마이터: 날카로운 모서리 기본값
베벨: 경사
둥근: 둥근 모서리

무슨 뜻인가요? 빈 직사각형을 사용하세요. 예:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
//第一个三角
ctx.beginPath();
ctx.strokeStyle='red';
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.lineTo(50,50);
ctx.closePath();
ctx.stroke();
//第二个三角
ctx.beginPath();
ctx.strokeStyle='green';
ctx.moveTo(150,50);
ctx.lineTo(200,100);
ctx.lineTo(150,200);
ctx.lineTo(150,50);
ctx.closePath();
ctx.stroke();

오른쪽은 폴리라인 효과입니다

폴리라인 효과에는 다음 속성도 있습니다.

miterLimit는 최대 마이터 길이를 지정합니다. 무슨 뜻인가요? 오른쪽의 꺾은선형 차트를 보십시오. 날카로운 모서리의 아래쪽 그룹을 마이터라고 합니다. 일반적인 의미는 날카로운 모서리의 길이가 miterLimit 값보다 작은 경우입니다. 이 값보다 크면 일부가 잘려지고 lineJoin='bevel'과 동일하게 됩니다. 이 방법은 lineJoin="miter"가 기본값으로 설정된 경우에만 작동합니다. .예를 들어보겠습니다:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.beginPath();
ctx.strokeStyle='red';
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.closePath();
ctx.stroke();
varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
vartimer=null;
varnum=1;
ctx.moveTo(150,50);
ctx.strokeStyle='gold';
setInterval(function(){
if(num==100){
clearInterval(timer);
num=1;
}else{
num++;
};
ctx.lineTo(150,100+num*2);
ctx.lineWidth=num;
ctx.stroke();
},100)

그림과 같이 miterLimit 값이 19보다 크거나 같을 때 뾰족한 모서리가 18보다 작을 때 뾰족한 모서리가 정상적으로 표시됩니다. 모서리가 잘립니다. 효과는 lineJoin='bevel'을 설정하는 것과 동일합니다. 어떤 효과가 있는지는 나중에 알아보겠습니다.

또 다른:
lineCap은 선의 끝점 스타일을 설정하거나 반환합니다. 참고로 이는 선을 설정하기 위한 것입니다!
매개변수:
기본값입니다. 선의 각 끝에 직선 모서리를 추가합니다.
라운드는 선의 각 끝에 둥근 와이어 캡을 추가합니다.
square는 선의 각 끝에 정사각형 선 캡을 추가합니다.
무슨 뜻인가요? 선은 황금색 곤봉을 예로 들어보겠습니다. (황금색 곤봉을 보면 웃고 싶어요)

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.lineWidth=10;
ctx.beginPath();
ctx.lineJoin='miter';
ctx.strokeRect(100,10,80,80);
ctx.closePath();
ctx.beginPath();
ctx.lineJoin='round';
ctx.strokeRect(100,110,80,80);
ctx.closePath();
ctx.beginPath();
ctx.lineJoin='bevel';
ctx.strokeRect(100,210,80,80);
ctx.closePath();

보시다시피 마지막 두 개가 더 좋습니다. 첫 번째 더 길어야 하는데, 얼마나 더 길어야 하나요? 설명할 그림 그리기:

圆角和方脚的原理其实是这样的,很明显多出的一部分的宽度就是线条的一半的长度,所以要精确计算其长度,此小细节需谨记!

现在我们来讲讲画圆及其相关的图形:

arc(x,y,r,sAngle,eAngle,counterclockwise)

什么意思?x,y表示坐标点表示圆心坐标,r表示半径,sAngle表示开始弧度,eAngle表示结束弧度,counterclockwise表示顺时针还是逆时针方式,默认为顺时针false,逆时针为true

注意,这里的角度是用弧度表示的,不是直接写角度,那问题来了,一般我们知道一个圆弧是多少度,怎么知道它是多少弧度呢?总感觉弧度太抽象,嗯嗯,我也有同感,那我们就来科普一下弧度的算法吧,列几个公式(初中,高中的数学,都还给老师了):

1弧度=r;
360°=2∏;
周长C=2∏r;
那么一周的弧度数=2∏r/r=2∏=360°
则1°=2∏*1°/360°=∏*1°/180°(弧度)
90°=∏*90°/180°(弧度)

圆的初始位置是在最右边,跟我们自己手绘圆的起点有那么一点点的不一样,默认是顺时针方向,那角度就应该是如图所示的角度,要是还不清楚的话,我们画2半圆,分别表示顺时针和逆时针,这样就应该清楚了,哦,需要说明的一点就是,画用的方法跟画直线和矩形框的原理是一样的,只是画出了路径,并没有添墨水,仍需用黑白双煞:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.beginPath();
ctx.arc(80,100,50,0,180*Math.PI/180,false);
ctx.stroke();

ctx.beginPath();
ctx.arc(200,100,50,0,180*Math.PI/180,true);
ctx.stroke();

js里面是没有∏的,你懂的,但是有函数Math.PI,咦,这里为什么是圆弧而不是半圆啊,如果我要画一个半圆怎么弄呢?哈哈~,还记得上面三角形的那个折线吗?这个是一个原理,只是图形没有闭合而已,用closePath()就可以闭合了。

画一个扇形看看,这里我就闭合图形哈:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.beginPath();
ctx.arc(80,100,50,30*Math.PI/180,150*Math.PI/180,false);
ctx.closePath();
ctx.stroke();

当当当当~~~噗,喷了一口老血,怎么是一条小船,说好的扇子呢?再看看三角图形,瞬间就明白了,图形闭合不是以圆心为起始点的,而是初始弧度为起点,然后闭合的时候是回到初始点,就变成小船了,那怎么才能画出一个扇形呢?给个思路,这里暂时不给代码,以后有时间当小实例给到大家,如果我以圆心为起点,画2条直线,连到圆弧的起始点和结束点,是不是就是一个扇形了,哈哈~,不多说了,脑补一下吧,当然,圆弧的起始点的坐标和结束点的坐标计算还是有点费劲的

前面我们画的是空心的圆或弧,可否画实心的呢?貌似问的有点多余,上面说了用黑白双煞,好吧,直接给个一饼好了:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.arc(150,150,50,0,360*Math.PI/180,false);
ctx.fill();

咦,怎么这么像某岛国国旗,还好我用的是默认黑色,嘘嘘,都没看到哈~
还有一个方法可以画圆弧:
arcTo(x1,y1,x2,y2,r)创建两个切线之间的弧/曲线
参数:x1,y1表示第一个坐标,x2,y2表示第二个坐标,r表示曲线半径
两个切线之间的曲线,试试:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
ctx.lineTo(100,20);
ctx.arcTo(150,20,150,70,50);
ctx.lineTo(150,120);
ctx.stroke();

果然是要在两条线段之间写曲线,要是先写2条曲线,在写arcTo(),貌似就出不来了,这让我们想到了moveTo(),lineTo(),再写一个例子:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.moveTo(150,20);
ctx.arcTo(150,200,50,0,20);
ctx.stroke();

想试一下,要是只有一条切线,会怎样?

好大的一个鱼钩啊,看来这样也是可以的,要是没有切线,可否?

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.arcTo(150,200,50,0,20);
ctx.stroke();

额,狗带了,没反应,看来必须至少有一个切线才能画弧线,有个点都行,要求不算高,满足你。

感觉这里始终没有将清楚,arcTo()为什么会画出这样的曲线呢,我觉得有必要画一张图来表示:

它的绘图原理应该是这样的,起始点是圆弧的第一个切点,也是画笔的起始点,然后arcTo的两个坐标点分别是圆弧的起点和终点,这样3个点就形成了2天相交的线,然后以半径为r画一个圆,与这2条线相切,2个切点就是绘制的这条弧,而第二张图就是arcTo()所绘制的图形,为了证实这一点,我们写一个相近的图形来看看:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.beginPath();
ctx.fillRect(100,100,5,5);
ctx.fillRect(180,80,5,5);
ctx.fillRect(160,180,5,5);
ctx.moveTo(62,112);
ctx.lineTo(182,82);
ctx.lineTo(162,182);
//这里是绘制切线弧
ctx.moveTo(103,103);
ctx.arcTo(183,83,162,182,40);
ctx.stroke();

对比这2组图,将生成的弧线用圆对比一下,会发现起点并不是切点,但基本思路是正确的,3点形成一个夹角,然后以r为圆心,画一个圆,从起点到第二个切点,就是arcTo()方法所绘制的图形。

今天就到这吧!讲的很混乱,东一脚西一脚的,希望你们能懂!最希望的是能对你们有帮助,那就再好不过了!

 以上就是canvas API ,通俗的canvas基础知识(二) 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

相关文章:

canvas API 介绍,常见的canvas基础知识(一)

캔버스 API 소개, 캔버스 공통 기초지식(3)

캔버스 API 소개, 캔버스 공통 기초지식(4)

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.