H5-Canvas标签

809 阅读6分钟

前言

canvas是H5新增的标签元素。canvas意思为画布,我们可以通过js在上面绘制图形。应用场景,比如运动轨迹、人像的标注、个性化海报、炫酷特效等等。

基础&概念

创建一个画布(Canvas)

<canvas id="myCanvas" width="200" height="100"></canvas>

注意:画布默认大小是300*150,不能用css去修改大小,可以利用画布的标签属性widthheight修改;canvas是一个双标签。

兼容性与支持

Mozilla 程序从 Gecko 1.8 (Firefox 1.5) 开始支持 <canvas>, Internet Explorer 从 IE9 开始 <canvas> 。Chrome 和 Opera 9+ 也支持 <canvas>

<canvas>
    你的浏览器不支持 canvas,请升级你的浏览器。
</canvas>

检测支持性

var canvas = document.getElementById('tutorial');
if (canvas.getContext){
  var ctx = canvas.getContext('2d');
  //开始画图
} else {
  // 不支持canvas
}

注意: 支持 <canvas> 的浏览器只会渲染 <canvas> 标签,而忽略其中的文本内容。不支持 <canvas> 的浏览器则会直接显示文本内容;当然这个文本内容也可以换成一张图片。

渲染上下文

这里的getContext()方法可以理解为工具箱,我们可以使用里面的工具进行绘制图形。

var mycanvas = document.getElementById('mycanvas');
//获得 2d 上下文对象
var ctx = mycanvas.getContext('2d');

开始画直线

Q1:想一想,为什么有起点和终点?

//起点
ctx.moveTo(100, 100)
// 终点
ctx.lineTo(200, 100)
// Q2:对线进行描边这里的strock()是什么?
ctx.stroke();

绘制形状(Q1)

canvas元素绘制图像的时候有两种方法(F-Q2)

context.fill()//闭合图形填充
context.stroke()//线段描边

像素栅格

(F-Q1):canvas 元素默认被网格所覆盖。通常来说网格中的一个单元相当于 canvas 元素中的一像素。栅格的起点为左上角,坐标为 (0,0) 。所有元素的位置都相对于原点来定位。

绘制路径

上面说过,像素格组成我们的画布,所以路径就可以理解为,所有画布所有像素对的集合,只是我们规定了路径轨迹和像素点颜色,任意路径都是闭合的。

步骤:

  • 创建路径起始点
  • 调用绘制方法去绘制出路径
  • 把路径封闭
  • 一旦路径生成,通过描边或填充路径区域来渲染图形。

绘制线段

    /*绘制线条*/
    if (mycanvas.getContext) {
      // 每个canvas节点上都有一个对应的context对象,要获取这个对象,方法是getCotext
      let ctx=mycanvas.getContext("2d");
      // 开启本次绘制
      ctx.beginPath();
      // 设置路径起点坐标
      ctx.moveTo(50,50);
      // 绘制一条线至坐标50 150
      ctx.lineTo(150,50);
      // 线条着色,描边
      ctx.stroke();
      // 结束本次绘制(闭合路径)
      ctx.closePath();  
    } else {
      alert("浏览器不支持")
    }

绘制矩形

重点留意下 fillStyle fillRect() strokeEect()属性和方法的使用;

   /*绘制矩形*/
    if (mycanvas.getContext) {
      let ctx = mycanvas.getContext("2d");
      ctx.beginPath();
      // 设置填充颜色
      ctx.fillStyle = '#cfa';
      //ctx.fillRect填充 (x,y,width,height)起始坐标值和矩形宽高
      ctx.fillRect(500, 100, 200, 100);
      // clearRect方法用来清除某个矩形区域的内容, (x,y,width,height)起始坐标值和矩形宽高
      ctx.clearRect(525, 125, 50, 50)
      //ctx.strokeRect 描边,ctx.strokeStyle 描边的颜色
      ctx.strokeStyle = 'red'
      ctx.strokeRect(50, 50, 100, 100);
      ctx.closePath(); 
    } else {
      alert("浏览器不支持")
    }

结果如下所示:

微信截图_20211202190223.png

【注意】

绘制圆形(这里默认画出的是空心圆)

   if (mycanvas.getContext) {
      let ctx = mycanvas.getContext("2d");
      ctx.beginPath();
      // arc方法的x和y参数是圆心坐标,radius是半径,startAngle和endAngle则是扇形的起始角度和终止角度(以弧度表示),anticlockwise表示做图时应该逆时针画(true)还是顺时针画(false)。
      //ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
      ctx.arc(200, 400, 100, 0, Math.PI * 2, true);
      // ctx.fillStyle = "#cfa";
      ctx.stroke();//空心圆
      // ctx.fill();//实心圆
      ctx.closePath();
    } else {
      alert("浏览器不支持")
    }

注意: 弧度=(Math.PI/180)*角度,思考一下利用这个我们是不是也可以画扇形?

特殊效果

绘制线条渐变

