HTML5 canvas 繪製精美的圖形

HTML5 是一個新興標準,它正在以愈來愈快的速度替代久經考驗的 HTML4。HTML5 是一個 W3C 「工做草案」 — 意味着它仍然處於開發階段 — 它包含豐富的元素和屬性,它們都支持現行的 HTML 4.01 版本規範。它還引入了幾個新元素和屬性,它們適用許多使用 web 頁面的領域 — 音頻、視頻、圖形、數據存儲、內容呈現,等等。本文主要關注圖形方面的加強:canvas。javascript

新的 HTML5 canvas 是一個原生 HTML 繪圖簿,用於 JavaScript 代碼,不使用第三方工具。跨全部 web 瀏覽器的完整 HTML5 支持尚未完成,但在新興的支持中,canvas 已經能夠在幾乎全部現代瀏覽器上良好運行了,但 Windows® Internet Explorer® 除外。幸運的是,一個解決方案已經出現,將 Internet Explorer 也包含進來。php

本質上,canvas 元素是一個白板,直到您在它上面 「繪製」 一些可視內容。與擁有各類畫筆的藝術家不一樣,您使用不一樣的方法在 canvas 上做畫。您甚至能夠在 canvas 上建立並操做動畫,這不是使用畫筆和油彩所可以實現的。html

本文探索新的 HTML canvas 元素,從簡單地包含一個 canvas 元素到高級 JavaScript 交互(動畫的關鍵)逐步進行演示。學習如何在一個 web 頁面上顯示 canvas。本文針對 web 設計師和開發人員,儘管 JavaScript 知識不是必須的,但理解該語言的運行方式將有所幫助。可是,HTML 知識是關鍵所在,尤爲是如何建立一個基本 web 頁面。html5

要查看本文展現的示例的實時實例,您須要一個瀏覽器並能訪問 Internet。全部示例都在一個真實網站上提供(參見 參考資料)。java

瀏覽器支持

肯定哪些瀏覽器支持 HTML5 和一個移動目標達到什麼程度。在本文撰寫之時,Google Chrome、Apple Safari 和 Mozilla Firefox 都支持大多數新的 HTML5 元素,它們都支持 canvas 元素。Internet Explorer 7 和 8 都不支持 HTML5;Internet Explorer 9 處於測試階段,支持 HTML5,但還有一些問題。web

在此期間,有一個針對不支持 HTML5 的 Internet Explorer 版本的補丁可用。這個補丁的前提是建立使用 JavaScript 代碼的元素。例如,可使用代碼段 document.createElement('canvas') 建立一個可識別的 Canvas 標記;可是,這並不意味着有東西通過元素自己 。一個流行的解決方法是包含一個完整的基於 canvas 的 JavaScript 庫,這個庫由 Google 提供,稱爲 ExplorerCanvas— 或簡稱 excanvas。下載並將其做爲一個外部文件引用,以下所示。(參見 參考資料 中的連接,瞭解更多 excanvas 信息。)ajax

<!--[if IE]>
  <script type="text/javascript" src="excanvas.js"></script>
<![endif]-->

經過包含 excanvas,您向 Internet Explorer 提供 canvas 及其大多數方法。編程

建立您的第一個 canvas

因爲 canvas 只是一個 HTML 標記,所以它的顯示方式只是包含在標記中。第一個示例(如 圖 1 所示)顯示一個最簡單的 canvas。它之因此可見,是由於它經過 style 屬性得到了一個顏色方案,經過 width 和 height 屬性得到了其大小。canvas

圖 1. 一個空白 canvas
一個空白 canvas,但因爲背景樣式而變得可見

這個頁面的代碼簡短明瞭,如 清單 1 所示。瀏覽器

清單 1. 包含一個 canvas 的 web 頁面的 HTML
<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas Demo</title>
<!--[if IE]><script type="text/javascript" src="excanvas.js"></script><![endif]-->
</head>
<body>
<div style="margin-left:30px;">
<canvas id="myCanvasTag" width="400" height="400" 
    style="border: 10px yellow solid"></canvas>
<br /><br />
<a href="index.html">back</a>
</div>
</body>
</html>

這個 canvas 的寬度和高度均爲 400 像素,邊框爲黃色,背景爲藍色。canvas 上沒有任何實際繪圖;繪圖經過屬於 canvas 的 JavaScript 方法完成。

