前面我整理过一篇文章介绍了一些基本的API,从这篇文章我们已经可以基本了解到常用绘图的API、简单的变换和动画。而本篇文章的主要内容包括高级动画、像素操作、性能优化等知识点,讲解每个知识点的同时还会有一些酷炫的demo,保证看官们全程在线,毫无尿点,看完不会后悔,哈哈,一个耿直的笑^_^。
除此之外,关于canvas的一系列实例即将来袭!欢迎关注!
开始之前
//获取canvas容器 var can = document.getElementById('canvas'); //创建一个画布 var ctx = can.getContext('2d');
下面所有的操作都在画布ctx上进行操作。
高级动画
继上一篇简单介绍了动画(主要是requestAnimationFrame方法),现在我们来一步步实现一个在画布内滚动的实例。
html代码:
<canvas></canvas>
js代码:
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var ball = { //小球属性,原点位置,速度,半径等。 x: 100, y: 100, vx: 4, vy: 2, radius: 20, 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; //改变小球位置坐标 if (ball.y + ball.vy > canvas.height-15 || ball.y + ball.vy < 15) { //边界判断 ball.vy = -ball.vy; } if (ball.x + ball.vx > canvas.width-15 || ball.x + ball.vx < 15) { //边界判断 ball.vx = -ball.vx; } window.requestAnimationFrame(draw); //循环执行 } draw();
上面代码实现的效果如下图:
代码我已经写了基本的注释,不难理解,简单概括一下这个实例的实现思想:
创建一个小球对象,包含一个绘制自己的方法。在整个画布中绘制这个小球,然后在下一次绘制之前,先清除整个画布,改变小球的各个属性(包含了逻辑,比如边界的判断),然后重新绘制一遍,从而达到了动起来的效果。
如果你把上面代码中的
ctx.clearRect(0,0, canvas.width, canvas.height);
换成下面这样:
ctx.fillStyle = 'rgba(255,255,255,0.3)'; ctx.fillRect(0, 0, canvas.width, canvas.height);
就可以得到渐变尾巴的效果:
大概意思就是使用半透明的白色背景填充画布来代替直接清除这个画布,从而实现了想要的效果。
像素操作
如果我们想对一个canvas画布进行如下操作:获取每一个点的信息,对每一个坐标点进行操作。那我们就需要了解一下ImageData对象了。
ImageData对象(由getImageData方法获取的)中存储着canvas对象真实的像素数据,它包含以下几个只读属性:
width
图片宽度,单位是像素。
height
图片高度,单位是像素。
data
Uint8ClampedArray类型的一维数组,包含着RGBA格式的整型数据,范围在0至255之间(包括255)。简单讲,就是一个数组,每四个元素存储一个点的颜色信息,这四个元素分别对应为R、G、B、A的值(知道颜色取值的一眼就明白了,不知道的也没关系,后面有实例,一看就明白)。
创建ImageData对象
去创建一个新的,空白的ImageData对像,你应该会使用createImageData()方法:
var myImageData = ctx.createImageData(width, height);
上面代码创建了一个新的具体特定尺寸的ImageData对像。所有像素被预设为透明黑。
获取像素数据
为了获得一个包含画布场景像素数据的ImageData对像,你可以用getImageData()方法:
var myImageData = ctx.getImageData(left, top, width, height);
创建的myImageData对象就有width、height、data三个属性的值了。看下面这个实例:
html代码:
<div>hover处的颜色</div> <canvas></canvas>
js代码:
var can = document.getElementById('myCanvas'); var ctx = can.getContext('2d'); var img = new Image(); img.src = "img_the_scream.jpg"; ctx.drawImage(img, 0, 0); var color = document.getElementById('color'); function pick(event) { var x = event.layerX; var y = event.layerY; var area = ctx.getImageData(x, y, 1, 1); //创建ImageData对象 var data = area.data; //获取data属性(一个存储颜色rgba值的数组) var rgba = 'rgba(' + data[0] + ',' + data[1] + ',' + data[2] + ',' + data[3] + ')'; color.style.color = rgba; color.textContent = rgba; } can.addEventListener('mousemove', pick);
实现的效果如下图: