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>