一、绘制一条直线
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <style> canvas{ border: 1px solid #333; } </style> </head> <body> <canvas id="my_anvas" width="300" height="300"></canvas> <script> var myCanvas = document.querySelector("canvas"); //获取上下文 var ctx = myCanvas.getContext("2d"); //移动画笔,原移到X:100 , Y:100 的位置 ctx.moveTo(100, 100); //绘制轨迹 ctx.lineTo(200, 100); //描边 ctx.stroke(); </script> </body> </html>
浏览器显示:
1、canvas元素
可以理解为画布,默认的背景是 #FFFFFF , 默认大小为 300 * 150 ,无边框
1.1、设置canvas 的大小建议在行内设置 , 因为在CSS中设置canvas的宽高 ,相当于从右下角把画布拉伸到指定的大小
例:在CSS中设置画布大小为300 * 300 ,显示如下 :
可以看到线的位置和大小都变了,因为画布被拉伸大了,里面的内容自然也被拉大了。
2、canvas元素里面的线
默认颜色 : 黑色 显示颜色 : 灰色
默认宽度 : 1px 显示宽度 : 2px
原因 :因为canvas 中线是从刻度 1px 的中间开始绘制 (刻度1px 对着线的中间),上线各占0.5px,而电脑无法解析0.5px,所以上下各延伸了0.5px,显示的宽度就成了2px 。 又因为0.5px 造成颗粒不饱和 ,显示的颜色变浅 ,就成了灰色。
解决方法 : 绘制的线往上或下移动 0.5px , 如 ctx . moveTo(100, 99.5); ctx . lineTo(300, 99.5);
3、线的属性
3.1 、 strokeStyle :设置线的颜色
lineWidth :设置线的宽度
注 :在多条线下 , 相同的属性是会覆盖的 。
例:画三条线,第一条宽度为10,颜色黄色,第二条宽度为20,颜色红色,第三条宽度为30,颜色粉色
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <style> canvas{ border: 1px dotted #ccc; background-color: orange; } </style> </head> <body> <canvas id="my_anvas" width="400" height="400"></canvas> <script> var myCanvas = document.querySelector("canvas"); var ctx = myCanvas.getContext("2d"); //第一条线 , 宽 :10 ,颜色 : yellow ctx.moveTo(100, 100); ctx.lineTo(300, 100); ctx.strokeStyle = "yellow"; ctx.lineWidth = 10; ctx.stroke(); //第二条线 ,宽 :20 , 颜色 :red ctx.moveTo(100, 200); ctx.lineTo(300, 200); ctx.strokeStyle = "red"; ctx.lineWidth = 20; ctx.stroke(); //第三条线 ,宽 :30 , 颜色 :pink ctx.moveTo(100, 300); ctx.lineTo(300, 300); ctx.strokeStyle = "pink"; ctx.lineWidth = 30; ctx.stroke(); </script> </body> </html>
结果 : 却和想象的不一样 ,显示出了三条粉色的线 ,图(1)
原因 :因为属性是会覆盖的,下面的 lineWidth 和 strokeStyle 覆盖了上面设置的值
图(1)
图(2)
解决方法 :beginPath(); //开启新的路径 ,在绘制每一条线前设置 ,它下面的属性不会影响到上面设置的属性 ,互不相干(上面设置的属性会影响上面,如果上面设置了lineWidth或strokeStyle,下面没设,下面的线会跟随上面的样式),得到结果 图(2)
//开启新路径 ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(300, 100); ctx.strokeStyle = "yellow"; ctx.lineWidth = 10; ctx.stroke(); //开启新路径 ctx.beginPath(); ctx.moveTo(100, 200); ctx.lineTo(300, 200); ctx.strokeStyle = "red"; ctx.lineWidth = 20; ctx.stroke(); //开启新路径 ctx.beginPath(); ctx.moveTo(100, 300); ctx.lineTo(300, 300); ctx.strokeStyle = "pink"; ctx.lineWidth = 30; ctx.stroke();
3.2、 closePath( ) //自动闭合,关闭路径 ,和上面的beginpath( )没有半毛钱关系
例 :画一个三角型 , 线宽为10
// 省略了上面的通用代码 ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(300, 100); ctx.lineTo(300, 300); ctx.lineTo(100, 100); ctx.lineWidth = 10 ; ctx.stroke();
结果 :可以看到图(1)左上角有一个缺口 ,因为原点刻度从0.5开始 ,
解决方法,不绘制最后一条线 ,用它的 closePath( ) 方法,自动闭合图形 ,得到结果 图(2)
(图1)
(图2)
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(300, 100);
ctx.lineTo(300, 300);
ctx.closePath();
ctx.lineWidth = 10 ;
ctx.stroke();
3.3、lineCap : 给线的两端设置样式 (cap:帽子 ,可以理解为给两个端点戴上一个帽子)
样式 :butt(默认) , round (环绕) , square (方的)
ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(300, 100); ctx.lineWidth = 10; ctx.strokeStyle = "skyblue"; ctx.lineCap = "butt"; ctx.stroke(); ctx.beginPath(); ctx.moveTo(100, 120); ctx.lineTo(300, 120); ctx.lineWidth = 10; ctx.strokeStyle = "red"; ctx.lineCap = "square"; ctx.stroke(); ctx.beginPath(); ctx.moveTo(100, 140); ctx.lineTo(300, 140); ctx.lineWidth = 10; ctx.strokeStyle = "green"; ctx.lineCap = "round"; ctx.stroke();
注 :黑色虚线为自己画上去的,可以看到红线和绿线都凸出了一截
3.4、lineJoin : 相交线的拐点样式
miter(默认) bevel (切面) round (环绕)
3.4、setLineDash( [ ] ) : 设置虚线 ,参数是一个数组
数组中的内容是虚线中实现和空线的排列方式
如 例1:传5,实现和空线的长度都为5
如 例2:传 5,10 ,实线为5 ,空线为 10
如 例3:传 5,10,15 ,实空线排列方式为5 ,10 ,15顺序排列
3.5、getLineDash( ) : 获取虚线 ,获取的是虚线中不重复的排列方式
如上 例1 :获取到 [5]
如上 例2 :获取到 [5,10]
如上 例3 :获取到 [5,10,15,5,10,15]
3.6、lineDashOffset : 虚线偏移
如果设置的值为正数 , 虚线往起点的方向偏移
如果设置的值为负数 , 虚线往终点的方向偏移
4、填充
fill( ) : 填充一个闭合图形,默认颜色黑色
fillStyle : 设置颜色
5、非零环绕填充
画两个矩形套矩形的图,并ctx.fill( ),填充,如下:
注:箭头表示绘制轨迹的顺序
5.1、填充的规则 :如果想判断一个图形是否填充,要从图中拉一条线出去,与此线会有多个相交的轨迹,如轨迹方向为顺时针加1,逆时针减1,
计算结果不为0时填充
结果如下:图1,里外都填充 ,图2外面填充,里面不填充