我的家園

          我的家園

          HTML5 canvas 元素詳細教程七

          Posted on 2012-04-15 16:37 zljpp 閱讀(193) 評論(0)  編輯  收藏

          HTML5 canvas 元素詳細教程七:基本的動畫。

          由于我們是用腳本去操控 canvas 對象,這樣要實現一些交互動畫也是相當容易的。只不過,canvas 從來都不是專門為動畫而設計的(不像 Flash),難免會有些限制。

          可能最大的限制就是圖像一旦繪制出來,它就是一直保持那樣了。如果需要移動它,我們不得不對所有東西(包括之前的)進行重繪。重繪是相當費時的,而且性能很依賴于電腦的速度。

          基本動畫的步驟 Basic animation steps

          畫一幀,你需要以下一些步驟:

          1. 清空 canvas
            除非接下來要畫的內容會完全充滿 canvas (例如背景圖),否則你需要清空所有。最簡單的做法就是用 clearRect 方法。
          2. 保存 canvas 狀態
            如果你要改變一些會改變 canvas 狀態的設置(樣式,變形之類的),又要在每畫一幀之時都是原始狀態的話,你需要先保存一下。
          3. 繪制動畫圖形(animated shapes)
            這一步才是重繪動畫幀。
          4. 恢復 canvas 狀態
            如果已經保存了 canvas 的狀態,可以先恢復它,然后重繪下一幀。

          操控動畫 Controlling an animation

          在 canvas 上繪制內容是用 canvas 提供的或者自定義的方法,而通常,我們僅僅在腳本執行結束后才能看見結果,比如說,在 for 循環里面做完成動畫是不太可能的。

          我們需要一些可以定時的執行重繪的方法。有兩種方法可以實現這樣的動畫操控。首先可以通過 setInterval 和 setTimeout方法來控制在設定的時間點上執行重繪。

          	setInterval(animateShape,500);
          setTimeout(animateShape,500);
          
          如果你不需要任何交互操作,用 setInterval 方法定時執行重繪是最適合的了。在上面的例子(leegorous不見了?)里 animateShape 方法每半秒執行一次。
          setTimeout 方法只會在預設時間點上執行操作。
          
          第二個方法,我們可以利用用戶輸入來實現操控。如果需要做一個游戲,我們可以通過監聽用戶交互過程中觸發的事件(如 keyboard,mouse)來控制動畫效果。
          

          下面的例子,我還使用第一種方式實現動畫效果。頁面底部有些鏈接,那些是應用第二種方法的例子。

          動畫例子 1

          效果圖這個例子里面,我會讓一個小型的太陽系模擬系統動起來。

          	var sun = new Image();
          var moon = new Image();
          var earth = new Image();
          function init(){
            sun.src = 'images/sun.png';
            moon.src = 'images/moon.png';
            earth.src = 'images/earth.png';
            setInterval(draw,100);
          }
          
          function draw() {
            var ctx = document.getElementById('canvas').getContext('2d');
          
            ctx.globalCompositeOperation = 'destination-over';
            ctx.clearRect(0,0,300,300); // clear canvas
          
            ctx.fillStyle = 'rgba(0,0,0,0.4)';
            ctx.strokeStyle = 'rgba(0,153,255,0.4)';
            ctx.save();
            ctx.translate(150,150);
          
            // Earth
            var time = new Date();
            ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
            ctx.translate(105,0);
            ctx.fillRect(0,-12,50,24); // Shadow
            ctx.drawImage(earth,-12,-12);
          
            // Moon
            ctx.save();
            ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
            ctx.translate(0,28.5);
            ctx.drawImage(moon,-3.5,-3.5);
            ctx.restore();
          
            ctx.restore();
            
            ctx.beginPath();
            ctx.arc(150,150,105,0,Math.PI*2,false); // Earth orbit
            ctx.stroke();
           
            ctx.drawImage(sun,0,0,300,300);
          }

          動畫例子 2

          效果圖

          	function init(){
            clock();
            setInterval(clock,1000);
          }
          function clock(){
            var now = new Date();
            var ctx = document.getElementById('canvas').getContext('2d');
            ctx.save();
            ctx.clearRect(0,0,150,150);
            ctx.translate(75,75);
            ctx.scale(0.4,0.4);
            ctx.rotate(-Math.PI/2);
            ctx.strokeStyle = "black";
            ctx.fillStyle = "white";
            ctx.lineWidth = 8;
            ctx.lineCap = "round";
          
            // Hour marks
            ctx.save();
            for (var i=0;i<12;i++){
              ctx.beginPath();
              ctx.rotate(Math.PI/6);
              ctx.moveTo(100,0);
              ctx.lineTo(120,0);
              ctx.stroke();
            }
            ctx.restore();
          
            // Minute marks
            ctx.save();
            ctx.lineWidth = 5;
            for (i=0;i<60;i++){
              if (i%5!=0) {
                ctx.beginPath();
                ctx.moveTo(117,0);
                ctx.lineTo(120,0);
                ctx.stroke();
              }
              ctx.rotate(Math.PI/30);
            }
            ctx.restore();
            
            var sec = now.getSeconds();
            var min = now.getMinutes();
            var hr  = now.getHours();
            hr = hr>=12 ? hr-12 : hr;
          
            ctx.fillStyle = "black";
          
            // write Hours
            ctx.save();
            ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
            ctx.lineWidth = 14;
            ctx.beginPath();
            ctx.moveTo(-20,0);
            ctx.lineTo(80,0);
            ctx.stroke();
            ctx.restore();
          
            // write Minutes
            ctx.save();
            ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
            ctx.lineWidth = 10;
            ctx.beginPath();
            ctx.moveTo(-28,0);
            ctx.lineTo(112,0);
            ctx.stroke();
            ctx.restore();
            
            // Write seconds
            ctx.save();
            ctx.rotate(sec * Math.PI/30);
            ctx.strokeStyle = "#D40000";
            ctx.fillStyle = "#D40000";
            ctx.lineWidth = 6;
            ctx.beginPath();
            ctx.moveTo(-30,0);
            ctx.lineTo(83,0);
            ctx.stroke();
            ctx.beginPath();
            ctx.arc(0,0,10,0,Math.PI*2,true);
            ctx.fill();
            ctx.beginPath();
            ctx.arc(95,0,10,0,Math.PI*2,true);
            ctx.stroke();
            ctx.fillStyle = "#555";
            ctx.arc(0,0,3,0,Math.PI*2,true);
            ctx.fill();
            ctx.restore();
          
            ctx.beginPath();
            ctx.lineWidth = 14;
            ctx.strokeStyle = '#325FA2';
            ctx.arc(0,0,142,0,Math.PI*2,true);
            ctx.stroke();
          
            ctx.restore();
          }

          動畫例子 3

          這是一個從左到右滾動的全景動畫的代碼。請注意圖片的大小需要比 canvas 大。

          本例中用的是這張圖片:
          http://www.css3-html5.com/uploadfile/2011/0721/20110721020253661.jpg

          	var img = new Image();
          
          //User Variables
          img.src = 'Capitan_Meadows,_Yosemite_National_Park.jpg';
          var CanvasXSize = 800;
          var CanvasYSize = 200;
          var speed = 30; //lower is faster
          var scale = 1.05;
          var y = -4.5; //vertical offset
          //End User Variables
          
          var dx = 0.75;
          var imgW = img.width*scale;
          var imgH = img.height*scale;
          var x = 0;
          if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
          var clearX;
          var clearY;
          if (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvas
          else { clearX = CanvasXSize; }
          if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvas
          else { clearY = CanvasYSize; }
          var ctx;
          
          function init() {
              //Get Canvas Element
              ctx = document.getElementById('canvas').getContext('2d');
              //Set Refresh Rate
              return setInterval(draw, speed);
          }
          
          function draw() {
              //Clear Canvas
              ctx.clearRect(0,0,clearX,clearY);
              //If image is <= Canvas Size
              if (imgW <= CanvasXSize) {
                  //reset, start from beginning
                  if (x > (CanvasXSize)) { x = 0; }
                  //draw aditional image
                  if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
              }
              //If image is > Canvas Size
              else {
                  //reset, start from beginning
                  if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
                  //draw aditional image
                  if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
              }
              //draw image
              ctx.drawImage(img,x,y,imgW,imgH);
              //amount to move
              x += dx;
          }

          html code. Canvas width and height should match the CanvasXSize, CanvasYSize.

          	<body onload="init();">
          <canvas id="canvas" width="800" height="200"></canvas>

          其它例子

          HTML5 Canvas 的詳細教程就先在這結束,以后有更好的教程,我們會第一時間分享給大家。


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 蛟河市| 崇文区| 韩城市| 东平县| 弋阳县| 苗栗市| 冕宁县| 涞源县| 子洲县| 日喀则市| 宝山区| 新干县| 十堰市| 彝良县| 盐津县| 方城县| 阿图什市| 阜新| 佛坪县| 威远县| 监利县| 德化县| 正镶白旗| 泰来县| 汉沽区| 黑山县| 托克逊县| 攀枝花市| 闵行区| 凤山县| 侯马市| 乐山市| 漾濞| 敖汉旗| 德清县| 安岳县| 九寨沟县| 三门县| 丰城市| 全椒县| 郎溪县|