canvas 方法

表 1 列示了幾個附加到 canvas 上下文的方法。

表 1. canvas 方法
方法 用途
getContext(contextId) 公開在 canvas 上繪圖須要的 API。唯一(當前)可用的 contextID 是 2d
height 設置 canvas 的高度。默認值是 150 像素。
width 設置 canvas 的寬度。默認值是 300 像素。
createLinearGradient(x1,y1,x2,y2) 建立一個線性漸變。起始座標爲 x1,y1,結束座標爲 x2,y2
createRadialGradient(x1,y1,r1,x2,y2,r2) 建立一個放射狀漸變。圓圈的起始座標是 x1,y1,半徑爲 r1。圓圈的結束座標爲x2,y2,半徑爲 r2
addColorStop(offset, color) 向一個漸變添加一個顏色中止。顏色中止(color stop) 是漸變中顏色更改發生的位置。offset 必須介於 0 到 1 之間。
fillStyle 設置用於填充一個區域的顏色 — 例如,fillStyle='rgb(255,0,0)'.
strokeStyle 設置用於繪製一根直線的顏色 — 例如,fillStyle='rgb(255,0,0)'.
fillRect(x,y,w,h) 填充一個定位於 x 和 y,寬度和高度分別爲 w 和 h 的矩形。
strokeRect(x,y,w,h) 繪製一個定位於 x 和 y,寬度和高度分別爲 w 和 h 的矩形的輪廓。
moveTo(x,y) 將繪圖位置移動到座標 x,y
lineTo(x,y)

從繪圖方法結束的最後位置到 x,y 繪製一條直線。

 translate(x,y):
translate(x,y)函數是將整個canvas水平移動x距離,垂直移動y距離。
canvas是以(0,0)爲默認原點,其原點默認在屏幕左上角;經過translate(x,y)把點(x,y)做爲原點。
須要注意的是:是在原點的基礎上分別偏移x和y。
例子:原點假如落在(1,1),那麼translate(10,10)就是在原點(1,1)基礎上分別在x軸、y軸移動10,則原點變爲(11,11)。

構建更復雜的 canvas 應用程序

本小節將展現一系列示例,每一個示例的功能都比前一個示例略有增長。

更深入的視覺體驗

首先,將一組矩形放置到 canvas 上。記住,矩形是擁有 4 條直邊和 4 個直角的圖形,正方形是矩形的變體。圖 2 顯示 canvas 上有一系列矩形,每一個矩形都比前一個略小。注意,每一個矩形的顏色都不一樣,使其更清晰明確。

圖 2. 使用一些矩形填充的 canvas
canvas 由一些顏色不一樣的矩形填充

