canvas学习笔记(1)--基本用法

概念

Canvas是什么?

<canvas>是一个可以使用脚本来绘制图形的HTML元素。

canvas是HTML5新增的标签,表示“油画布”。是HTML5中最最浓墨重彩的一笔,能够颠覆Flash。

例如,它可以用于绘制图表、制作图片构图或者制作简单的动画.

开始前的准备

HTML+Javascript知识

一些过时的浏览器不支持<canvas> 元素,但是所有的新版本主流浏览器都支持它。

Canvas基本用法。

如何去设置一个 canvas 2D 上下文以及如何在浏览器上创建第一个例子。

1.添加<canvas> 元素

<canvas id="tutorial" width="150" height="150"></canvas>

2.渲染上下文

<canvas>元素创造了一个固定大小的画布,它公开了一个或多个渲染上下文,其可以用来绘制和处理要展示的内容。一般将主要用于2D渲染上下文中。其他种类的上下文提供了不同种类的渲染方式;比如,WebGL便可以进行3D渲染上下文。

//得到画布
var canvas = document.getElementById('tutorial');
//得到上下文
var ctx = canvas.getContext('2d');

之后的所有绘制,都是调用ctx的方法,而不是canvas的方法。

例如:

ctx.fillRect();
ctx.fillArc();

简单例子

<html>
 <head>
  <script type="application/javascript">
    function draw() {
      var canvas = document.getElementById("canvas");
      if (canvas.getContext) {
        var ctx = canvas.getContext("2d");

        ctx.fillStyle = "rgb(200,0,0)";
        ctx.fillRect (10, 10, 55, 50);

        ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
        ctx.fillRect (30, 30, 55, 50);
      }
    }
  </script>
 </head>
 <body onload="draw();">
   <canvas id="canvas" width="150" height="150"></canvas>
 </body>
</html>

运行效果

在这里插入图片描述

绘制形状

坐标系:在这里插入图片描述

canvas中有两个重要的部分:

1、stroke(笔触、描边)

2、fill(填充)

什么意思呢?

绘制矩形

fillRect(x,y,width,height)

绘制一个填充的矩形

strokeRect(x,y,width,height)

绘制一个矩形的边框

clearRect(x, y, width, height)

清除指定矩形区域,让清除部分完全透明(当宽高等于画布的宽高时,也可用于清除画布内容)

		//得到画布
		var canvas=document.getElementById("mycanvas");
		//得到2d上下文
		var ctx=canvas.getContext('2d');
		//更改笔触颜色
		ctx.strokeStyle='red';
		//设置笔触粗细
		ctx.lineWidth="4px";
		//开始绘制
		ctx.strokeRect(30,30,50,100);

在这里插入图片描述

填充矩形:

		//得到画布
		var canvas=document.getElementById("mycanvas");
		//得到2d上下文
		var ctx=canvas.getContext('2d');
		
		//填充颜色
		ctx.fillStyle="blue";
		//绘制填充矩形
		ctx.fillRect(30,30,50,50);

在这里插入图片描述

清除矩形:

		//得到画布
		var canvas=document.getElementById("mycanvas");
		//得到2d上下文
		var ctx=canvas.getContext('2d');
		
		/*先绘制填充矩形*/
		//填充颜色
		ctx.fillStyle="blue";
		//绘制填充矩形
		ctx.fillRect(30,30,100,100);
		
		/*清除矩形*/
		ctx.clearRect(30,30,25,25);

在这里插入图片描述

直接在画布上绘制矩形的上面三个额外方法,同样,也有rect()方法,将一个矩形路径增加到当前路径上。

react(x,y,width,height)

当该方法执行的时候,moveTo()方法自动设置坐标参数(0,0)。也就是说,当前笔触自动重置回默认坐标。

这个方法绘制出的是路径,需要stroke()描边,或者fill()进行填充

绘制路径

路径就是线,路径没有fill,只有stroke。路径没有填充色,只有描边。

需要注意的是:

一个路径,甚至一个子路径,都是闭合的。使用路径绘制图形需要一些额外的步骤。

  1. 首先,需要创建路径起始点。
  2. 然后使用“画图命令”去画出路径。
  3. 之后把路径封闭。
  4. 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。

绘制路径常用的函数:

beginPath()

新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。

closePath()

闭合路径之后图形绘制命令又重新指向到上下文中。

strole()

通过线条来绘制图形轮廓。

fill()

通过填充路径的内容区域生成实心的图形。

