이 글은 HTML5 Canvas에서 직선을 그리는 방법과 선 스타일을 설정하는 방법을 주로 소개합니다. 참고할 만한 가치가 있습니다. 도움이 필요한 친구들이 참고할 수 있도록 공유합니다.
그림을 배울 때 가장 기본적인 것은 선입니다. , 선의 연결은 어떤 모양이든 만들 수 있습니다. 다음으로는 가장 간단한 선 그리기 방법을 자세히 소개하겠습니다.
아직 캔버스가 무엇인지 모르신다면 이전 글을 읽어보세요.
그림을 배울 때 선이 가장 기본이고 선의 연결이 모든 그래픽을 형성할 수 있습니다. 캔버스에서도 마찬가지입니다.
시작하기 전에 캔버스와 브러시를 꺼냅니다.
var cvs = document.getElementById('cvs'); //画布 var ctx = cvs.getContext('2d'); // 画笔
그림을 그릴 때 시작점은 고정되어 있지 않고 언제든지 바뀔 수 있습니다. 캔버스에서는 필기 지점을 직접 결정하지 않지만 moveTo라는 방법이 있습니다. moveTo의 기능은 펜촉을 캔버스에서 들어 올려 지정된 지점(예: 좌표)으로 이동하는 것과 같습니다.
ctx.moveTo(x,y)
이 과정에서는 그래픽이 그려지지 않습니다. 이는 캔버스에 펜을 대고 있는 것과 같습니다.
하지만 여기저기 돌아다녀도 소용없어요. 그리기 시작해야 해요. 가장 간단한 것을 먼저 그립니다: 직선
직선을 그리는 방법은 lineTo입니다. 해당 매개변수는 점인 moveTo와 동일합니다.
ctx.lineTo(x,y) 물론 선을 그리면 쓰기 지점도 이동하므로 lineTo 이후에는 쓰기 지점이 목표 지점이 됩니다.
ctx.moveTo(100,100); ctx.lineTo(200,100);
이때 웹페이지를 새로고침하면 캔버스에 예상한 선도 없고 아무것도 없는 것을 확인할 수 있습니다. 한 단계가 누락되었기 때문에 lineTo는 실제로 그 자체로 보이지 않는 "경로"입니다. 표시하려면 "그려"야 합니다.
PS를 사용해 본 학생들은 두 가지 그래픽 모드, 즉 채우기 모드와 획 모드를 확실히 알고 있을 것입니다. 이제 선을 그렸으므로 PS에서 경로를 그리는 것과 같습니다. 이때 경로의 가장자리를 그릴 수 있으며 그래픽이 표시됩니다.
캔버스 스트로크 방법은 스트로크()입니다. 이제 코드를 완성해 보겠습니다.
ctx.moveTo(100,100); ctx.lineTo(200,100);
ctx.스트로크() 이때 새로고침하면 선이 표시됩니다. 물론 수백 개의 경로를 연속으로 그린 다음 스트로크 동작을 수행하여 수백 개의 선을 한 번에 그릴 수도 있습니다. 이제 4개의 선으로 직사각형을 그려 보겠습니다.
ctx.moveTo(100,100); ctx.lineTo(200,100); ctx.lineTo(200,200); ctx.lineTo(100,200); ctx.lineTo(100,100); ctx.stroke();
여기에서는 먼저 전체 경로를 그린 다음 한 번에 모두 획을 그립니다.
———작가의 불만: 캔버스 그리기의 한 가지 단점은 기본적으로 추측에 기반을 두고 있다는 점이며, 이는 매우 직관적이지 않습니다.
중요 알림: 캔버스 그리기 프로세스(예: 채우기 및 스트로크)는 리소스를 많이 소모합니다. 시스템 리소스를 절약하고 효율성을 높이려면 모든 경로를 그린 다음 그래픽을 한 번에 채우거나 스트로크하는 것이 가장 좋습니다.
위 그래픽을 보면 기본 선 굵기가 1px이고 선 색상이 검은색임을 알 수 있습니다. 물론 설정할 수 있지만 이상한 점은 선 너비를 설정하는 것이 lineWidth인데 선 스타일을 설정하는 것을 스트로크 스타일이라고 한다는 것입니다. 나도 모른다. :
ctx.lineWidth = 10; ctx.strokeStyle = 'rgba(255,0,0,0.5)';
위 코드는 선 너비를 10px로 설정하고 선 색상을 반투명 빨간색으로 설정합니다.
그림 1과 같이 새로고침해 보세요. 뭔가 잘못된 것 같습니다! 왼쪽 상단 모서리에 작은 조각이 누락된 이유는 무엇입니까? 이것은 환상이 아닙니다. 그 이유는 캔버스의 선 그리기 방식에서 시작된다.
질문: 내가 그리는 직사각형 경로의 너비와 높이가 100이고 옆선 너비가 10픽셀인 경우 측면이 그려진 직사각형의 전체 너비와 높이는 얼마입니까? 100+10*2=120인가요?
가장자리가 경로 바깥쪽으로 완전히 그려지면 120입니다. 하지만 캔버스는 그렇지 않습니다. 캔버스의 모든 선에는 선의 절대 중앙에 위치한 "중간선"이 있습니다. 선의 획은 중심선에서 양쪽으로 확장됩니다. 예를 들어, 선 너비가 1이면 중심선은 0.5이고, 너비가 5이면 중심선은 2.5입니다. 캔버스 그래픽을 스트로크하면 경로가 선의 중심선에 정렬된 다음 스트로크됩니다. 그림 2와 같이:
그래서 추적할 때 선의 절반은 외부에 있고 절반은 내부에 있습니다. 즉, 위 직사각형의 전체 너비는 100+(10/2)입니다. *2, 110과 같습니다.
도 맞습니다. 따라서 왼쪽 상단에 누락된 모서리가 있는 것은 당연합니다. 여기에는 아무도 그림을 그리지 않으니까요.
그런데 나머지 모서리는 왜 깨지지 않나요? 사진 네 귀퉁이에 틈이 있는 것 같지 않나요?
선을 그릴 때 브러시를 "들어 올리지" 않았기 때문입니다. 즉, 브러시가 연속적으로 움직이지 않았기 때문입니다. 믿기지 않는다면 이제 moveTo를 해보자:
ctx.moveTo(100,100); ctx.lineTo(200,100); ctx.moveTo(200,100); //注意这里 ctx.lineTo(200,200); ctx.lineTo(100,200); ctx.lineTo(100,100); ctx.lineWidth = 10; ctx.strokeStyle = 'rgba(255,0,0,0.5)'; ctx.stroke();
두 번째 선을 그리기 전에 moveTo를 옮겼고, moveTo의 좌표는 변하지 않아 여전히 같은 지점이었는데, 새로고침을 하고 나면 그래프가 이렇게 된다. [그림 3]:
明白了?因为我们把笔提起来了。
现在我们删掉moveTo,不要纠结他了,我们来思考一下如何把左上角那个缺角给补上?
首先问个问题,我们的路径闭合了吗?这不是废话么,我们不是已经把路径绕回原点了么?当然算是闭合了!
错!这样只是让路径最后一个点和起点重合了而已,路径本身却没有闭合!
Canvas怎么闭合路径?用closePath().
ctx.moveTo(100,100); ctx.lineTo(200,100); ctx.lineTo(200,200); ctx.lineTo(100,200); ctx.lineTo(100,100); ctx.closePath();//闭合路径 ctx.lineWidth = 10; ctx.strokeStyle = 'rgba(255,0,0,0.5)'; ctx.stroke();
此时刷新,就是一个完美的正方形了。图4:
无论我们把线条改到多粗————越粗越有人喜欢是吧?————这个四方形的四个角都是规矩的直角,不会出现圆滑的情况。圆滑的角是什么情况?请看PS中的四方形描边,图5:
看到了吧,越粗的边线,他的角的圆弧越大。
如果我想Canvas里面的边线也和PS这种一样,有没有办法呢?当然有,就是lineJoin属性。
lineJoin,意思即线的交汇处,有3个属性:miter(默认,尖角),bevel(斜角),round(圆角),如图6:
毫无疑问我们一下就能明白我们的矩形用的是尖角,所以试着把他改成圆角看看:
图形变成了这样,图7:
有点像PS的了吧?
另外,通过前面图我们了解到,Canvas的线条两端是平的,可不可以改呢?毕竟平的不好看。
也是可以的,即lineCap属性,这个就是定义线条的端点。lineCap有3个值:butt(平,默认),round(圆),square(方),如图8
看图就能发现,其实平头跟方头是一样的,区别只是平头没有伸出去那么一截。圆头和方头都会伸出去一截,这一节是多长呢?就是线条宽度的一半。
你有没有想到什么?哈哈,前面的闭合路径的问题,如果我们把lineCap设为方头,效果也是一样的!
但为了保险起见,我们还是要把路径闭合了,切记!
我还要提醒一下:闭合的路径没有端点!所以闭合的路径上看不到端点的样式。
另外:lineCap与lineJoin有点相似,注意不要搞混。
如果你眼尖并且运气不好,你可能会发现有时候1像素的线条不是1像素宽,好像要宽一些,模糊一些。如图9:
恭喜你!你遇到了一个不是bug的bug。这个很特别,我把他放到下一篇文章讲吧
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
HTML5 Canvas渐进填充与透明实现图像的Mask效果
위 내용은 html5 Canvas는 직선 그리기 및 선 스타일 설정을 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!