1. 程式人生 > >安卓鳥學Html5 之Canvas繪圖實踐一

安卓鳥學Html5 之Canvas繪圖實踐一

前言

預言帝喬布斯說HTML5將會改變網際網路的生態環境,自從2014年html5的火爆然後對移動開發者是一個衝擊,很多公司紛紛轉戰HTML5個人覺得對我們是一個考驗,然後有朋友去面試直接問會nodejs不,然後 也有朋友轉成hybird開發了,說實在的用ionic和angularjs真心不會,壓力大的一逼。

以前也寫過一篇html5的,但是發現東西還是相當多的,所以這裡還是使用canvas來一步步重新學習,既然安卓自定義控制元件離不開canvas那麼html5的canvas同樣很重要。

Html5概述

HTML5是HTML標準的下一個版本。雖然HTML5沒有完全顛覆HTML4,但是它們也有一些不同最新最全的HTML5-HTML4對比資訊請看

http://dev.w3.org/html5/html4-differences/
1. 簡化的語法
HTML5簡化了很多細微的語法,例如doctype的宣告,你只需要寫!doctype html就行了。HTML 5 指定 UTF-8 編碼的方式如下meta charset=”UTF-8”
2. canvas標籤替代Flash
Flash給很多Web開發者帶來了麻煩,要在網頁上播放Flash需要一堆程式碼和外掛。canvas標籤使得開發者只要使用一個標籤就能和使用者產生UI互動。
3 新增許多標籤,也廢棄了很多標籤
4. 全新的表單
5.HTML5 支援了不同型別的儲存型別

HTML5 支援本地儲存,在之前版本中是通過 Cookie 實現的。HTML5 本地儲存速度快而且安全。並且HTML5有兩種不同的物件可用來儲存資料,HTML5通過JS來儲存和訪問資料:

localStorage 適用於長期儲存資料,瀏覽器關閉後資料不丟失
sessionStorage 只是針對一個session的資料儲存,儲存的資料在瀏覽器關閉後自動刪除

總的來說,HTML5已經超越了標記語言的範疇,更富語義的標籤將使得HTML5更有用處。Canvas+WEBGL等技術,實現無外掛的動畫以及影象、圖形處理能力;本地儲存,可實現offline應用;websocket,一改http的純pull模型,實現資料推送的夢想;MathML,SVG等,支援更加豐富的render等等等等,現在對於對HTML5的瞭解還只停留在表面階段,以後會多閱讀一部分HTML5的書籍增加一下見識。

Canvas使用

為什麼挑canvas來講?

一般的標籤還是沒有什麼好介紹的,我們還是來學習一些新標籤,然後canvas也是安卓的重要東西,所以我們學起來也順手點。

HTML5 canvas 標籤用於繪製圖像(通過指令碼,通常是 JavaScript)。
不過,canvas 元素本身並沒有繪製能力(它僅僅是圖形的容器) - 您必須使用指令碼來完成實際的繪圖任務。getContext() 方法可返回一個物件,該物件提供了用於在畫布上繪圖的方法和屬性。提供 getContext(“2d”) 物件屬性和方法,可用於在畫布上繪製文字、線條、矩形、圓形等等。

canvas初始化
<canvas id="canvas" width="800" height="300" style="background-color: aqua;align-content: center">
    你的瀏覽器暫不支援Canvas,請更換瀏覽器後再試
</canvas>
<script>
    window.onload=function(){
        var canvas=document.getElementById("canvas")
        canvas.width=800
        canvas.height=300
        var context=canvas.getContext("2d")
    }
</script>

可以看出我們的canvas物件是從document取出來的,而且必須是ElementById,用ElementsByName是沒有效果的(故意試了下),然後canvas就是一個畫布,畫東西必須是在javaScript裡面並且是context來操作。

draw one Line

draw 直線
    context.moveTo(100,100)//把畫筆移到這個位置
    context.lineTo(300,200)//把畫筆與此位置連線
    context.stroke()//畫

這裡寫圖片描述
canvas是基於狀態的繪製,我們可以改變畫筆的屬性(寬度,顏色)。

  context.lineWidth=8
  context.strokeStyle="#578"

strokeStyle和fillStyle設定的值:

ffffff

642

rgb( 255 , 128 , 0 )
rgba( 100 , 100 , 100 , 0.8 )
hsl( 20 , 62% , 28% )
hsla( 40 , 82% , 33% , 0.6 )
red

這裡寫圖片描述
接下來我們來改變形狀:

        var canvas=document.getElementById("canvas")
        canvas.width=800
        canvas.height=300
        var context=canvas.getContext("2d")
        context.lineWidth=30
        context.moveTo(100,100)
        context.lineTo(190,200)
        context.lineCap="butt"
        context.stroke()
        context.beginPath()
        context.moveTo(400,210)
        context.lineTo(250,100)
        context.lineCap="round"
        context.stroke()
        context.beginPath()
        context.moveTo(600,200)
        context.lineTo(300,280)
        context.lineCap="square"
        context.stroke()

這裡寫圖片描述

