HTML5 Canvas绘图基础

一、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);
原文地址:https://www.cnblogs.com/gengzhen/p/11915071.html