이 글에서 공유한 내용은 캔버스를 사용하여 선분을 그리는 방법에 대한 내용입니다. 다음으로 구체적인 내용을 살펴보겠습니다.
캔버스를 배우려면 먼저 선분을 그리는 방법을 알아야 하며, 그런 다음 간단한 선분을 많이 사용하여 보다 복잡한 그래픽을 구현할 수 있습니다. 예를 들어 일반적인 차트, 막대 차트, 선 차트 등은 모두 통해 구현됩니다. 선분.
캔버스에 대한 기본 지식은 많지 않으며 주로 선분, 그래픽, 그림, 텍스트 등을 그리는 방법을 마스터합니다. 브라우저에서 캔버스를 그릴 수도 있고, node-canvas의 도움으로 노드 서버에서 간단한 그림을 그릴 수도 있습니다. 본 글은 브라우저에서의 드로잉만을 기록하고 있으며, 노드 측에서 그리는 방법은 직접 확인하실 수 있습니다.
브라우저에서 그리려면 먼저 HTML에서 캔버스 요소를 정의하세요. 기본 너비와 높이는 300 * 150이며 너비
및 높이
를 통해 설정할 수 있습니다. 캔버스 요소 스타일의 너비와 높이는 캔버스 그리기 캔버스의 너비와 높이가 동일하지 않다는 점에 유의하세요. width
和height
设置。注意canvas元素样式宽高和canvas绘图画布宽高不是一个东西,这块将在以后说的。
<canvas> <p>当前浏览器不支持canvas,请升级浏览器</p> </canvas>
在绘制之前,我们要先获取当前canvas的2d绘制上下文context,后续总是通过操作context来进行绘制。
let canvas = document.querySelector('#canvas'); if (!canvas) { throw new Error('can not find canvas element'); } // 注意2d.参数必须是小写的; // 通过设置参数为webgl,可以获取3d绘制上下文 let ctx = canvas.getContext('2d');
注:后续示例中会忽略上面的代码片段,直接使用 ctx
变量表示canvas的2d绘制上下文。
再来看看canvas 2d绘制中的坐标系统,当前canvas元素左上角为坐标原点(0,0),水平向右为X轴正方向,垂直向下为Y轴正方向,如下图。可以通过平移(translate),旋转(rotate),缩放(scale)来操作坐标系,实现一些动画,这部分将在动画知识部分详细讲解。
在绘制一条简单的线段时,一般会先设置线段的样式,比如,颜色,线条宽度,线条端点样式等,我们通过设置strokeStyle
来设置ctx
的全局绘制样式,可以是rgba
或合法的16进制颜色值,或者渐变对象等。如下代码简单的绘制了一条从(10,10)到(50,60)的,宽度为10的,红色的线段。
ctx.strokeStyle = 'red'; ctx.lineWidth = 10; ctx.moveTo(10, 10); ctx.lineTo(50, 60); ctx.stroke();
先看看与绘制线段相关的方法以及属性,
相关属性:
lineCap,该值告诉浏览器如何绘制线段的端点,可选值为以下三个之一:butt,round,square。默认为butt。
lineWidth,该值决定了线段的像素宽度。必须为非负,非无穷,默认为1.0。
lineJoin,决定了两条线段相交时如何绘制焦点,只有当两条线段方向不同时,才会生效。可取值:bevel,round,miter。默认值是miter。
miterLimit,告诉浏览器如何绘制miter形式的线段焦点,只有当lineJoin='miter'
有效,默认为10.0。
lineDashOffset,设置虚线偏移量,默认为0.0。
相关方法:
beginPath,将当前路径之中的所有子路径都要清除掉,以此来重置当前路径。一般在绘制闭合图形时要先调用。
closePath ,显示的封闭某段路径。该方法用于封闭圆弧路径以及由曲线或线段所创建的开放路径。
moveTo,移动当前绘制点到指定的坐标。
lineTo,从上一个点绘制一条到指定坐标点的线段。
setLineDash,用来设置虚线的方法,参数是一个数组,表明绘制实线的长度,以及实线之间的间隙的长度。
试试用设置不同的lineCap
值来绘制同样的线段
ctx.lineWidth = 10; ctx.textAlign = 'center'; let colors = ['red', 'green', 'blue']; let lineCaps = ['butt', 'round', 'square']; for (let [index, lc] of lineCaps.entries()) { ctx.strokeStyle = colors[index]; //设置线段的颜色 ctx.lineCap = lc; // 设置lineCap ctx.beginPath(); // 清空当前路径 ctx.moveTo(10, 20 + 20 * index); ctx.lineTo(50, 20 + 20 * index); ctx.stroke(); ctx.fillText(lc, 80, 25 + 20 * index); }
从上图结果可以看出,再将lineCap
设置为round 和square时会在原线段的两端加上一定长度的端点,只不过round是圆弧样式,square是矩形样式。需要注意的一点是,在canvas绘制上下文中同一时刻只能存在一个当前路径,为了绘制不同的线段,必须在每次绘制之前调用beginPath()
来清空当前路线,开始新的路径。
再来试试用不同的lineJoin
ctx.lineWidth = 20; ctx.textAlign = 'center'; ctx.lineCap = 'butt'; let colors = ['red', 'green', 'blue']; let lineJoins = ['bevel', 'round', 'miter']; for (let [index, lj] of lineJoins.entries()) { ctx.strokeStyle = colors[index]; //设置线段的颜色 ctx.lineJoin = lj; //设置lineJoin ctx.beginPath(); //清空当前路径 ctx.moveTo(10 + 80 * index, 20); ctx.lineTo(50 + 80 * index, 20); ctx.lineTo(50 + 80 * index, 60); ctx.stroke(); ctx.fillText(lj, 40 + 80 * index, 80); }
ctx.lineWidth = 10; ctx.textAlign = 'center'; ctx.setLineDash([8, 8]); //表示实线部分8个像素,间隙部分8个像素 let colors = ['red', 'green', 'blue']; let lineDashOffsets = [1, 2, 4]; for (let [index, ldOffset] of lineDashOffsets.entries()) { ctx.strokeStyle = colors[index]; //线段颜色 ctx.lineDashOffset = ldOffset; //设置了偏移量 ctx.beginPath(); ctx.moveTo(10, 20 + 20 * index); ctx.lineTo(100, 20 + 20 * index); ctx.stroke(); ctx.fillText(`lineDashOffset:${ldOffset}`, 160, 25 + 20 * index); }
ctx
변수가 캔버스의 2D 그리기 컨텍스트를 나타내는 데 직접 사용됩니다. 캔버스 2D 도면의 좌표계를 살펴보겠습니다. 현재 캔버스 요소의 왼쪽 상단은 좌표 원점(0,0)이고, 수평 오른쪽은 X-의 양의 방향입니다. 축이며 수직 아래쪽은 다음 그림과 같이 Y축의 양의 방향입니다. 일부 애니메이션을 구현하기 위해 변환, 회전 및 크기 조정을 통해 좌표계를 조작할 수 있습니다. 이 부분은 애니메이션 지식 섹션에서 자세히 설명합니다. 🎜🎜🎜🎜🎜Line Segment🎜🎜간단한 선분을 그릴 때 일반적으로 색상, 선 너비, 선 끝점 스타일 등 선분의 스타일을 먼저 설정합니다. 설정 >ctx의 전역 그리기 스타일은 rgba
또는 합법적인 16진수 색상 값 또는 그라데이션 객체 등이 될 수 있습니다. 다음 코드는 단순히 (10,10)에서 (50,60)까지 너비가 10인 빨간색 선분을 그립니다. 🎜ctx.lineWidth = 10; ctx.textAlign = 'center'; let colors = ['red', 'green', 'blue', 'gray']; let lineDashes = [[20, 20], [40, 40], [20, 40], [20, 40, 20]]; for (let [index, ld] of lineDashes.entries()) { ctx.strokeStyle = colors[index]; //设置颜色 ctx.setLineDash(ld); //设置lineDash ctx.beginPath(); ctx.moveTo(10, 20 + 20 * index); ctx.lineTo(171, 20 + 20 * index); ctx.stroke(); ctx.fillText(`lineDashes:[${ld}]`, 240, 25 + 20 * index); }
lineJoin='miter'
인 경우에만 유효하며 기본값은 10.0입니다. . 🎜lineCap
값을 설정하여 동일한 선분을 그려보세요 🎜let lineDashOffset = 0; //初始lineDashOffset ctx.strokeStyle = 'green'; function animate() { if (lineDashOffset > 25) { lineDashOffset = 0; } ctx.clearRect(0, 0, width, height); //清空当前canvas ctx.lineDashOffset = -lineDashOffset; //设置lineDashOffset ctx.setLineDash([4, 4]); // 设置实线长度和间隙长度 ctx.rect(20, 20, 100, 100); //绘制一个矩形 ctx.stroke(); //对canvas当前路径描边 lineDashOffset += 1; //lineDashOffset偏移加1 window.requestAnimationFrame(animate); //用浏览器帧速率来反复执行animate函数 } animate();
beginPath()
를 호출하여 해당 경로를 지워야 합니다. 현재 경로를 선택하고 새 경로를 시작하세요. 🎜🎜다른 lineJoin
값을 사용하여 두 선분의 초점에 스타일을 그려보겠습니다🎜rrreee🎜🎜🎜🎜🎜可以看到,三种lineJoin
在处理两条线段的焦点处的不同。其中,在设置lineJoin="miter"
时,通过设置miterLimit
属性可以设置斜接线的长度与二分之一线宽的最大比值,当超过这个比值时,则lineJoin
会采用bevel方式。
canvas不仅可以绘制实线,还可以绘制虚线。绘制虚线,通过设置lineDashOffset
属性和调用setLineDash()
方式。
ctx.lineWidth = 10; ctx.textAlign = 'center'; ctx.setLineDash([8, 8]); //表示实线部分8个像素,间隙部分8个像素 let colors = ['red', 'green', 'blue']; let lineDashOffsets = [1, 2, 4]; for (let [index, ldOffset] of lineDashOffsets.entries()) { ctx.strokeStyle = colors[index]; //线段颜色 ctx.lineDashOffset = ldOffset; //设置了偏移量 ctx.beginPath(); ctx.moveTo(10, 20 + 20 * index); ctx.lineTo(100, 20 + 20 * index); ctx.stroke(); ctx.fillText(`lineDashOffset:${ldOffset}`, 160, 25 + 20 * index); }
从图可以看到lineDashOffset
就是设置的开始绘制虚线的偏移量。setLineDash()
方法,接受一个数组参数,如果数组个数是奇数,则会默认把当前数组元素复制一份,使之变成偶数。从第0个元素,表示实线部分长度,第1个元素,表示间隙部分长度,第2个元素,表示实线部分长度,第3个元素,表示间隙部分长度,如果到数组最后一个元素了,又会从头开始,以此类推。
ctx.lineWidth = 10; ctx.textAlign = 'center'; let colors = ['red', 'green', 'blue', 'gray']; let lineDashes = [[20, 20], [40, 40], [20, 40], [20, 40, 20]]; for (let [index, ld] of lineDashes.entries()) { ctx.strokeStyle = colors[index]; //设置颜色 ctx.setLineDash(ld); //设置lineDash ctx.beginPath(); ctx.moveTo(10, 20 + 20 * index); ctx.lineTo(171, 20 + 20 * index); ctx.stroke(); ctx.fillText(`lineDashes:[${ld}]`, 240, 25 + 20 * index); }
可以通过动态设置lineDashOffset
来实现蚁线,比如选择PS中选区边缘的蚁线。
let lineDashOffset = 0; //初始lineDashOffset ctx.strokeStyle = 'green'; function animate() { if (lineDashOffset > 25) { lineDashOffset = 0; } ctx.clearRect(0, 0, width, height); //清空当前canvas ctx.lineDashOffset = -lineDashOffset; //设置lineDashOffset ctx.setLineDash([4, 4]); // 设置实线长度和间隙长度 ctx.rect(20, 20, 100, 100); //绘制一个矩形 ctx.stroke(); //对canvas当前路径描边 lineDashOffset += 1; //lineDashOffset偏移加1 window.requestAnimationFrame(animate); //用浏览器帧速率来反复执行animate函数 } animate();
绘制线段时,要理解canvas当前路径概念,某一时刻,canvas中当前路径只有一条,在开始新的路径时,必须调用beginPath()
。可以通过设置lineWidth
,lineCap
,lineJoin
设置线段的绘制样式。在描边线段时,可以通过strokeStyle
来设置线段的颜色。
canvas中不仅可以绘制实线,还可以通过lineDashOffset
和setLineDash()
来绘制虚线。
相关推荐:
위 내용은 캔버스를 사용하여 선분을 그리는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!