draw 折線
        context.lineWidth=10
        context.moveTo(100,100)
        context.lineTo(190,200)
        context.lineTo(100,290)
        context.lineTo(600,290)
        context.stroke()

通過lineTo不斷改變位置,連線起來就是直線。
這裡寫圖片描述

draw more line

使用

context.beginPath()//新路徑
context.closePath()//自動封閉路勁

    context.lineWidth=10
        context.moveTo(100,100)
        context.lineTo(190,200)
        context.lineTo(190,100)
        context.strokeStyle="blue"
        context.stroke()
        context.moveTo(300,100)
        context.lineTo(390,200)
        context.lineTo(390,100)
        context.strokeStyle="red"
        context.stroke()
        context.moveTo(500,100)
        context.lineTo(590,200)
        context.lineTo(590,100)
        context.strokeStyle="green"
        context.stroke()

這裡寫圖片描述
你是不是發現雖然生成了3條折線,但是好像顏色都被最後一個顏色屬性覆蓋了,所以就要使用beginPath()

        context.lineWidth=10
        context.moveTo(100,100)
        context.lineTo(190,200)
        context.lineTo(190,100)
        context.strokeStyle="blue"
        context.stroke()
        context.beginPath()
        context.moveTo(300,100)
        context.lineTo(390,200)
        context.lineTo(390,100)
        context.strokeStyle="red"
        context.stroke()
        context.beginPath()
        context.moveTo(500,100)
        context.lineTo(590,200)
        context.lineTo(590,100)
        context.strokeStyle="green"
        context.stroke()

這裡寫圖片描述

然後你會發現使用了beginPath()後,moveTo()變成lineTo()後效果也是一樣。

draw封閉圖形

想當然的把首尾座標弄一樣,就是封閉圖形,結果還是有點小問題:

        context.lineWidth=20
        context.moveTo(400,350)
        context.lineTo(200,150)
        context.lineTo(600,150)
        context.lineTo(400,400)
        context.lineTo(500,200)
        context.lineTo(400,350)
        context.strokeStyle="green"
        context.stroke()

這裡寫圖片描述
看見沒有,有個小缺口,然後解決的辦法就是使用 context.closePath()代替 context.lineTo(400,350)
這裡寫圖片描述

畫五角星

實現思路:
這裡寫圖片描述
程式碼實現:

  function drawStar(ctx,r,R,x,y,rotaion){
       ctx.beginPath()
       for(var i =0 ;i<5;i++){
           ctx.lineTo(Math.cos((18+i*72-rotaion)/180*Math.PI)*R+x,Math.sin((18+i*72-rotaion)/180*Math.PI)*R+y)
           ctx.lineTo(Math.cos((54+i*72-rotaion)/180*Math.PI)*r+x,Math.sin((54+i*72-rotaion)/180*Math.PI)*r+y)
       }
       ctx.closePath()
       ctx.fillStyle="orange"
       ctx.fill()
   }

 window.onload=function(){
        var canvas=document.getElementById("canvas")
        canvas.width=400
        canvas.height=400
        var context=canvas.getContext("2d")
        context.lineWidth=2
        drawStar(context,100,200,200,200,0)

    }

效果:
這裡寫圖片描述
根據相同的原理,我們可以畫出不同的多邊形效果:
我們從割圓術的方法可以看出多邊形都是根據圓心的角度來確定座標,所以推出規律

var deg=2*Math.PI/lines //角度等於2pi/邊數
var x=Math.sin(i*deg);//橫座標
var y=-Math.cos(i*deg);//縱座標

然後我們就不難畫出多邊形效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自定義邊數和旋轉角度</title>
</head>
<body>
   <canvas id="slef_line" width="400" height="400" style="border: 1px #ccc solid;">你這渣渣瀏覽器居然不支援canvas</canvas>
   <script>
       window.onload =function(){
           var  canvas=document.getElementById("slef_line")
           var  context=canvas.getContext("2d")
           canvas.width=400
           canvas.height=400
           context.translate(200,200);//起始點移動到200,200位置
           drawMoreLine(context,6,80,80,20)
       }
/**
*  context,邊數,x方向長度,y方向長度,旋轉角度
*/
function drawMoreLine(context,lines,width,height,rotation){
          var deg=2*Math.PI/lines
          context.beginPath()
          for(var i=0;i<lines;i++){
              var x=Math.sin(i*deg-rotation);
              var y=-Math.cos(i*deg-rotation);
              context.lineTo(x*width,y*height);
          }
          context.closePath();
          context.fillStyle="green"
          context.fill()
          context.restore();
      }
      </script>
</body>
</html>

效果呢:
1.六邊形
這裡寫圖片描述
2.十二邊形

drawMoreLine(context,12,80,80,20)

這裡寫圖片描述
3.三角形

drawMoreLine(context,3,80,80,20)

這裡寫圖片描述

總結:

本篇主要使用canvas的畫線功能,然後之前呢也寫過Html5 的canvas使用,好久了,這一次記錄了一下容易出問題的地方,也是更加詳細的去介紹Html5 的Canvas標籤。