HTML5 横空出世,怎能不提神奇的 canvas。还记得多年前小探 GDI 和 opengl 时的心潮澎湃,那时一心想在web中实现画板功能,但困惑于如何在 html 中嵌入 c++ 编译后的 exe 文件。后来,flash 和 flash3D 的发展让人没理由再去纠结这个问题,在 web 中嵌入一个 swf 相比 exe 要轻松多啦。直到有一天,WHATWG 的那组人向世界宣称 HTML5 添加了对脚本和布局之间的原生交互能力,他们的目标是和插件说再见。哇,这太让人激动,当禁用屏蔽安装失败的隐患消除之后,世界将变得更加和谐,于是渺小的我,从 canvas 开始,开启 Html5 的入门之旅。
首先要提的是 canvas 不是所有浏览器都支持,到目前为止,最新的 chrome,firefox,safari,opera 都支持 canvas,except 万恶的IE,IE真是说有多么可恶就有多么可恶啊!!
<!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]-->
其次,canvas 的使用方式基本遵循如下的顺序:
1、获取 canvas 对象,可以用 getElementById 可以用 querySelector (也是IE不支持) 还可以用 jquery 的选择器,var canvas = document.querySelector('canvas');
2、关联到 canvas 的上下文,指定 2D 的模式。 var context = canvas.getContext('2d');
3、保存之前的绘图 save
4、应用变形,scale、transform、shdow
5、开始记录需要绘制的路径,可以是直线,曲线
6、填充或者绘图,stroke、fill
7、重置 restore
最后,来小试牛刀,想要实现简易的画板,那么只要完成几个步骤
1、鼠标在 canvas 里面 mousemove 的时候要获取鼠标的位置 (posX,posY)
2、获取 canvas 顶点的坐标, canvas.left(), canvas.top()
3、由此可以获得 mousemovede 的时候鼠标点 point 相对于 canvas 原点的坐标为 (posX-canvas.left(),posY-canvas.top())
4、以鼠标 point 的位置为圆心,小圆点作为笔触
代码贴在后面供参考,其中获取canvas起点的坐标用了三种写法,分别为(其中的优缺点不言自明,推崇第二种写法):
screenPosition(canvas).left、 canvas.left()、getLeft(canvas)
screenPosition(canvas).top、 canvas.top()、getTop(canvas)
<!DOCTYPE html> <html> <title>HTML5 Canvas Example</title> <style type="text/css"> canvas {background-image: url("flower.jpg"); border: 1px solid ; } </style> <h1>Magical Canvas,Let's begin!</h1> <canvas class="clear" width="300" height="300"> </canvas> <button>Reset</button> <script> var resetBtn = document.querySelector('button'); var canvas = document.querySelector('canvas'); var context = canvas.getContext('2d'); function reset(){ context.clearRect(0,0,300,300); } function move(e){ var posX = mousePosition(e).x; var posY = mousePosition(e).y; var x = posX - canvas.left(); var y = posY - canvas.top(); drawHeatPoint(x, y, context); } function drawHeatPoint(x,y,context){ context.save(); context.fillStyle = 'yellow'; context.beginPath(); context.arc(x,y,3,0,Math.PI*2,true); context.closePath(); context.fill(); context.restore(); } function mousePosition(e) { return { x : e.clientX + document.documentElement.scrollLeft - document.documentElement.clientLeft, y : e.clientY + document.documentElement.scrollTop - document.documentElement.clientTop }; } function screenPosition(e){ var offsetTop=e.offsetTop; var offsetLeft=e.offsetLeft; if(e.offsetParent!=null){ offsetTop += arguments.callee(e.offsetParent); offsetLeft += arguments.callee(e.offsetParent); } return{ top:offsetTop, left:offsetLeft }; } canvas.top = function(){ var offset=this.offsetTop; if(this.offsetParent!=null) offset+=getTop(this.offsetParent); return offset; } canvas.left = function(){ var offset=this.offsetLeft; if(this.offsetParent!=null) offset+=getLeft(this.offsetParent); return offset; } //获取元素的纵坐标 function getTop(e){ var offset=e.offsetTop; if(e.offsetParent!=null) offset+=getTop(e.offsetParent); return offset; } //获取元素的横坐标 function getLeft(e){ var offset=e.offsetLeft; if(e.offsetParent!=null) offset+=getLeft(e.offsetParent); return offset; } resetBtn.addEventListener('click',reset,true); canvas.addEventListener('mousemove',move,true); </script> </html>