案例
		//得到画布
		var canvas=document.getElementById("mycanvas");
		//得到上下文
		var ctx=canvas.getContext("2d");
		//开始绘制路径
		ctx.beginPath();
		//绘制点移动到100,100的位置
		ctx.moveTo(100,100);
		//绘制一条线,从绘制点的位置到100,200
		ctx.lineTo(100,200);
		//绘制一条线,从100,200到150,150
		ctx.lineTo(150,150);
		//闭合路径,此时会自动绘制一条线,连接起点和终点
		ctx.closePath();
		//设置stroke的颜色
		ctx.strokeStyle="black";
		ctx.lineWidth="4";
		ctx.stroke();
		//填充色
		ctx.fillStyle="red";
		ctx.fill();

运行效果:

在这里插入图片描述

画线是虚的(不可见的),只有stroke()、fill()了,才能看见。

圆弧

绘制圆弧或者圆使用arc()方法。

arc(x,y,radius,startAngle,endAngle,anticlockwise)

x,y : 圆心坐标

startAngle : 开始弧度

endAngle : 结束弧度

anticlewise :是否逆时针(true为逆时针,false为顺时针)

ctx.arc(200,200,100,0,90*Math.PI/180,false);

90角度的圆弧在这里插入图片描述

ctx.arc(200,200,100,0,360*Math.PI/180,false);

完整的圆弧在这里插入图片描述

现在,我们利用这个方法来绘制一个卡通笑脸

		//得到画布
		var canvas=document.getElementById("mycanvas");
		//得到上下文
		var ctx=canvas.getContext("2d");
		/*绘制笑脸*/
		var wholeAngle=Math.PI*2;
		ctx.beginPath();
		//绘制脸
		ctx.arc(100,100,80,0,wholeAngle,false);
		//移动画笔
		ctx.moveTo(70,80);
		//绘制左眼
		ctx.arc(60,80,10,0,wholeAngle,false);
		//移动画笔
		ctx.moveTo(150,80);
		//绘制右眼
		ctx.arc(140,80,10,0,wholeAngle,false);
		//移动画笔
		ctx.moveTo(50,120);
		//绘制嘴巴
		ctx.arc(100,120,50,0,0.5*wholeAngle,false);
		ctx.stroke();
运行效果
在这里插入图片描述
贝塞尔曲线

用来绘制复杂又规律的图形

quadraticCurveTo(cp1x,cp1y,x,y)

绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点(蓝色),x,y为结束点(红色)

在这里插入图片描述

其中有一个蓝色点可以是绘制的起点,也可以是上一个二次贝塞尔曲线的结束点。

做个实例来看一下:

		//得到画布
		var canvas=document.getElementById("mycanvas");
		//获取上下文
		var ctx=canvas.getContext("2d");
		
		var cpx1=350;
		var cpy1=250;
		var x=400;
		var y=500;
		//绘制一个三角形的辅助线
		ctx.font="14px 微软雅黑";
		ctx.beginPath();
		ctx.moveTo(300,300);
		//标注坐标
		ctx.fillText("(起点x:300,起点y:300)",180,280);
		//移动笔,绘制直线
		ctx.lineTo(cpx1,cpy1);
		//标注坐标
		ctx.fillText("(cpx1:"+cpx1+",cpy1:"+cpy1+")",cpx1,cpy1);
		//移动笔,绘制直线
		ctx.lineTo(x,y);
		//标注坐标
		ctx.fillText("(x:"+x+",y:"+y+")",x,y);
		//闭合路径
		ctx.closePath();
		ctx.stroke();
		
		//使用贝塞尔二次曲线函数
		ctx.beginPath();
		ctx.strokeStyle="coral";
		ctx.moveTo(300,300);
		ctx.quadraticCurveTo(cpx1,cpy1,x,y);
		ctx.stroke();

运行效果:

在这里插入图片描述

当改变cpx1和cpy1的值,就可以看出它的规律啦。

在这里插入图片描述

关于三次贝塞尔曲线参看下面的博客讲解

https://www.cnblogs.com/joyho/articles/5817170.html

通过利用可是化工具可以大致画出图形

		//得到画布
		var canvas=document.getElementById("mycanvas");
		//获取上下文
		var ctx=canvas.getContext("2d");
		ctx.beginPath();
		ctx.moveTo(50,250);
		ctx.lineTo(50,50);
		ctx.lineTo(250,50);
		ctx.lineTo(250,250);
		ctx.closePath();
		ctx.stroke();
		
		ctx.strokeStyle="coral";
		ctx.beginPath();
		ctx.moveTo(50,250);
		ctx.bezierCurveTo(50+100,250-80,50,50,250,50);
		ctx.stroke();

在这里插入图片描述

文本(基本用法)
ctx.font="16px 微软雅黑";
ctx.fillText=("文本内容"100,100)//100,100为坐标位置
运动

在canvas上,要想让元素运动起来,需要使用定时器setinterval()

然而canvas有个特性,就是上屏的元素,将会立刻被像素化,将得不到这个“对象”的引用,因此不能像操作dom那样操作上屏的元素。也就是说,想要通过改变元素属性使其运动是行不通的。

那要想实现canvas中上屏元素的运动,应该怎么做呢?

其实原理就是:清除→重绘→清除→重绘→……使它看起来像是在运动

<script type="text/javascript">
		//使用DOM方法得到画布
		var mycanvas = document.querySelector("canvas");
		//使用画布的上下文
		var ctx = mycanvas.getContext("2d");
 		
 		var x = 100;
 		setInterval(function(){
 			x++;
 			//清屏
 			ctx.clearRect(0,0,600,400);
 			//重新绘制一个新圆形
 			ctx.beginPath();
	 		ctx.arc(x,100,50,0,Math.PI * 2, true);
	 		ctx.closePath();
	 		ctx.fillStyle = "orange";
	 		ctx.fill();
 		},20);
</script>

绘制图片

canvas中不可能所有形状都自己画,美工会有素材给我们使用。而且有些复杂的,像图片这样的图像是很难一点一点画出来的。所以canvas是可以绘制图片的。

一个重要的图片绘制函数

drawImage

它有三种形态

需要注意的是:在使用canvas绘制图片时,一定要在图片加载完成后进行。否则不会有任何效果,甚至有些浏览器还会报错。

var img = new Image();   // 创建img元素
img.onload = function(){
  // 执行drawImage语句
}
img.src = 'myImage.png'; // 设置图片源地址
最基础的一种

drawImage(img,x,y)

img就是图片对象,x,y是图片在目标canvas中的起点坐标

<body>
		<canvas id="mycanvas" width="800" height="800"></canvas>
	</body>
	
	<script type="text/javascript">
		//获取画布
		var canvas=document.getElementById("mycanvas");
		//获取上下文
		var ctx=canvas.getContext("2d");
		
		var xiaolu=new Image();
		xiaolu.src="../img/lu.jfif";
		xiaolu.onload=function(){
			ctx.drawImage(xiaolu,0,0);
		}
	</script>

运行效果:

在这里插入图片描述

这样图片便可以按照原本的样子被绘制到canvas画布上了。

但在有些时候,我们不想要图片按照原本的大小绘制怎么办呢?

drawImage()的第二种用法

缩放Scaling

drawImage(img,x,y,width,height)

这个方法增加了2个参数:widthheight,这两个参数决定了图片是放大还是缩小

<body>
		<canvas id="mycanvas" width="800" height="800"></canvas>
	</body>
	
	<script type="text/javascript">
		//获取画布
		var canvas=document.getElementById("mycanvas");
		//获取上下文
		var ctx=canvas.getContext("2d");
		
		var xiaolu=new Image();
		xiaolu.src="../img/lu.jfif";
		xiaolu.onload=function(){
			ctx.drawImage(xiaolu,0,0,400,200);
		}
	</script>

这样图片就能被固定到w:400,h:200的大小了

在这里插入图片描述

切片

drawImage()的第三个形态,就是切片。

当我们只想要图片的某一部分,并且绘制到canvas上应该怎么做呢?

drawImage(img , sx , sy , sWidth , sHeight , dx , dy , dWidth , dHeight);

看起开比较复杂实际上很容易理解,这里是火狐MDN的一张解释图片。

在这里插入图片描述

当我们只想要下图中的小鹿子的时候,我们可以借助图片工具,获取到小鹿在原图中的大小和位置

在这里插入图片描述

然后通过代码来进行切片

//获取画布
		var canvas=document.getElementById("mycanvas");
		//获取上下文
		var ctx=canvas.getContext("2d");
		
		var xiaolu=new Image();
		xiaolu.src="../img/lu.jpg";
		xiaolu.onload=function(){
			ctx.drawImage(xiaolu,472,314,161,296,0,0,167,296);
		}

运行效果:

在这里插入图片描述

Path2D()

所有的路径方法比如moveTo, rect, arcquadraticCurveTo等,都可以在Path2D中使用。

Path2D API 添加了 addPath作为将path结合起来的方法。当想要从几个元素中来创建对象时,这将会很实用。

事例
function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');

    var rectangle = new Path2D();
    rectangle.rect(10, 10, 50, 50);

    var circle = new Path2D();
    circle.moveTo(125, 35);
    circle.arc(100, 35, 25, 0, 2 * Math.PI);

    ctx.stroke(rectangle);
    ctx.fill(circle);
  }
}

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值