Canvas是H5的一部分,但是无法做到绝对兼容,没有兼容插件
上下文getContext()有2d无3d,但可用WebGL实现3D视觉效果
绘制步骤
- 准备画布:画布默认为白色300*150px,要想设置画布大小不能在
style
标签中,而应该在canvas
标签中直接设置width
和height
- 准备绘图工具
- 利用工具绘图
<canvas width="600" height="400" ></canvas>
<script>
// 获取元素
const myCanvas = document.querySelector('canvas');
// 获取上下文 -> 绘制工具箱
const ctx = myCanvas.getContext('2d');
// 移动画笔
ctx.moveTo(100,100);
// 绘制直线 (轨迹,绘制路径 -> 不描边看不见)
ctx.lineTo(200,100);
// 描边
ctx.stroke();
</script>
常用属性方法
属性
ctx.canvas.width/height
或myCanvas.width/height
:获取画布宽高ctx.lineWidth
:线宽,默认1px
ctx.lineCap
:线末端类型,butt
(默认),square
(矩形),round
(圆弧)ctx.lineJoin
:相交线的拐点(两直线交点) ,miter
(默认),bevel
(平的),round
(圆弧)ctx.strokeStyle
:线条颜色。ctx.fillStyle
:填充颜色。ctx.lineDashOffset
:设置虚线偏移量,负值 -> 前(水平右)偏移,正值 -> 后(水平左)偏移
方法
ctx.closePath()
:关闭路径,自动闭合(可以解决手动闭合造成的缺角)- 注意
closePath()
和beginPath()
无关
- 注意
ctx.fill()
:自动填充,默认为黑色填充ctx.stroke()
:绘制线条ctx.beginPath()
:开启新的路径ctx.setLineDash(arr)
:设置虚线。参数arr
排列方式,arr
内可传1~3个值,如[5]
、[5,10]
、[5,10,15]
ctx.getLineDash()
:获取虚线宽度集合,获取的是不重复的那一段的排列方式。ctx.moveTo(x,y)
:画笔移动到某坐标处。ctx.lineTo(x,y)
:画笔绘制到某坐标处。
绘制线条
简单直线
const myCanvas = document.querySelector('canvas');
const ctx = myCanvas.getContext('2d');
ctx.moveTo(100, 100.5); // 移动画笔
ctx.lineTo(300, 100.5); // 画线
ctx.stroke(); // 描边
-
默认宽度=
1px
, 默认颜色color='black'
; -
线条模糊原因:对齐的点是线的中心位置,所以会把线分成两个
0.5px
, 但会不饱和增加宽度,所以变为2px
灰色。 -
线条模糊解决方案:绘制线条时前后移动
0.5px
绘制颜色宽度不同的直线
- 想要绘制不同样式的直线,必须开启不同的路径
ctx.beginPath(); // 开启新的路径
ctx.moveTo(100,100);
ctx.lineTo(300,100);
ctx.strokeStyle = 'blue'; // 设置线条颜色
ctx.lineWidth = 10; // 设置线条宽度
ctx.stroke();
ctx.beginPath(); // 开启新的路径
ctx.moveTo(100,200);
ctx.lineTo(300,200);
ctx.strokeStyle = 'red'; // 红色 20px
ctx.lineWidth = 20;
ctx.stroke();
填充三角形
ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.lineTo(200,200);
ctx.closePath(); // 自动闭合
ctx.lineWidth = 10;
ctx.stroke();
ctx.fillStyle = 'red'; // 设置填充颜色
ctx.fill(); // 填充
镂空正方形
-
非零环绕(非零填充) :
渐变矩形
ctx.lineWidth = 30;
for (var i = 0; i < 255; i++) {
// 每次循环完之后都要重置!
ctx.beginPath();
// x的值必须要比lineTo()的x值小
ctx.moveTo(100+i-1, 100);
ctx.lineTo(100+i, 100);
ctx.strokeStyle = `rgb(${i},0,0)`; // 黑 -> 红
// 别忘记描边
ctx.stroke();
}
绘制矩形
绘制矩形
-
不是独立路径,不用每一次绘制都重新开始
ctx.rect(100, 100, 200, 100); ctx.fillStyle = 'green'; ctx.stroke(); ctx.fill();
-
有自己的独立路径
// 起点x,起点y,w,h ctx.strokeRect(100,100,200,100); ctx.fillRect(100, 100, 200, 100);
-
清除矩形内容:
// 起点x,起点y,w,h ctx.clearRect(0,0,100,100);
渐变
-
fillStyle
属性可以赋予字符串("pink"
)、16进制('#000'
)、rgb()
、rgba()
,还可以传入一个渐变方案,即
ctx.fillStyle = linearGradient
// 1.创建渐变对象, 起点x,起点y,终点x,终点y const linearGradient = ctx.createLinearGradient(100,100,500,400); // 2.渐变对象添加色彩值 linearGradient.addColorStop(0,'pink'); linearGradient.addColorStop(0.5,'red'); linearGradient.addColorStop(1,'blue'); // 3.将渐变方案传入fillStyle ctx.fillStyle = linearGradient;
绘制圆弧
-
绘制:
// 圆心x,圆心y,半径r,起始弧度,结束弧度,逆(true)/顺(false)时针 ctx.arc(x,y,r,start,end,false);
-
渲染:
// 注意: 0弧度是在正右方的位置 ctx.stroke();
绘制文字
属性
ctx.textAlign
:文本相对起点的对齐方式,center,left,right,start(起始),end(结束)
ctx.textBaseline
:相对起点的基线,top,bottom,middle
ctx.measureText(str).width
:文本的宽度。
方法
ctx.strokeText(str,x,y)
:以(x,y)
为左下角起点,内容为str的镂空文本ctx.fillText(str,x,y)
:以(x,y)
为左下角起点,内容为str的填充实心文本
绘制图片
// 1.创建对象
const img = new Image();
// 2.绑定加载完成事件
img.onload = function(){
// 3参: 在(x,y)坐标处绘制img
ctx.drawImage(img, x, y);
// 5参: 在(x,y)处缩放为W*H大小后绘制img
ctx.drawImage(img, x, y, W, H);
// 9参: 从img原图(X,Y)处截取w*h大小图像后在画布(x,y)处缩放为(W,H)后绘制img
ctx.drawImage(img, X, Y, w, h, x, y, W, H);
};
// 3.引入图片路径
img.src = 'xxx.jpg';
绘制扇形
// 注意: 一定要把画笔移动到圆心位置
ctx.moveTo(w/2,h/2); // 在画圆之前把起点放到圆心位置
ctx.arc(w/2,h/2,150,0,-Math.PI/2,true);
ctx.fill(); // 无需闭合回路即可填充