html5 canvas入门
可以把canvas看做div,不过,它的长和宽不能通过css来定义,要使用标签属性:
<canvas id=”myCanvas” width=”100px” height=”100px”>
或者javascript对象属性设置:
canvas.width=1024;
canvas.height=768;
使用canvas,只有一种操作方式,使用javascript。
获得canvas对象的上下文对象,该对象是操作canvas的主要对象:
var canvas = document.getElementById(‘myCanvas’);
var context = canvas.getContext(’2d’);
画简单的线
使用canvas画最简单的线, 点击运行示例,结果看起来是这样:
代码很简单:
<script>
window.onload = function () {
var canvas = document.getElementById(‘myCanvas’);
canvas.width=1024;
canvas.height=768;
var context = canvas.getContext(’2d’);context.moveTo(100, 100);//移动到起点
context.lineTo(1024-100, 768-100);//从起点划线到端点
context.lineWidth = 10;//线的宽度
context.strokeStyle = “#ff0000″;//线的颜色
context.lineCap = “butt”;//端点边缘样式,默认是butt
context.stroke();//为线填充颜色,默认颜色黑
};
加入图片
如果想在canvas里加入图片, 点击运行示例,结果类似这样:
主要代码如下:
<script>
window.onload = function () {
var canvas = document.getElementById(‘myCanvas’);
canvas.width=1024;
canvas.height=768;
var context = canvas.getContext(’2d’);var image = new Image();
var x = 50, y = 10;image.onload = function () {
context.drawImage(image,x,y,image.width*.5,image.height*.5);//缩小到一半
};image.src = ‘tank.gif’;
};
简单的动画
使用canvas处理动画,其实本质上就是定时重绘canvas。比如在上面图片示例做修改,让坦克运动起来, 点击运行示例:
这里要考虑的是,如何处理时间间隔。以前的一般做法是使用定时器,每间隔1000ms/60的时间绘制一个canvas,这样能每秒显示60桢,动画应该很流畅。
html5目前大部分浏览器支持一种新的函数,比如chrome下:
window.webkitRequestAnimationFrame(callback)
其中callback是函数,是由你来实现的,用于绘制下一桢canvas。把这个函数传给webkitRequestAnimationFrame,它会统一来绘制。
目前除了Safari未实现这个函数(应该在不久的将来得到实现,因为最新开发中版本的webkit已经带这个函数),各个浏览器均实现了类似功能,为了统一处理,一般会写如下的函数:
window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
这个函数定义了统一的requestAnimFrame函数,它会检测,如果没有支持,比如Safari的情况,就使用定时器来实现这个功能。
实现动画的主要代码:
<script>
window.onload = function () {
var canvas = document.getElementById(‘myCanvas’);
canvas.width = 1024;
canvas.height = 768;
var context = canvas.getContext(’2d’);window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();var image = new Image();
var x = 50, y = 10;function animate() {
context.clearRect(0, 0, canvas.width, canvas.height);//清除canvas
context.drawImage(image, x++, y++, image.width, image.height);window.requestAnimFrame(function () {
if (x > 1024) {
console.log(‘animate stop’);
return;
}
animate();
});
}image.onload = function () {
context.drawImage(image, x, y, image.width, image.height);
animate();
};image.src = ‘tank.gif’;
};
这里的animate函数被递归调用,直到坦克图片到达canvas边缘停止。
保存和恢复状态
一般动画会有背景,比如 类似这样:
这要求重新绘制坦克的时候,也要重新绘制后面的线。
canvas提供了save和restore状态的方法,可以把这想象为一个堆栈,save和restore是对当前绘制状态的保存和恢复。
不过,要注意的是,保存和恢复的是状态,而不是图形。比如可以保存线的坐标点,线的宽度,线的样式和线的颜色,这些是状态信息,但是restore的时候并不绘制它们,你还需要调用stroke方法来划线。这已经极大的简化了很多需要重复的劳动了。
主要代码:
<script>
window.onload = function () {
var canvas = document.getElementById(‘myCanvas’);
canvas.width=1024;
canvas.height=768;
var context = canvas.getContext(’2d’);context.moveTo(100, 100);//移动到起点
context.lineTo(1024-100, 768-100);//从起点划线到端点
context.lineWidth = 10;//线的宽度
context.strokeStyle = “#ff0000″;//线的颜色
context.lineCap = “butt”;//端点边缘样式,默认是butt
context.stroke();//为线填充颜色,默认颜色黑
context.save();window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();var image = new Image();
var x = 50, y = 10;function animate() {
context.clearRect(0, 0, canvas.width, canvas.height);//清除canvas
context.restore();
context.stroke();
// context.save();
context.drawImage(image,x++,y++,image.width,image.height);window.requestAnimFrame(function(){
if(x>1024){
console.log(‘animate stop’);
return;
}
animate();
});
}image.onload = function () {
context.drawImage(image,x,y,image.width,image.height);
animate();
};image.src = ‘tank.gif’;
};
本文完整源代码可参见: https://github.com/MarshalW/CanvasDemo/tree/gh-pages