HTML5 canvas 学习笔记

       Canvas API 提供了一个通过JavaScript 和 HTML<canvas>元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。

1、基础结构

        canvas元素本身没有任何外观,它就是一块空白画板,提供给JS的一套API,最早由Safari引入,IE9之前可以使用一些类库在IE中模拟canvas,大部分的API都不在canvas元素自身定义,canvas元素自身属性与常规的HTML元素并没有多大区别, 它的绘图API都定义在一个CanvasRenderingContext2D对象上(这里简单翻译成上下文对象),该对象可以通过getContext()方法获得,代码示例:

<html>
<head>
<title>demo</title>
</head>
<body>
<canvas id = 'canvasId' width= 200 heigth=200></canvas>
</body>
<script>
var canvas = document.getElementById('canvasId')
var ctx = canvas.getContext('2d')//2d表示画板维度,输入3d将得到一个更为复杂的3d图形API,也称WebGL
</script>

2、基本用法

绘制矩形

  •  fillRect(x, y, width, heigh)    =>  绘制一个填充的矩形
  •  strokeRect(x, y, width, heigh)    =>  绘制一个矩形的边框
  •  clearRect(x, y, width, heigh)    =>  清除指定矩形区域,让清除部分完全透明

 代码使用示例:

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>demo</title> 
</head>
<body>
<canvas id="myCanvas" width="200" height="200" style="border:1px solid #c3c3c3;">
</canvas>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillRect(25, 25, 150, 150);
ctx.clearRect(45, 45, 30, 30);
ctx.strokeRect(50, 50, 20, 20);
	
// ctx.clearRect(125, 45, 30, 30);
// ctx.strokeRect(130, 50, 20, 20);
</script>
</body>
</html>

运行结果如图:

 绘制形状(重点)

  •   beginPath()  =>  新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
  •   closePath()  =>  闭合路径之后图形绘制命令又重新指向到上下文中。
  •   stroke()  =>  通过线条来绘制图形轮廓。
  •   fill()  =>  通过填充路径的内容区域生成实心的图形。
  •  moveTo(x,y  =>  定义线条开始坐标。
  •  arc(x, y, r, start, stop)   =>  绘制一个以 r 为半径的圆形。
  •  lineTo(x, y)  =>  绘制一条从当前位置到指定x以及y位置的直线。

使用示例如下(笑脸):

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>demo</title> 
</head>
<body>
<canvas id="myCanvas" width="200" height="200" style="border:1px solid #c3c3c3;">
</canvas>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
   ctx.beginPath();
   ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // 绘制
   ctx.moveTo(110, 75);
   ctx.arc(75, 75, 35, 0, Math.PI, false);   // 口(顺时针)
   ctx.moveTo(65, 65);
   ctx.arc(60, 65, 5, 0, Math.PI * 2, true);  // 左眼
   ctx.moveTo(95, 65);
   ctx.arc(90, 65, 5, 0, Math.PI * 2, true);  // 右眼
   ctx.stroke();
</script>
</body>
</html>

运行结果如下: 

 注意:

1、线条(lineTo)绘制的用法也是差不多,只需要在适当的位置(x, y), lineTo(x, y)  就可以得到你想要的线性图形(比如三角形等),这里就不另外示例;

2、闭合路径closePath(),不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做;

3、当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合

3、基本动画

首先,可以用​ window.setInterval(), window.setTimeout() window.requestAnimationFrame() 来设定定期执行一个指定函数。

setInterval(function, delay) (en-US)   =>  当设定好间隔时间后,function会定期执行。

setTimeout(function, delay) (en-US)  =>  在设定好的时间之后执行函数。

requestAnimationFrame(callback)  =>

告诉浏览器你希望执行一个动画,并在重绘之前,请求浏览器执行一个特定的函数来更新动画。

下面是示例代码:

var sun = new Image();
var moon = new Image();
var earth = new Image();
function init(){
  sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
  moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
  earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
  window.requestAnimationFrame(draw);
}

function draw() {
  var ctx = document.getElementById('myCanvas').getContext('2d');

  // 设置或返回如何将一个源(新的)图像绘制到目标(已有)的图像上。
  ctx.globalCompositeOperation = 'destination-over'; 
  ctx.clearRect(0,0,300,300); // clear canvas

  ctx.fillStyle = 'rgba(0,0,0,0.4)';
  ctx.strokeStyle = 'rgba(0,153,255,0.4)'; // 设置或返回用于笔触的颜色、渐变或模式。
  ctx.save();    // 如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。
  ctx.translate(150,150); // 垂直和水平方向的偏移

  // 地球
  var time = new Date();
  ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
  ctx.translate(105,0);
  ctx.fillRect(0,-12,50,24); // 阴影
  ctx.drawImage(earth,-12,-12);

  // 月球
  ctx.save();
  ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
  ctx.translate(0,28.5);
  ctx.drawImage(moon,-3.5,-3.5);
  ctx.restore(); // 用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。

  ctx.restore();

  ctx.beginPath();
  ctx.arc(150,150,105,0,Math.PI*2,false); // 地球轨道
  ctx.stroke();

  ctx.drawImage(sun,0,0,300,300); // 太阳

  window.requestAnimationFrame(draw);
}

init();

以下为运行结果: 

 

上面的例子,采用 
window.requestAnimationFrame()实现动画效果。这个方法提供了更加平缓并更加有效率的方式来执行动画,当系统准备好了重绘条件的时候,才调用绘制动画帧。一般每秒钟回调函数执行60次,也有可能会被降低。

4、高级动画

高级动画其实就是在基础动画的基础上添加一些符合物理的运动,比如速率、拖尾、鼠标控制等等,进而让动画变得更高级。

下面是示例代码:

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var raf;

var ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 2,
  radius: 25,
  color: 'blue',
  draw: function() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  }
};

function draw() {
  ctx.clearRect(0,0, canvas.width, canvas.height);
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;
  raf = window.requestAnimationFrame(draw);
	
  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
    ball.vy = -ball.vy;
  }
  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
    ball.vx = -ball.vx;
  }
}

canvas.addEventListener('mouseover', function(e){
  raf = window.requestAnimationFrame(draw);
});

canvas.addEventListener('mouseout', function(e){
  window.cancelAnimationFrame(raf);
});


ball.draw();

运行结果如下:

      上述案例依然是使用了 window.requestAnimationFrame() 来控制动画,然后小球按照一定的速率进行移动,然后设置边界值,超越边界的时候将速率反转,产生反弹的效果。同时,还给canvas添加了鼠标移入移出的事件监听,只有鼠标移入的时候才进行动画请求,鼠标移出的时候就取消请求(window.cancelAnimationFrame())。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值