利用canvas製作最簡易的畫板

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>

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章