posts - 48,comments - 156,trackbacks - 0

          在前一篇博客中,我們測試了 canvas 標簽的用法,并得到了 canvas 標簽的渲染上下文對象, 但是并沒有用它繪制任何圖形。在這一篇中,我們先了解一下HTML5繪圖的一些基礎(chǔ)概念,然后再來畫幾個圖形玩玩。

          一、坐標系

          其實只要玩過一點點圖形編程的人都知道,電腦上的坐標系和數(shù)學上的坐標系稍微有點不同,坐標的原點在繪制區(qū)域(這里是Canvas)的左上角,X軸正向朝右,Y軸正向朝下,如下圖

          聲明:為本文為原創(chuàng)文章,作者保留所有權(quán)利!歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者左洸和出處博客園

           

          二、Stroke 和 Fill

          HTML5中將圖形分為兩大類:

          第一類稱作 Stroke,我的理解就是輪廓、勾勒或者線條,總之,圖形是由線條組成的;

          第二類稱作 Fill,就是填充區(qū)域

          上下文對象中有兩個繪制矩形的方法,可以讓我們很好的理解這兩大類圖形的區(qū)別:

          一個是 strokeRect,還有一個是 fillRect

          下面的代碼分別用這兩個方法來繪制矩形,你可以分別點擊兩個按鈕來看看有什么不同,從而理解 stroke 和 fill 的區(qū)別

          設(shè)置畫布
          <canvas id="test1" width="200" height="200" style=" background-color: grey">你的瀏覽器不支持 &lt;canvas&gt;標簽,請使用 Chrome 瀏覽器 或者 FireFox 瀏覽器</canvas>
          <input type="button" value="strokeRect"  onclick="strokeRect();"/>
          <input type="button" value="fillRect"  onclick="fillRect();"/>

           

          strokeRect 和 fillRect
          function strokeRect(){
              var canvas 
          = document.getElementById('test1');
              var ctx
          =canvas.getContext("2d");
              ctx.clearRect(
          0,0,200,200);
              ctx.strokeStyle
          ="blue";
              ctx.strokeRect(
          10,10,180,180);
          }

          function fillRect(){
              var canvas 
          = document.getElementById('test1');
              var ctx
          =canvas.getContext("2d");
              ctx.clearRect(
          0,0,200,200);
              ctx.fillStyle
          ="blue";
              ctx.fillRect(
          10,10,180,180);
          }

           

          你的瀏覽器不支持 <canvas>標簽,請使用 Chrome 瀏覽器 或者 FireFox 瀏覽器

           

          三、顏色

          上下文對象有兩個屬性可以用來設(shè)置顏色:strokeStyle 和 fillStyle

          strokeStyle 的值決定了你當前要繪制的線條的顏色

          fillStyle 的值決定了你當前要填充的區(qū)域的顏色

          顏色值應該是符合CSS3 顏色值標準的有效字符串。下面的例子都表示同一種顏色。

          //這些 fillStyle 的值均為 '橙色',ctx 是上下文對象 
          ctx.fillStyle = "orange"
          ctx
          .fillStyle = "#FFA500";
          ctx
          .fillStyle = "rgb(255,165,0)"
          ctx
          .fillStyle = "rgba(255,165,0,1)";

          關(guān)于顏色,以后會有更多的說明。

           

          四、基本繪圖

          除了上面給出的兩個繪制矩形的方法外,上下文對象還有幾個方法可以用來繪制一些基本圖形,如下:

          moveTo(x,y):moveTo方法并不能畫出任何東西,它只是將畫筆的當前點移動到(x,y)處

          lineTo(x,y):從當前點到(x,y)點繪制一條直線。注意:繪制完成后,當前點就變成了(x,y),除非你用 moveTo 方法去改變他

          arc(x, y, radius, startAngle, endAngle, anticlockwise) :繪制一條弧線

          quadraticCurveTo(cp1x, cp1y, x, y)
          bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) :這兩個方法都是繪制貝葉斯曲線,具體用法看參考手冊

          rect(x, y, width, height) :繪制一個矩形。注意: 當它被調(diào)用時,moveTo 方法會自動被調(diào)用,參數(shù)為(0,0),于是起始坐標又恢復成初始原點了。

          有了直線、弧線、曲線、方形和圓形這幾種基本圖形,我們就可以組合出更復雜的圖形了

           

          五、理解繪制路徑 Drawing Path

          上一篇文章中說過,我們繪制的圖形是先繪制到一個抽象的上下文對象中(其實就是內(nèi)存中),然后再將上下文對象輸出到顯示設(shè)備上,這個輸出到顯示設(shè)備的過程不需要我們操心。但是有時候我們并不想立刻輸出每一次繪制動作,也許我想讓一組繪制動作完成以后,再集中一塊輸出, 比如一個圍棋棋盤有19×19條直線組成,正常情況下需要向想顯示設(shè)備輸出19×19次,但是如果我們先暫停向顯示設(shè)備輸出,等在上下文中(內(nèi)存中)全部繪制完成19×19條直線時,再向顯示設(shè)備輸出,只需要輸出一次就可以了。

          這種情況在HTML5中叫做繪制路徑,它由幾個上下文對象的方法組成:

          beginPath() :開始路徑,意思就是在你調(diào)用這個方法后,你繪制的圖形就不會再向屏幕輸出了,而只是畫到了上下文對象中(內(nèi)存中)

          stroke() :將你調(diào)用 beginPath 方法以后繪制的所有線條,一次性輸出到顯示設(shè)備上

          closePath() :如果你調(diào)用 beginPath 方法以后,在上下文對象中進行了一系列的繪制,但是得到的圖形是不閉合的,這個方法將會幫你補上最后一條直線,將你的圖形閉合起來。

          注意closePath并不向屏幕輸出圖形,而只是在上下文對象中補上一條線,這個步驟不是必需的

          fill() :

          如果你的繪制路徑組成的圖形是封閉的,這個方法將用 fillStyle 設(shè)置的顏色填充圖形,然后立即向屏幕輸出;

          如果繪制路徑不是封閉的,這個方法會先將圖形閉合起來,然后再填充輸出。

          注意:所有的 fill 圖形,如 fillRect 等,都是立刻向屏幕輸出的,他們沒有繪制路徑這個概念

           

          下面的代碼將繪制一個簡單的填充三角形。

          注意:繪制三角形的時候,默認的背景色為白色,默認的前景色為黑色

          設(shè)置畫布
          <canvas id="test2" width="200" height="200" style="border:1px solid #c3c3c3;">你的瀏覽器不支持 &lt;canvas&gt;標簽,請使用 Chrome 瀏覽器 或者 FireFox 瀏覽器</canvas>
          <input type="button" value="畫三角"  onclick="drawTri();"/>
          <input type="button" value="清除"  onclick="clearTri();"/>

           

          繪制三角形
          <script type="text/javascript">
              
          function drawTri(){
                  var canvas 
          = document.getElementById('test2');
                  var ctx
          =canvas.getContext("2d");
                  ctx.beginPath();
                  ctx.moveTo(
          75,50);
                  ctx.lineTo(
          100,75);
                  ctx.lineTo(
          100,25);
                  ctx.fill();
              }
              
          function clearTri(){
                  var canvas 
          = document.getElementById('test2');
                  var ctx
          =canvas.getContext("2d");
                  ctx.clearRect(
          0,0,200,200);
              }
          </script>

          你的瀏覽器不支持 <canvas>標簽,請使用 Chrome 瀏覽器 或者 FireFox 瀏覽器

           

          六、半個單位的坐標

          這里還要回過頭來說說坐標,下面的代碼是在畫布上繪制網(wǎng)格,點擊“畫網(wǎng)格”按鈕可以看見效果

          設(shè)置畫布
          <canvas id="test3" width="500" height="375" style="border:1px solid #c3c3c3;">你的瀏覽器不支持 &lt;canvas&gt;標簽,請使用 Chrome 瀏覽器 或者 FireFox 瀏覽器</canvas>
          <input type="button" value="畫網(wǎng)格"  onclick="drawMap();"/>
          <input type="button" value="清除"  onclick="clearMap();"/>

           

          繪制網(wǎng)格
          <script type="text/javascript">
              
          function drawMap(){
                  var canvas 
          = document.getElementById('test3');
                  var ctx
          =canvas.getContext("2d");
                  ctx.beginPath();
                  
          for (var x = 0.5; x < 500; x += 10) {
                      ctx.moveTo(x, 
          0);
                      ctx.lineTo(x, 
          375);
                  }
                  
          for (var y = 0.5; y < 375; y += 10) {
                      ctx.moveTo(
          0, y);
                      ctx.lineTo(
          500, y);
                  }
                  ctx.strokeStyle 
          = "#eee";
                  ctx.stroke();
              }
              
          function clearMap(){
                  var canvas 
          = document.getElementById('test3');
                  var ctx
          =canvas.getContext("2d");
                  ctx.clearRect(
          0,0,500,375);
              }
          </script>

           

          你的瀏覽器不支持 <canvas>標簽,請使用 Chrome 瀏覽器 或者 FireFox 瀏覽器

           

          這段代碼中,有一處奇怪的地方,就是坐標循環(huán)是從0.5開始的,這是為什么呢?

          如下圖,假如我想繪制一條從(1,0)到(1,3)的線,由于線的默認寬度是一個像素,所以在我想象中應該繪制成深綠色的部分,即在坐標 1 兩邊各占半個像素的寬度。

          然而,瀏覽器的最小單位是一個像素,所以他會向兩邊擴展,實際繪制出來的淺綠色的部分,即占用了兩個像素的寬度。這樣,我們繪制的線條在坐標上就不精確了

          如下圖,如果我們給出的起始坐標是(1.5,0)和(1.5,3),那么線條的寬度才是正確的一個像素。

           

           

          七、清空畫布

          上面給出的兩段代碼中,我們都用到了清空畫布,用到的方法如下:

          clearRect(x,y,width,height):

          它接受四個參數(shù), x 和 y 指定矩形左上角(相對于原點)的位置,width 和 height 是矩形的寬和高。調(diào)用該方法會將給出的矩形區(qū)域中所有繪制圖形都清空,露出畫布的背景

           

          聲明:為本文為原創(chuàng)文章,作者保留所有權(quán)利!歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者左洸和出處博客園

          //==========================================

           

          posted on 2010-09-18 11:32 左洸 閱讀(2609) 評論(6)  編輯  收藏 所屬分類: HTML5

          FeedBack:
          # re: HTML5邊玩邊學(2):基礎(chǔ)繪圖
          2010-09-18 18:39 | SoleilNeon
          很好的教程,收藏了,HTML5是今后的發(fā)展方向。  回復  更多評論
            
          # re: HTML5邊玩邊學(2):基礎(chǔ)繪圖
          2010-09-18 21:23 | 高華
          jQueryWTP
          http://www.langtags.com/jquerywtp/?page_id=2
          讓Eclipse WTP 支持 HTML Canvas API,
          可以自動提示Canvas API,下載中文版,還有中文API  回復  更多評論
            
          # re: HTML5邊玩邊學(2):基礎(chǔ)繪圖[未登錄]
          2010-09-19 22:09 | 相信
          悲劇了...怎么跟javafx那么像  回復  更多評論
            
          # re: HTML5邊玩邊學(2):基礎(chǔ)繪圖[未登錄]
          2011-07-02 19:24 | l
          坐標循環(huán)是從0.5開始,還是不懂。  回復  更多評論
            
          # re: HTML5邊玩邊學(2):基礎(chǔ)繪圖[未登錄]
          2011-07-02 19:27 | l
          如果想每條畫出來的顏色不同,這樣加有什么錯?我是菜鳥。
          for (var x = 0.5; x < 500; x += 10) {
          ctx.moveTo(x, 0);
          ctx.lineTo(x, 375);
          ctx.strokeStyle = "rgba("+x+","+x+","+x+",1)";
          }  回復  更多評論
            
          # re: HTML5邊玩邊學(2):基礎(chǔ)繪圖[未登錄]
          2011-07-02 19:28 | l
          您有微博嗎?可以比較方便問你問題。  回復  更多評論
            
          主站蜘蛛池模板: 新巴尔虎左旗| 清水县| 前郭尔| 陆川县| 苏尼特左旗| 桂林市| 普陀区| 南江县| 乌鲁木齐市| 陆丰市| 夏河县| 海淀区| 福建省| 泰州市| 建平县| 滁州市| 安图县| 南京市| 松溪县| 阿克苏市| 澳门| 铁岭县| 盐源县| 贺州市| 随州市| 林口县| 海盐县| 镇原县| 铁岭市| 江津市| 大丰市| 开封县| 新乐市| 嘉禾县| 呼和浩特市| 黑水县| 金堂县| 威宁| 万全县| 青冈县| 冕宁县|