清單 2 顯示了用於建立圖 2 中的 canvas 的代碼。每一個矩形都由兩行代碼建立:首先,fillStyle 方法使用顏色定義的紅、綠、藍(RGB)格式定義顏色(fillStyle='rgb(255,0,0))。而後,fillRect 方法(fillRect(50,50,300,300))定義大小。前兩個值設置起始座標,後兩個值設置結束座標。

清單 2. 使用 JavaScript 代碼建立上下文並使用各類方法
<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas Demo</title>
<!--[if IE]>
  <script type="text/javascript" src="excanvas.js"></script>
<![endif]-->
<script>
 window.onload=function() {
   var mycanvas=document.getElementById("myCanvasTag");
   var mycontext=mycanvas.getContext('2d');
   mycontext.fillStyle='rgb(0,0,255)'; 
   mycontext.fillRect(0,0,400,400);   
   mycontext.fillStyle='rgb(255,0,0)';  
   mycontext.fillRect(50,50,300,300);    
   mycontext.fillStyle='rgb(0,255,0)';  
   mycontext.fillRect(100,100,200,200);
   mycontext.fillStyle='rgb(100,100,100)';  
   mycontext.fillRect(125,175,150,25);
 }
</script>
</head>
<body>
<div style="margin-left:30px;">
<canvas id="myCanvasTag" width="400" height="400" style="border: 10px yellow solid">
</canvas>
<br /><br />
<a href="index.html">back</a>
</div>
</body>
</html>

要在 canvas 上繪圖,經過將 getContext('2d') 應用到 canvas 元素訪問提供方法的 API。經過這個 document.getElementById 方法,canvas 元素被設置爲一個 JavaScript 變量:

var mycanvas=document.getElementById("myCanvasTag");

而後將 getContext 應用到 canvas 元素,以下所示。

var mycontext=mycanvas.getContext('2d');

一旦一個變量被設置到上下文,全部方法就可使用了。

下一個示例展現如何結合兩種技術。一種是矩形重疊,方法是使用 fillRect 參數來定位矩形(見 圖 3)。

圖 3. 向一個 canvas 上的矩形應用透明度
設置 canvas 上的對象的透明度

第二種技術是 RGB 顏色處理的變體,即添加透明度。不使用 rgb,而是使用 rgbaa 表示 alpha 通道,該通道控制透明度。在圖 3 中的示例中,第二個矩形的透明度被設置爲 50%(或 .5),第三個設置爲 25%(或 .25)。清單 3 顯示了完整的標記。

清單 3. 使用透明度
<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas Demo</title>
<!--[if IE]>
  <script type="text/javascript" src="excanvas.js"></script>
<![endif]-->
<script>
  window.onload=function() {
    var mycanvas=document.getElementById("myCanvasTag");
    var mycontext=mycanvas.getContext('2d');
    mycontext.fillStyle='rgb(0,0,255)'; 
    mycontext.fillRect(30,30,300,300);           
    mycontext.fillStyle='rgba(0,255,0,0.5)';  
    mycontext.fillRect(60,60,300,300);    
    mycontext.fillStyle='rgba(255,0,0,0.25)';  
    mycontext.fillRect(90,90,300,300); 
  }
</script>
</head>
<body>
<div style="margin-left:30px;">
<canvas id="myCanvasTag" width="400" height="400" style="border: 10px yellow solid">
</canvas>
<br /><br />
<a href="index.html">back</a>
</div>
</body>
</html>

漸變— 通過協調的顏色混合 — 原生於 canvas ,經過兩種方法:createLinearGradient 和 createRadialGradient圖 4 展現了一個線性漸變。addColorStop 方法定義一個顏色,以及它在漸變中變爲活動狀態的位置。因爲一個漸變能夠擁有多個顏色中止,所以這種定位是主觀的。顏色定位值必須介於 0 到 1 之間,但測試變體和顏色中止的數量能夠生成不一樣的結果,即便一個值(好比 .25)保持不變。換句話說,一個顏色中止能夠將其位置設定爲 .25,可是相關顏色能夠從整個漸變路徑的四分之一處以後一點開始發生,一直持續到漸變結束,具體狀況取決於您設置其餘顏色中止的位置。記住,這是一個新的實現,可能還在改進過程當中。漸變的一個好處是它們老是引人注目,不管代碼和結果是否通過完美的協調。

圖 4. 一個線性漸變
一個線性漸變

圖 4 中的漸變經過 清單 4 中的 JavaScript 代碼建立。

清單 4. 建立一個線性漸變
    var mycanvas=document.getElementById("myCanvasTag");
    var mycontext=mycanvas.getContext('2d');
    var mygradient=mycontext.createLinearGradient(30,30,300,300);           
    mygradient.addColorStop(0,"#FF0000");
    mygradient.addColorStop(1,"#00FF00");
    mycontext.fillStyle=mygradient;
    mycontext.fillRect(0,0,400,400);

注意,清單 4 中的顏色中止被全面實現爲從這個方法自己建立的一個實時(on-the-fly)漸變的一個方法。語句mygradient.addColorStop(0,"#FF0000") 顯示顏色中止擁有兩個參數:位置和顏色。

圖 5 展現了一個放射狀漸變。用於建立這個漸變的代碼與清單 4 中的代碼相似,除了使用 createRadialGradient 方法替代createLinearGradient 方法以外。

圖 5. 一個放射狀漸變
一個放射狀漸變

用於建立圖 5 中的放射狀漸變的代碼如 清單 5 所示。注意全部 5 個顏色中止。

清單 5. 建立一個放射狀漸變
<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas Demo</title>
<!--[if IE]>
  <script type="text/javascript" src="excanvas.js"></script>
<![endif]-->
<script>
  window.onload=function() {
    var mycanvas=document.getElementById("myCanvasTag");
    var mycontext=mycanvas.getContext('2d');
    var mygradient=mycontext.createRadialGradient(300,300,0,300,300,300);           
    mygradient.addColorStop("0","magenta");
    mygradient.addColorStop(".25","blue");
    mygradient.addColorStop(".50","green");
    mygradient.addColorStop(".75","yellow");
    mygradient.addColorStop("1.0","red");                
    mycontext.fillStyle=mygradient;
    mycontext.fillRect(0,0,400,400);
  }
</script>
</head>
<body>
<div style="margin-left:30px;">
<canvas id="myCanvasTag" width="400" height="400" style="border: 10px blue solid">
</canvas>
<br /><br />
<a href="index.html">back</a>
</div>
</body>
</html>

多個 canvas

一個 web 頁面可以包含多個 canvas,每一個 canvas 引用它們本身的獨特 JavaScript 上下文變量。結果,每一個 canvas 都獨立於其餘 canvas 工做。圖 6 展現了 4 個 canvas,每一個 canvas 上的圖像都不一樣。

圖 6. 一個 web 頁面上的多個 canvas
多個 canvas

清單 6 顯示了用於建立圖 6 中的頁面的代碼。注意,每一個 canvas 都有一個唯一 ID 且每一個上下文都是唯一的。

清單 6. 一個 web 頁面上的多個 canvas
<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas Demo</title>
<!--[if IE]>
  <script type="text/javascript" src="excanvas.js"></script>
<![endif]-->
<script>
  window.onload=function() {
    var mycontext1=document.getElementById("myCanvasTag1").getContext('2d');
    var mycontext2=document.getElementById("myCanvasTag2").getContext('2d');
    var mycontext3=document.getElementById("myCanvasTag3").getContext('2d');
    var mycontext4=document.getElementById("myCanvasTag4").getContext('2d');         
    // gradient 1
    var mygradient1=mycontext1.createLinearGradient(30,30,90,90);           
    mygradient1.addColorStop(0,"#FF0000");
    mygradient1.addColorStop(1,"#00FF00");
    mycontext1.fillStyle=mygradient1;
    mycontext1.fillRect(0,0,100,100);
    // gradient 2   
    var mygradient2=mycontext2.createLinearGradient(30,30,90,90);           
    mygradient2.addColorStop(1,"#FF0000");
    mygradient2.addColorStop(0,"#00FF00");
    mycontext2.fillStyle=mygradient2;
    mycontext2.fillRect(0,0,100,100);

    var mygradient3=mycontext3.createLinearGradient(30,30,90,90);           
    mygradient3.addColorStop(0,"#0000FF");
    mygradient3.addColorStop(.5,"#00FFDD");
    mycontext3.fillStyle=mygradient3;
    mycontext3.fillRect(0,0,100,100);

    var mygradient4=mycontext1.createLinearGradient(30,30,90,90);           
    mygradient4.addColorStop(0,"#DD33CC");
    mygradient4.addColorStop(1,"#EEEEEE");
    mycontext4.fillStyle=mygradient4;
    mycontext4.fillRect(0,0,100,100);
  }
</script>
</head>
<body>
<div style="margin-left:30px;">
<canvas id="myCanvasTag1" width="100" height="100" style="border: 10px blue solid">
</canvas>
<canvas id="myCanvasTag2" width="100" height="100" style="border: 10px green solid">
</canvas>
<br />
<canvas id="myCanvasTag3" width="100" height="100" style="border: 10px red solid">
</canvas>
<canvas id="myCanvasTag4" width="100" height="100" style="border: 10px black solid">
</canvas>
<br /><br />
<a href="index.html">back</a>
</div>
</body>
</html>
 

JavaScript 事件和動畫

本文已經展現了可用於 canvas 的各類方法,每種方法都建立了一個可視結果。如今咱們提升一個等級,看看 canvas 如何實現事件和動畫。JavaScript 可以識別許多事件,包括在一個特定 web 頁面元素上方移動或懸停鼠標。JavaScript 語言可以識別更多事件,下面的示例將使用其中幾個。

整合事件

圖 7 中的示例是使用前面清單中的方法建立的。如今咱們添加幾個新技術。面部的鼻子、眼睛和圓形項目以及外部邊界都使用 arc 方法建立。眼睫毛被繪製爲線條,嘴被建立爲一條貝賽爾曲線。圖 7 還在 canvas 底部顯示了一些文本,這是使用 fillText 方法建立的。

圖 7. 使用 JavaScript 事件繪製一張正在眨眼的臉
一張正在眨眼的臉

清單 7 顯示圖 7 使用的代碼。

清單 7. 使用事件建立一個眨眼
<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas Demo</title>
<!--[if IE]>
  <script type="text/javascript" src="excanvas.js"></script>
<![endif]-->
<script>
window.onload=function() {
  var mycanvas=document.getElementById("myCanvasTag");
  var mycontext=mycanvas.getContext('2d');

  //draw face
  mycontext.beginPath();
  mycontext.arc(300, 250, 200, 0, Math.PI * 2, true);
  mycontext.closePath();
  mycontext.stroke();

  //draw left eye
  mycontext.beginPath();
  mycontext.arc(220, 150, 30, 0, Math.PI * 2, true);
  mycontext.closePath();
  mycontext.fillStyle='rgb(100,100,225)';
  mycontext.fill();

  //draw left iris
  mycontext.beginPath();
  mycontext.arc(220, 150, 10, 0, Math.PI * 2, true);
  mycontext.closePath();
  mycontext.fillStyle='rgb(0,0,0)';
  mycontext.fill();

  //draw left eyelid
  mycontext.beginPath();
  mycontext.arc(220, 150, 30, 0, Math.PI, true);
  mycontext.closePath();
  mycontext.fillStyle='rgb(200,200,200)';
  mycontext.fill();

  //draw left eyelashes
  mycontext.strokeStyle='rgb(0,0,0)';
  lashes(mycontext,198, 170, 193, 185);
  lashes(mycontext,208, 177, 204, 193);
  lashes(mycontext,220, 180, 220, 195);
  lashes(mycontext,232, 177, 236, 193);
  lashes(mycontext,242, 170, 247, 185);
  mycontext.stroke();

  openeye();

  //draw right eyelashes
  mycontext.strokeStyle='rgb(0,0,0)';
  lashes(mycontext, 358, 170, 353, 185);
  lashes(mycontext, 368, 177, 364, 193);
  lashes(mycontext, 380, 180, 380, 195);
  lashes(mycontext, 392, 177, 396, 193);
  lashes(mycontext, 402, 170, 407, 185);
  mycontext.stroke();

  //draw nose
  mycontext.beginPath();
  mycontext.arc(300, 250, 20, 0, Math.PI * 2, true);
  mycontext.closePath();
  mycontext.stroke();

  // draw smile
  mycontext.beginPath();
  mycontext.lineWidth = 10;
  mycontext.moveTo(180, 320);
  mycontext.bezierCurveTo(140, 320, 340, 420, 400, 360);
  mycontext.closePath();
  mycontext.stroke();

  //draw message at bottom
  mycontext.font="1em sans-serif";
  mycontext.fillStyle="rgb(0,0,0)";
  mycontext.fillText("Move the mouse over and off the canvas - the face winks!", 10, 480);
}

function lashes(cntx,x1,y1,x2,y2) {
  cntx.moveTo(x1,y1);
  cntx.lineTo(x2,y2);
}

function closeeye() {
  //close right eye
  var mycanvas=document.getElementById("myCanvasTag");
  var mycontext=mycanvas.getContext('2d');
  mycontext.beginPath();
  mycontext.arc(380, 150, 30, 0, Math.PI * 2, true);
  mycontext.closePath();
  mycontext.fillStyle='rgb(200,200,200)';
  mycontext.fill();
}

function openeye() {
  //open right eye
  var mycanvas=document.getElementById("myCanvasTag");
  var mycontext=mycanvas.getContext('2d');
  mycontext.beginPath();
  mycontext.arc(380, 150, 30, 0, Math.PI * 2, true);
  mycontext.closePath();
  mycontext.fillStyle='rgb(100,100,225)';
  mycontext.fill();
  //draw right iris
  mycontext.beginPath();
  mycontext.arc(380, 150, 10, 0, Math.PI * 2, true);
  mycontext.closePath();
  mycontext.fillStyle='rgb(0,0,0)';
  mycontext.fill();
  //draw right eyelid
  mycontext.beginPath();
  mycontext.arc(380, 150, 30, 0, Math.PI, true);
  mycontext.closePath();
  mycontext.fillStyle='rgb(200,200,200)';
  mycontext.fill();
}
</script>
</head>
<body>
<div style="margin-left:30px;">
<canvas id="myCanvasTag" width="600" height="500" style="border: 5px blue solid"
   onmouseover="closeeye()" onmouseout="openeye()"></canvas>
<br /><br />
<a href="index.html">back</a>
</div>
</body>
</html>

圖 7 中的臉經過一些 JavaScript 事件而改變。特別是, onmouseover 和 onmouseout 事件分別用於調用 closeeye() 和 openeye() 函數。這些函數不是 canvas 的方法,可是標準 JavaScript 函數。事件和函數之間的鏈接在 canvas 元素自己中進行。在 清單 7 中,頁面的主體區域接近代碼的底部,那是 canvas 所在的位置。canvas 標記內是:

onmouseover="closeeye()" onmouseout="openeye()"

清單 7 中出現了一個新的構造 —beginPath() 和 endPath() 的使用,它們用於明確區分獨立的複雜繪圖動做。封裝在其中的代碼繪製一個特殊的圖像,以分隔其餘繪圖動做。

關於 清單 7 中的代碼的幾個值得注意的地方列示以下:

  • 當頁面打開時,經過調用 openeye() 函數來繪製右眼。
  • 使用 fillText 方法將文本寫到 canvas 上。
  • 在 arc 方法中,MATH.PI * 2 建立了一個完整的圓圈,而 MATH.PI 將只建立一個半圓(例如,眼皮)。

動畫

JavaScript 打包了一個強大的編程利器。這種語言可以執行不少操控,如 清單 8 所示。這個代碼重複運行,在 canvas 上繪製一些線條。線條顏色隨機設置。

清單 8. 使用 JavaScript 建立動畫
<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas Demo</title>
<!--[if IE]>
  <script type="text/javascript" src="excanvas.js"></script>
<![endif]-->
</head>
<body>
<div style="margin-left:30px;">
<canvas id="myCanvasTag" width="400" height="400" style="border: 10px blue solid">
</canvas>
<br /><br />
<a href="index.html">back</a>
</div>
<script>
  var mycanvas  = document.getElementById("myCanvasTag")
  var mycontext = mycanvas.getContext('2d');
  var x;
  var y;
  var x2;
  var y2;
  var r;
  var g;
  var b;
 function line() {
   x=Math.floor(Math.random()*190) + Math.floor(Math.random()*190);
   y=Math.floor(Math.random()*190) + Math.floor(Math.random()*190);
   x2=Math.floor(Math.random()*190) + Math.floor(Math.random()*190);
   y2=Math.floor(Math.random()*190) + Math.floor(Math.random()*190);
   r=Math.floor(Math.random()*255);
   g=Math.floor(Math.random()*255);
   b=Math.floor(Math.random()*255);
   mycontext.moveTo(x, y);
   mycontext.lineTo(x2, y2);
   mycontext.strokeStyle='rgb(' + r + ',' + g +  ',' + b + ')';  
   mycontext.lineWidth=Math.floor(Math.random()*6);      
   mycontext.stroke();
   mycontext.restore();
 }
 setInterval(line, 100);

</script>
</body>
</html>

圖 8 顯示了這個動畫的一張快照。清單 8 中的代碼與本文其餘全部代碼示例都不一樣,由於 JavaScript 塊被放置到頁面底部,canvas 元素下方。這確保 canvas 在代碼運行以前就已經被呈現了。

圖 8. JavaScript 用於繪製無窮無盡的隨機線條
一個 canvas 上的動畫
 

結束語

HTML5 被定位於用於改變 web 開發的面貌。新的元素使得頁面佈局更簡單,支持經過瀏覽器存儲本地數據,擁有 canvas 之類的音頻、視頻和圖形平臺。隨着瀏覽器升級以支持更多新功能,web 的性質和用戶體驗將變得妙不可言。web 開發前景一片光明!

參考資料

學習

得到產品和技術

 

文章出處:http://www.ibm.com/developerworks/cn/web/wa-html5canvas/#ibm-pcon

相關文章
相關標籤/搜索