前面我门可以用css的渐变来实现线条渐变,这里我们试试用这个实现渐变。

    if (mycanvas.getContext) {
      let ctx = mycanvas.getContext("2d");
      // createLinearGradient方法的参数是(x1, y1, x2, y2),
      // 其中x1和y1是起点坐标,x2和y2是终点坐标。
      // 通过不同的坐标值,可以生成从上至下、从左到右的渐变等等。
      var myGradient = ctx.createLinearGradient(10, 10, 610, 30);
      myGradient.addColorStop(0, "red");
      myGradient.addColorStop(0.5, "green");
      myGradient.addColorStop(1, "blue");
      ctx.fillStyle = myGradient;
      // 绘制矩形
      ctx.fillRect(10, 10, 600, 20);
    } else {
      alert("浏览器不支持")
    }

效果:

2.png

绘制阴影

    // /*绘制阴影*/
    if (mycanvas.getContext) {
      let ctx = mycanvas.getContext("2d");
      ctx.shadowOffsetX = 5; // 设置水平位移
      ctx.shadowOffsetY = 5; // 设置垂直位移
      ctx.shadowBlur = 5; // 设置模糊度
      ctx.shadowColor = "rgba(0,0,0,0.5)"; // 设置阴影颜色
      ctx.fillStyle = "#CC0000";
      ctx.fillRect(10, 600, 110, 20);
    } else {
      alert("浏览器不支持")
    }

效果:

3.png

绘制文本

canvas 有两种方法来渲染文本

fillText(text, x, y [, maxWidth])
//在指定的(x,y)位置填充指定的文本(text),绘制的最大宽度是可选的.
strokeText(text, x, y [, maxWidth])

//在指定的(x,y)位置绘制文本边框(text),绘制的最大宽度是可选的.

例子(想一想绘制文本有啥用?Q3)

var ctx;
function draw(){
    var canvas = document.getElementById('tutorial');
    if (!canvas.getContext) return;
    ctx = canvas.getContext("2d");
    ctx.font = "100px sans-serif"
    ctx.fillText("想一想绘制文本有啥用?", 10, 100);
    ctx.strokeText("想一想绘制文本有啥用?", 10, 200)
}
draw();

绘制图片

我们也可以在canvas上直接绘制图片;注意调整画布的宽高和图片相适应,效果会好点。

创建<img>元素

var image = new Image();
image.src = "images/tu.jpg"

绘制img

//参数1:要绘制的img  参数2、3:绘制的img在canvas中的坐标
ctx.drawImage(img,0,0); 

注意:考虑到图片是从网络加载,如果 drawImage 的时候图片还没有完全加载完成,则什么都不做,个别浏览器会抛异常。所以我们应该保证在 img 绘制完成之后再 drawImage

var img = new Image();   // 创建img元素
img.src = 'myImage.png'; // 设置图片源地址
img.onload = function(){
  ctx.drawImage(img, 0, 0)
}

绘制 img 标签元素中的图片

<img src="./tu.jpg" alt="" width="300"><br>
<canvas id="tutorial" width="600" height="400"></canvas>
<script type="text/javascript">
    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        var img = document.querySelector("img");
        ctx.drawImage(img, 0, 0);
    }
    document.querySelector("img").onclick = function (){
        draw();
    }
</script>

缩放图片

drawImage() 也可以再添加两个参数:drawImage(image, x, y, width, height)

这个方法多了2个参数:widthheight,这两个参数用来控制 当向canvas画入时应该缩放的大小。

ctx.drawImage(img, 0, 0, 400, 200)

绘制图片+绘制文本--案例:水印(F-Q3)

1. 在html中准备canvas

<canvas id="myCanvas" width="1000" height="500" >
	你的浏览器不支持 canvas,请升级你的浏览器。
</canvas>

2. 加载图片

var img = new Image();   
img.src = './img/demo.jpg'; 

3. 绘制图片

img.onload=function(){
    var canvas=document.getElementById("myCanvas");
    var ctx=canvas.getContext("2d");
    ctx.drawImage(img,0,0);
}

4. 绘制水印 在canvas上绘制好图片之后,回到onload函数中,利用我们在上一步中获取的ctx对象,继续绘制水印。

   ctx.font="20px microsoft yahei"; //定义水印的大小以及字体
   ctx.fillStyle = "rgba(255,255,255,0.5)";  //自定义水印的颜色以及透明度
   ctx.fillText("my images",100,100); //完成水印填充以及水印的位置定位

源码

<canvas id="myCanvas" width="1000" height="500" >
	Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
    //准备img对象 
    var img = new Image();   
    img.src = './img/demo.jpg';
    // 加载完成开始绘制
    img.onload=function(){
       //准备canvas环境 
       var canvas=document.getElementById("myCanvas");
       var ctx=canvas.getContext("2d");
       // 绘制图片
       ctx.drawImage(img,0,0);
       // 绘制水印
       ctx.font="20px microsoft yahei";
       ctx.fillStyle = "rgba(255,255,255,0.5)";
       ctx.fillText("洋葱水印",100,100);
    }
</script>

效果:

4.png