一、canvas是什么?
canvas就是画布
canvas元素用于在网页上绘制2D图形和图像
二、canvas坐标体系
canvas的默认宽高是300*150,要在脚本中对画布进行操作。
踩坑注意:如果要对canvas画布的大小进行操作,不能在style上操作,要在内联样式上写或者js中操作,在style上改变宽高画布会被拉伸
三、canvas画直线、曲线和圆
(1)canvas画直线
<canvas id="myCanvas1">
您的浏览器不支持Canvas,请升级浏览器
</canvas>
<script>
var canvas1 = document.getElementById('myCanvas1');
var ctx1 = canvas1.getContext('2d'); //
ctx1.canvas.width = 100; //js获取宽高
ctx1.canvas.height = 100;
ctx1.moveTo(0, 0); //起点
ctx1.lineTo(100, 100); //直线到100,100
ctx1.stroke(); //没有这个stroke()的话不会出现画布效果
</script>
(2)canvas画圆和矩形
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.canvas.width = 600;
ctx.canvas.height = 400;
ctx.beginPath(); //重新开始新路径
ctx.moveTo(0, 0);
ctx.lineTo(100, 100);
ctx.lineTo(100, 200);
ctx.closePath(); //闭合路径(可以连接首尾)
ctx.stroke(); //记得最后调用stroke才能画线
// 画圆
ctx.beginPath();
//ctx.arc(开始原点x,开始原点y,半径,起始弧度,终止弧度,true表示逆时针动画)
ctx.arc(200, 150, 100, 0, Math.PI * 2, true);
ctx.closePath();
ctx.stroke();
//画矩形,封装一个stroke的rect(矩形,所以不用调用rect)
//ctx.strokeRect(开始原点x,开始原点y,宽度,高度)
ctx.strokeRect(100, 100, 100, 100);
(3)canvas描边和填充
//线条样式
ctx.beginPath();
ctx.strokeStyle = "#00FF00"; //设置线条的样式颜色
ctx.lineWidth = 5; //设置描边的线宽
ctx.moveTo(100, 200);
ctx.lineTo(200, 200);
ctx.stroke();
//填充
ctx.beginPath();
ctx.moveTo(300, 100);
ctx.lineTo(400, 100);
ctx.lineTo(400, 200);
ctx.closePath();
//ctx.stroke();
ctx.fillStyle = "#0000FF"; //设置填充的颜色
ctx.fill(); //填充 (如果是首尾没有连接的话会自动连接填充里面)
ctx.beginPath();
ctx.moveTo(300, 150);
ctx.lineTo(400, 150);
ctx.lineTo(400, 250);
ctx.closePath();
ctx.stroke();
四、canvas图形变换
(1)、save()和restore()方法
save(),保存当前绘画环境,包括样式和变换
restroe(),恢复当前绘画环境,包括样式和变换
注意:ctx.save()和restore()方法,保存了上下文的环境包括图形变换和样式。并且一定要同时出现。restore之后的canvas样式会以save之前的样式重新开始
ctx.beginPath();
//ctx.save()和restore()方法,保存了上下文的环境包括图形变换和样式。并且一定要同时出现
ctx.save();
//x轴的平移方向,translate平移变换
ctx.translate(0, 20);
ctx.moveTo(50, 50);
ctx.lineTo(150, 50);
ctx.restore(); //restore之后的canvas样式会以save之前的样式重新开始
ctx.stroke();
//ctx.fillRect(-5, -5, 10, 10);
ctx.beginPath();
(2)偏移、旋转、缩放变换
ctx.beginPath();
//x轴的平移方向,translate平移变换
ctx.translate(300, 0);
for(var i=0; i<10; i++) {
//rotate旋转变换,Math.PI=180
ctx.rotate(Math.PI / 5);
ctx.moveTo(-50, 0);
ctx.lineTo(50, 0);
}
ctx.stroke();
//scale缩放变换,(x轴缩放,y轴缩放)
ctx.sacle(1,0.5)
五、canvas中的渐变
(1)线性渐变 ctx.createLinearGradient(x轴起点,y轴起点,x轴终点,y轴终点)
(2)径向渐变 ctx.createRadialGradient(x,y起点,原点起点,x,y终点,原点终点)
(3)渐变中的颜色转换ctx.createLinearGradient(createRadialGradient).addColorStop(0-1百分比,rgba)
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.canvas.width = 600;
ctx.canvas.height = 400;
//线性渐变 ctx.createLinearGradient(x轴起点,y轴起点,x轴终点,y轴终点);
var linearGradient = ctx.createLinearGradient(50, 50, 150, 150);
//linearGradient.addColorStop(0-1百分比,rgba)
linearGradient.addColorStop(0, 'rgb(255,0,0)');
linearGradient.addColorStop(0.5, 'rgb(0,255,0)');
linearGradient.addColorStop(1, 'rgb(0,0,255)');
ctx.fillStyle = linearGradient;
ctx.fillRect(0, 0, 200, 200);
ctx.beginPath();
ctx.arc(400, 150, 100, 0, Math.PI * 2, true);
ctx.closePath();
//径向渐变 ctx.createRadialGradient(x,y起点,原点起点,x,y终点,原点终点)
var radialGradient = ctx.createRadialGradient(400, 150, 0, 400, 150, 100);
radialGradient.addColorStop(0, 'rgb(255,0,0)');
radialGradient.addColorStop(1, 'rgb(0,0,255)');
ctx.fillStyle = radialGradient;
ctx.fill();
六、canvas中文字和图片的绘制
1、canvas中的文字
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.canvas.width = 600;
ctx.canvas.height = 400;
var str = "hello world"
//设置文本样式、比如大小,字体
ctx.font = "bold 100px sans-serif";
//水平对齐设置,left,center,top
ctx.textAlign = "center";
//垂直对齐设置,top,middle,bottom
ctx.textBaseline = "top";
ctx.fillStyle = "#FF0000";
//填充文本
ctx.fillText(str, 300, 100);
ctx.strokeStyle = "#0000FF";
//描边文本
ctx.strokeText(str, 300, 300);
//获取文本宽度
console.log(ctx.measureText("慕课网").width);
2、canvas图片的绘制(图片的裁剪:要看图片的实际宽高)
注意:一定要在图像加载完成后的回调中会绘制图像,否则图像显示不出来
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.canvas.width = 600;
ctx.canvas.height = 400;
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
var img = new Image();
img.src = "logo.png";
//一定要在图像加载完成后的回调中会绘制图像,否则图像显示不出来
img.onload = function () {
//如果是三个参数,表示以(0,0)在图像左上角开始绘制图像
//如果是五个参数,表示在(0,0)点处绘制img图像,缩放(截取)成40*40
//如果是九个参数,表示获取img图像(0,0)点处的40*40区域,绘制在(100,100)点处,缩放成80*80
ctx.drawImage(img, 0, 0, 40, 40, 100, 100, 80, 80);
3、图形画刷
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, canvas.width, canvas.height);
var img = new Image();
img.src = "logo.png";
img.onload = function () {
//创建图形画刷,repeat,no-repeat,repeat-x,repeat-y
var pattern = ctx.createPattern(img, "repeat");
ctx.fillStyle = pattern;
ctx.fillRect(0, 0,canvas.width,canvas.height);
七、canvas中剪辑、阴影以及曲线的绘制
1、canvas中剪辑区域
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
//保存当前环境
ctx.save();
ctx.beginPath();
ctx.arc(200, 150, 100, 0, Math.PI * 2, true);
ctx.closePath();
//进行区域剪辑
ctx.clip();
//恢复环境,释放了剪辑区域的作用
ctx.restore();
ctx.fillStyle = "#FF0000";
ctx.fillRect(100, 100, 200, 200);
ctx.fillStyle = "#0000FF";
ctx.fillRect(200, 150, 200, 200);
2、canvas阴影绘制
//阴影的x轴偏移量
ctx.shadowOffsetX = 10;
//阴影的y轴偏移量
ctx.shadowOffsetY = 10;
//阴影的颜色
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
//阴影的模糊程度
ctx.shadowBlur = 1.5;
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
ctx.fillRect(100, 100, 100, 100);
3、canvas绘制曲线
ctx.beginPath();
ctx.arc(150, 150, 100, 0, Math.PI, true);
ctx.stroke();
// 二次样条曲线
ctx.beginPath();
ctx.moveTo(50, 350); //起始点
ctx.quadraticCurveTo(100, 250, 150, 350); // 前两个参数是可以调节的点,最后两个参数是终点
ctx.stroke();
showPoint(ctx, 50, 350);
showPoint(ctx, 100, 250);
showPoint(ctx, 150, 350);
// 三次贝塞尔曲线
ctx.beginPath();
ctx.moveTo(200, 350);
ctx.bezierCurveTo(200, 250, 300, 250, 300, 350); // 前四个参数是可以调节的点,最后两个参数是终点
ctx.stroke();
ctx.fill();
showPoint(ctx, 200, 350);
showPoint(ctx, 200, 250);
showPoint(ctx, 300, 250);
showPoint(ctx, 300, 350);
八、canvas动画(实现一个方块左右移动,鼠标放上去就停止的效果)
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.canvas.width = 600;
ctx.canvas.height = 400;
var posx = 0, posy = 0;
var dir = 1; //判断方块是正向前进还是反向运动。正向就是1,反向就是-1
var isMouseInReat //判断鼠标是否移动进了方块里面,是的话就停止运动
canvas.onmousemove =function(e){
var mouseX = e.offsetX;
var mouseY = e.offsetY;
if (mouseX>posx && mouseX<posx +50 && mouseY>posy && mouseY<posy +50){
isMouseInReat = true;
}else{
isMouseInReat = false;
}
}
setInterval(function() {
if(!isMouseInReat){
posx = posx + 10 * dir;
}
//clearRect清空画布的一个矩形区域
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillRect(posx, posy, 50, 50);
if (posx +50 >=ctx.canvas.width) {
dir = -1;
}else if(posx <= 0){
dir = 1
}
}, 50);
九、canvas离屏技术(可以解决因为setInterval多次循环卡顿的问题)
// 要显示的canvas
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.canvas.width = 600;
ctx.canvas.height = 400;
// 不显示的canvas(离屏)用dispaly:none隐藏即可
var offCanvas = document.getElementById('offCanvas');
var offCtx = offCanvas.getContext('2d');
offCtx.canvas.width = 600;
offCtx.canvas.height = 400;
ctx.fillStyle = "#FF0000";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
offCtx.strokeStyle = "#00FF00";
offCtx.lineWidth = 10;
offCtx.moveTo(0, 0);
offCtx.lineTo(offCtx.canvas.width, offCtx.canvas.height);
offCtx.stroke();
// 把离屏canvas的内容搬过来
ctx.drawImage(offCanvas, 0, 0, ctx.canvas.width, ctx.canvas.height,
0, 0, offCtx.canvas.width, offCtx.canvas.height);