HTML5 Canvas初體驗之繪圖基礎

相信到目前你應該已經對Canvas這一神奇的HTML5新元素有了必定的瞭解。在本文中,咱們將深刻了解畫布的功能及特色,學習如何在HTML中利用Canvas繪製圖形以及其它類型對象。

【E800編譯】相信到目前你應該已經對Canvas這一神奇的HTML5新元素有了必定的瞭解。在本文中,咱們將深刻了解畫布的功能及特色,學習如何在HTML中利用Canvas繪製圖形以及其它類型對象。理解如何改變圖形形狀和對象是如何繪製在畫布上,以及如何將其擦除。最後,實例演示如何創建與瀏覽器窗口的大小相同的畫布,以及一些開發遊戲必不可缺的技巧等等。 javascript

熟悉canvas元素 css

如同視頻和音頻元素,canvas元素絕對沒有使用外部插件。你惟一須要的只是2D渲染上下文API,即便你不瞭解2D渲染上下文API也不用擔憂。 html

使用canvas元素很簡單,咱們從下面的代碼開始: java

<canvaswidth="500" height="500"> jquery

<!--Insert fallback content here --> web

</canvas> ajax

它的做用是建立一個新的空白畫布元素,目前還不可以看到什麼,由於你沒有作任何2D渲染上下文。 canvas

建立canvas元素時要特別注意寬度和高度屬性,顯然這些屬性定義canvas元素的大小,進而定義了2D渲染上下文的大小。在沒有定義的狀況下,將被設置默認的寬度和高度分別爲300150。稍後在本章,咱們將着眼於建立一個動態改變大小並填滿整個瀏覽器窗口的畫布。 api

注:canvas元素的位置在你的HTML文檔中定義。與其餘HTML元素同樣,它能夠按CSS所需處處移動。 瀏覽器

瀏覽器支持

目前大多數瀏覽器都支持canvas元素和其大部分功能,但對於Internet Explorer,至少任何早於Internet Explorer 9的版本沒法提供支持。一種方式是提醒舊版IE用戶升級,另外一種選擇是使用谷歌開發的一些ExplorerCanvas腳本。這種方法的優勢是,你只須要在頁面中潛入一個腳本,那麼canvas元素在舊版IE中也能正常顯示。

ExplorerCanvas腳本可在ExplorerCanvaswebsite下載,並按照說明安裝。

2D渲染上下文

canvas元素的目的是充當2D渲染上下文的封裝,爲您提供全部必要的方法調用以及繪製和操做的功能點。如下這一點很是重要:繪圖是在2D渲染上下文中進行,而不是在canvas元素中。你能夠經過canvas元素訪問並顯示2D渲染上下文。

座標系統

2D渲染上下文是一標準的基於屏幕的繪圖平臺。與其餘2D平臺一樣,使用同一個平面直角座標系左上角的原點(0,0)。向右移動會增長x的值,向下移動則增長y值。因此繪圖前必需要先了解座標系統是如何工做的。

2D渲染上下文中直角座標系

一般一個座標系統中的單個單元至關於在屏幕上的1個像素,因此位置(2430)位於向右24像素,向下30像素。也有一些場合座標系統的單位可能等於2個像素,如高清顯示器,不過通常的經驗法則是:1座標單位等於1個屏幕像素。

訪問2D渲染系統

不用多說,下面讓咱們建立一個基本的帶空白畫布元素的HTML頁:

<!DOCTYPE html>

<html>

       <head>

                <title>Learning thebasics of canvas</title>

               <metacharset="utf-8">

                <scripttype="text/javascript" src="http://ajax.googleapis.com

/ajax/libs/jquery/1/jquery.min.js"></script>

                <scripttype="text/javascript">

                       $(document).ready(function() {

                        });

                </script>

       </head>

       <body>

                <canvasid="myCanvas" width="500" height="500">

                        <!-- Insert fallbackcontent here -->

                </canvas>

       </body>

</html>

若是如今就運行它,將看不到任何東西。在真正開始繪圖以前,咱們先訪問2D渲染上下文。將如下代碼寫入jQuery聲明語句中:

var canvas = $("#myCanvas");

var context =canvas.get(0).getContext("2d");

咱們在這裏所要作的只是給canvas元素分配一個變量,而後經過調用getContext方法爲2D渲染上下文分配另外一個變量的。這裏須要注意的是,咱們使用了jQuery,咱們須要調用get方法來獲取canvas元素的DOM,這樣咱們就能夠獲取canvasgetContext方法。記住一點, get方法與畫布自己無關。

如今咱們就有了一個包含2D渲染上下文的變量,在聲明上下文變量後添加如下代碼:

context.fillRect(40, 40, 100, 100);

此時刷新頁面,你會發現已經出現了一個黑色的正方形!

圖形是黑色的,這是在畫布上繪製時的默認顏色。在稍後章節中,咱們會學習如何使用默認以外的顏色進行圖形繪製。

繪製基本形狀與線條

正如你所看到的,繪製一個正方形是很是簡單的,它只需一行代碼,fillRect()方法以下:

context.fillRect(40, 40, 100, 100);

你會發現所調用的方法爲fillRect()而不是fillSquare()。而咱們都知道正方形實際是具備相同長度的邊的矩形。

建立一個矩形須要四個參數,前兩個是矩形起點(左上角)的座標值(XY),最後兩個爲矩形的寬度和高度。fillRect()方法能夠形象化改寫成以下形式:

context.fillRect(x, y, width, height);

爲清晰起見,改變矩形的寬度值爲200,保存該文件並刷新頁面。

固然,這是一個矩形。在不一樣的位置繪製矩形只是改變起點的座標(xy)。例如在(200300)該點處:

在不一樣位置繪製一個矩形

注意:若是你繪圖時原點超出了canvas元素尺寸範圍,它將不會出如今屏幕上,而只有原點或者圖形的某些部分處於畫布元素範圍內時纔是可見的。

fillRect()strokeRect()是對雙胞胎,fillRect方法繪製一個矩形並填充一種顏色(本例以黑色爲例),strokeRect方法繪製一個矩形並描邊,也就是說矩形的輪廓有線條描邊。固然你也能夠在fillRect實例中改用strokeRect方法。

繪製一個描邊的矩形

如今出現的是一箇中空的矩形輪廓。

直線

直線與以上形狀略有不一樣,他們實際上爲路徑。建立一個簡單的路徑,你必須首先在2D渲染上下文中調用beginPath方法,接着調用moveTo方法,設置咱們即將繪製路徑的起點座標(XY)。最後調用closePath開始路徑繪製,其參數(XY)指定了路徑終點。示例代碼以下:

context.beginPath(); // Start the path

context.moveTo(40, 40); // Set the pathorigin

context.lineTo(340, 40); // Set the pathdestination

context.closePath(); // Close the path

context.stroke(); // Outline the path

路徑效果如圖:

經過改變lineTo方法的參數(XY)能夠實現直線的傾斜:

context.lineTo(340, 340);

在畫布上建立一個圈的方式遠區別於建立一個矩形。圓是一個至關複雜的形狀,甚至在Canvas中沒有單獨的方法調用來繪製。不過Canvas中提供了繪製圓弧的方法,而咱們所要作的就是將弧的兩端拼接。下面咱們來看看如何在Canvas中繪製一個圓:

context.beginPath(); // Start the path

context.arc(230, 90, 50, 0, Math.PI*2,false); // Draw a circle

context.closePath(); // Close the path

context.fill(); // Fill the path

第一個與最後兩行分別是開啓和關閉路徑(弧)並填充。

其中共有六個參數,(XY)指定了圓弧原點的座標(本例中圓的圓心),弧的半徑,起始角度,終止角度以及一個布爾值(布爾值爲true則逆時針繪製圓弧,反之順時針)。Arc()方法中具體參數以下:

context.arc(x, y, radius, startAngle,endAngle, anticlockwise);

圓的繪製圖示以下:

這裏須要注意的是,角度的單位都爲弧度,360度(一個完整的圓)爲2π(圓周率乘以2)弧度。能夠利用下面的公式完成弧度轉換:

var degrees = 1; // 1 degree

var radians = degrees * (Math.PI / 180); //0.0175 radians

度和弧度之間的轉換

注意:在JavaScript中能夠經過調用數學函數Math對象獲取PI值,除此以外數學函數的做用也十分普遍,如咱們後面即將提到的隨機數生成。

運最後行這個實例,實際效果以下:

若是隻是繪製一個半圓,很簡單,只需將角度改成π,代碼以下:

context.arc(230, 90, 50, 0, Math.PI,false); // Draw a semi-circle

若是一切順利,應該有一個可愛的半圈,在您的瀏覽器。

Arc()中的第六個參數是可選的,不過在Firefox瀏覽器下,若是它被省略了則會拋出一個錯誤,因此在繪圖時最好保留以明肯定義繪製的方向。

樣式

下面咱們看看在本章開頭說起的定義圖形顏色的問題:

context.fillStyle = "rgb(255, 0,0)";

context.fillRect(40, 40, 100, 100);

經過設置2D渲染上下文中的FillStyle屬性,可以實現改變圖形和路徑的填充色。在前面的實例中,分配了一個RGB(紅,綠,藍)顏色值,固然你也可使用任何有效的十六進制代碼形式的CSS顏色值(如#FF0000或「red」)。在本例中顏色設置爲全紅(紅色,沒有綠色與藍色),實際效果將會以下:

這樣會有一個缺點,問題在於設置了FillStyle屬性後就意味着你以後的一切圖形繪製都會按該顏色方案執行。當你只是想改變其中一個對象的顏色,需在完成繪製後將FillStyle屬性設置爲黑色(或另外某顏色),以下列代碼所示:

context.fillStyle = "rgb(255, 0,0)";

context.fillRect(40, 40, 100, 100); // Redsquare

context.fillRect(180, 40, 100, 100); // Redsquare

context.fillStyle = "rgb(0, 0,0)";

context.fillRect(320, 40, 100, 100); //Black square

在瀏覽器中的效果爲:

一樣你也能夠經過使用strokeStyle屬性勾勒圖形和路徑,例如,下面用stroke代替本例中的fill

context.strokeStyle = "rgb(255, 0,0)";

context.strokeRect(40, 40, 100, 100); //Red square

context.strokeRect(180, 40, 100, 100); //Red square

context.strokeStyle = "rgb(0, 0,0)";

context.strokeRect(320, 40, 100, 100); //Black square

注:固然也能夠同時使用fillStylestrokeStyle屬性,就繪製出填充與輪廓顏色大相徑庭的圖形。

context.strokeStyle = "rgb(255, 0,0)";

context.beginPath();

context.moveTo(40, 180);

context.lineTo(420, 180); // Red line

context.closePath();

context.stroke();

context.strokeStyle = "rgb(0, 0,0)";

context.beginPath();

context.moveTo(40, 220);

context.lineTo(420, 220); // Black line

context.closePath();

context.stroke();

調整線寬

想要在畫布上改變線寬,就要用到2D渲染上下文中的lineWidth屬性。lineWidth屬性默認值爲1,你能夠將它設置爲所需的任意值。例如,咱們改變紅色與黑色線條的寬度:

context.lineWidth = 5; // Make lines thick

context.strokeStyle = "rgb(255, 0,0)";

context.beginPath();

context.moveTo(40, 180);

context.lineTo(420, 180); // Red line

context.closePath();

context.stroke();

context.lineWidth = 20; // Make lines eventhicker

context.strokeStyle = "rgb(0, 0,0)";

context.beginPath();

context.moveTo(40, 220);

context.lineTo(420, 220); // Black line

context.closePath();

context.stroke();

運行結果顯示爲稍厚的紅線與過厚的黑線:

lineWidth屬性在圖形上一樣適用:

context.lineWidth = 5; // Make lines thick

context.strokeStyle = "rgb(255, 0,0)";

context.strokeRect(40, 40, 100, 100); //Red square

context.strokeRect(180, 40, 100, 100); //Red square

context.lineWidth = 20; // Make lines eventhicker

context.strokeStyle = "rgb(0, 0,0)";

context.strokeRect(320, 40, 100, 100); //Black square

繪製文本

Canvas不只僅是用來繪製圖形和圖像,也能夠用它來顯示文本。儘管在不少狀況下這並非一個較好的選擇,尤爲是相比使用更爲傳統的HTML元素(如AP元素)而言。

畫布上的文字是做爲一個圖像繪製出來,準確來說它並非文字,也就意味着它沒法像普通HTML文檔中的文本那樣被光標選中。若是你以前使用Microsoft畫圖,那麼你就會明白:一旦文本已經繪製,就不能再次編輯,除非刪除重繪。在畫布上繪製文本的好處是,你可使用各類精彩功能在畫布上繪製。這裏須要強調的是,不該在畫布上建立文本,你應該使用正常的HTML元素建立文本,而後經過CSS定位到畫布的頂層。這裏的關鍵區別在於,HTML處理文本(內容),而Canvas直接針對像素和圖形的處理。

如下代碼演示瞭如何繪製文本:

var text = "Hello, World!";

context.fillText(text, 40, 40);

2D渲染上下文中fillText方法共有四個參數(一個可選,咱們暫時忽略);首先是要繪製的文本字符串,第二和第三參數是文本原點(左下角)的座標值(XY)。

這裏沒有演示實例效果,由於它過小以至於很難看到,這是由於畫布上的文本字體的默認設置爲10px sans-serif(絕對微小)。可按下列代碼所示更改字體屬性:

var text = "Hello, World!";

context.font = "30px serif"; //Change the size and font

context.fillText(text, 40, 40);

CSS中的字體屬性相似,字體屬性爲一個字符串值。在前面的例子中,給出的字體屬性是像素尺寸,以及所要使用的字體名稱。實例中已將它設置爲serif,效果以下:

若是須要你甚至能夠設置爲斜體:

var text = "Hello, World!";

context.font = "italic 30pxserif";

context.fillText(text, 40, 40);

在這裏惟一要作的只是將italic添入字體屬性字符串中。除此以外還能夠做不少設置,諸如行的高度以及其它備用字體等等,這裏就不一一描述。

注:不難發現畫布的基礎功能使用極其簡單方便,由於2D渲染上下文API中使用的方法與屬性都是以易於理解的方式命名,這些都可以輕鬆掌握。

進行下一步以前,咱們先來了解下如何勾勒文本,這是很是有用的:

var text = "Hello, World!";

context.font = "italic 60pxserif";

context.strokeText(text, 40, 100);

其中調用的strokeText()方法的參數與fillText()徹底相同,爲了能更清晰的顯示,調整了上例中字體的大小及位置:

畫布擦除

當你在繪圖過程當中出了錯或要擦拭重繪時,能夠有兩種選擇:調用clearRect()方法,或者寬度/高度技巧。咱們首先看看2D渲染上下文中clearRect()方法。

例如剛剛在畫布上繪製一個正方形和一個圓:

context.fillRect(40, 40, 100, 100);

context.beginPath();

context.arc(230, 90, 50, 0, Math.PI*2,false);

context.closePath();

context.fill();

如今須要作的就是調用clearRect()方法,指定擦除區域的原點座標(X,Y),以及其寬度和高度。若是畫布500像素寬,500像素高,那麼調用方式能夠以下:

context.clearRect(0, 0, 500, 500);

此時再運行,將顯示爲空白。當不清楚畫布的大小時,還能夠調用clearRect(),參數能夠由jQuery寬度與高度的方法獲取:

context.clearRect(0, 0, canvas.width(),canvas.height());

完整代碼以下:

var canvas = $("#myCanvas");

var context = canvas.get(0).getContext("2d");

context.fillRect(40, 40, 100, 100);

context.beginPath();

context.arc(230, 90, 50, 0, Math.PI*2,false);

context.closePath();

context.fill();

context.clearRect(0, 0, canvas.width(),canvas.height());

注:canvas元素實際上提供了寬度和高度屬性,因此選擇哪一種方式徹底取決於你,使用jQuery方式,或純JavaScript方式獲取畫布的尺寸。

其實能夠沒必要清除整個畫布,徹底能夠很容易地清除某一特定區域。例如,在本例中僅刪除正方形,就可按下列方式調用clearRect()

context.clearRect(40, 40, 100, 100);

這樣就能夠單獨留下一個圓。

這種方式能夠指定clearRect()中的參數以清除一個特定的區域。在本例中,咱們將擦除區域的起點(左上角)設定在正方形的左上角(40,40),並將擦除區域的寬度與高度設置爲正方形的寬高度(100)。其結果是隻有正方形被清除。一樣你也能夠經過改變clearRect()參數將圓形擦除:

context.clearRect(180, 40, 100, 100);

這樣保留下來的就會只是一個正方形。

需注意的是,一個弧形的圓心是它的中心,因此要獲得clearRect方法正確的起點,咱們須要首先獲取弧的圓心,且XY的值需分別減去半徑。

context.fillRect(40, 40, 100, 100);

context.beginPath();

context.arc(230, 90, 50, 0, Math.PI*2,false);

context.closePath();

context.fill();

context.clearRect(230, 90, 50, 50);

以上代碼會截去圓形的一部分:

有時這種方式能夠用於快速方便地繪製複雜圖形,先繪製出基本形狀再加以裁剪。

寬度/高度技巧

若是你想擦除畫布上的一切從頭開始,那麼能夠考慮寬度/高度的技巧。這能夠用來重置畫布至默認設置並刷新狀態。這種方法確實有一些缺點,先舉個例子:

context.fillStyle = "rgb(255, 0,0)";

context.fillRect(40, 40, 100, 100);

context.beginPath();

context.arc(230, 90, 50, 0, Math.PI*2,false);

context.closePath();

context.fill();

先在畫布上繪製一個紅色的正方形和圓形,而後添加畫布復位:

canvas.attr("width",canvas.width());

canvas.attr("height",canvas.height());

這只是一個jQuery技巧應用,您須要改變的是canvas元素的寬度與高度屬性,而且能夠經過jQueryattr()方法作到這一點。咱們需傳遞參數名(寬度和高度),以及所要設置的參數值(與以前的的寬度和高度相同)。正常狀況下你會看到一個空白的畫布。

添加如下代碼行:

context.fillRect(40, 40, 100, 100);

寬度/高度技巧的缺點是,在畫布上全部一切都會復位,包括樣式和顏色等。

Canvas填充瀏覽器窗口

到目前爲止canvas元素一直在500像素這一固定的寬度和高度上,但那麼如何才能讓它填滿整個瀏覽器窗口呢?對於一個普通的HTML元素來講,你只需正常將其寬度和高度屬性設置爲100%便可。不過畫布元素並不支持該方法,這裏咱們來看另外一種方式。

最簡單的方式作就是將canvas元素的寬度和高度精確設置爲瀏覽器窗口的寬度和高度。咱們能夠經過window瀏覽器對象和jQuery技巧獲取寬度和高度:

var canvas = $("#myCanvas");

var context = canvas.get(0).getContext("2d");

canvas.attr("width",$(window).get(0).innerWidth);

canvas.attr("height",$(window).get(0).innerHeight);

context.fillRect(0, 0, canvas.width(),canvas.height());

使用$(window).get(0).innerHeight代替$(window).height()是由於後者沒法返回全部瀏覽器窗口的完整高度值。這種方法實際效果並不完美,瀏覽器窗口中canvas元素和滾動條的四周仍存在白色區域:

爲了解決這個問題,咱們須要用到CSS。在文本編輯器中建立一個canvas.css,並保存在HTML文檔的同一目錄下,將下列代碼加入CSS文件中並保存:

* { margin: 0; padding: 0; }

html, body { height: 100%; width: 100%; }

canvas { display: block; }

要使用HTML文檔中這一CSS,須要添加如下代碼行至jQuery script元素前的head元素內:

<link href="canvas.css"rel="stylesheet" type="text/css">

其效果是canvas元素完美地填充了整個瀏覽器窗口。

固然,這並無結束。你會發現無論怎麼調整瀏覽器窗口大小,畫布都會保持着以前的尺寸:

這就須要在瀏覽器窗口大小改變的同時來調整畫板的大小。

$(window).resize(resizeCanvas);

function resizeCanvas() {

       canvas.attr("width", $(window).get(0).innerWidth);

       canvas.attr("height", $(window).get(0).innerHeight);

       context.fillRect(0, 0, canvas.width(), canvas.height());

};

resizeCanvas();

此時你會發現畫布實現完美調整,而且不會出現滾動條。

總結

本章中涵蓋了各類有趣的東西,特別是在你從未使用過的Canvas以前。如今你已經學會如何使用canvas元素進行基本形狀和路徑的繪製,改變圖形和路徑的顏色,以及如何繪製文本,擦除畫布,如何使畫布填充瀏覽器窗口等等。

相關文章
相關標籤/搜索