標籤:style blog http java color strong
Canvas元素稱得上是HTML5的核心所在,它是一個依靠JavaScript繪製華麗映像的元素。
Canvas由一個可繪製地區HTML代碼中的屬性定義決定高度和寬度,JavaScript代碼可以訪問該地區,通過一套完整的繪圖功能類似於其他通用二維的API,從而產生動態圖形。
Canvas可以在瀏覽器中繪製出十分華麗的圖形,比如:
當然這應該算比較進階的用法了,本菜也不會=.=
Canvas一個很大的作用就是製作遊戲,本文通過博主之前做的一個小遊戲來從零介紹Canvas的用法,先展示下吧:
OK,這就是用Canvas來完成的遊戲。
繪製之前的準備工作:
1.在body中加入canvas標籤,設定它的id、width、height,當然也可以動態設定它的寬高。
<canvas id="mycanvas" width="1200" height="500"></canvas>
2.獲得canvas對象的上下文obj.getContext(par),par參數為“2d”,目前canvas只支援二維效果。
var ctx = document.getElementById("mycanvas").getContext("2d");
如此你便有了一張1200*500的“畫布”和一支名為“ctx”的畫筆,接下來我們從一些最簡單的圖形開始繪製。
繪製矩形:
範例程式碼如下:
var ctx=document.getElementById("container").getContext("2d"); ctx.fillStyle="blue"; ctx.fillRect(10,10,200,100); ctx.lineWidth=10; ctx.strokeStyle="red"; ctx.strokeRect(300,10,200,100);
其中fill表示填充,stroke表示僅繪製邊框。
同理fillRect表示實心矩形,strokeRect表示矩形邊框,他們都有四個參數:x,y,w,h 分別為橫縱座標、寬、高。
fillStyle表示填充樣式,strokeStyle表示邊框樣式。
lineWidth表示線寬。
顯示結果:
需要注意的是,設定樣式等應寫在繪製圖形之前,否則樣式會渲染不上。
在繪製多個圖形時,應該在繪製一個圖形之前開繪製路徑,定製完成後關閉繪製路徑並繪製定製好的圖形。例如上例標準寫法應為:
var ctx=document.getElementById("container").getContext("2d"); ctx.beginPath(); ctx.fillStyle="blue"; ctx.fillRect(10,10,200,100); ctx.closePath(); ctx.stroke(); ctx.beginPath(); ctx.lineWidth=10; ctx.strokeStyle="red"; ctx.strokeRect(300,10,200,100); ctx.closePath(); ctx.stroke();
beginPath()開啟繪製路徑,closePath()閉合繪製路徑,stroke()繪製定製圖形。在之後的練習中一定要養成習慣,否則當繪製線條時就會發現由於未閉合繪製路徑所出現的線條錯連。
繪製線條:
範例程式碼如下:
var ctx=document.getElementById("container").getContext("2d"); ctx.beginPath(); ctx.moveTo(400,100); ctx.lineTo(300,200); ctx.lineTo(350,200); ctx.lineTo(250,300); ctx.lineTo(400,300); ctx.closePath(); ctx.stroke();
其中,moveTo表示將畫筆移動到某個座標上,lineTo指以畫筆落點開始畫到哪個位置。本次我們想要畫一個簡單的樹冠,結果:
可見,這裡我們只畫了一半。(400,100)位置為樹頂,(400,300)位置為樹底中部,線條自動閉合正是我們關閉繪製路徑所產生的效果。
接下來我們把另一半畫完,並給這棵樹填充上綠色:
var ctx=document.getElementById("container").getContext("2d"); ctx.beginPath(); ctx.fillStyle="green"; ctx.moveTo(400,100); ctx.lineTo(300,200); ctx.lineTo(350,200); ctx.lineTo(250,300); ctx.lineTo(400,300); ctx.lineTo(550,300); ctx.lineTo(450,200); ctx.lineTo(500,200); ctx.lineTo(400,100); ctx.fill(); ctx.closePath(); ctx.stroke();
注意寫在最後的fill()為填充樣式:
繪製圓形:
範例程式碼:
var ctx=document.getElementById("container").getContext("2d"); ctx.beginPath(); ctx.arc(200,200,100,0,360*Math.PI/180,true); ctx.closePath(); ctx.stroke();
arc(x,y,r,starta,enda,anti);參數分別代表:圓心橫、縱座標,半徑、起始角(需轉換成弧度值)、終止角、繪製方向。
用canvas繪製圓,如果你是剛接觸一定覺得很糾結,因為它的參數有很多都是相反的。這裡為了大家不糾結,我多羅嗦幾句。
起、止角的計算與我們數學上的角度計算不同,數學中的角度逆時針為正,而這裡的起止角是以順時針為正,也就是當你起角設為0度,止角設為120度。它是從右邊水平位置向下旋轉計算角度。
還有就是繪製方向上,true代表逆時針,false代表順時針。暈了的同學看下面的例子:
ctx.arc(200,200,100,0,120*Math.PI/180,true);
設起角為0,止角120。按數學上的思想應該是一個小於半圓的上半邊的弧,而結果:
這裡true表示逆時針繪製,所以繪出了的圖形大於半圓。若改為false:
此時順時針繪製出的圖形小於半圓,這裡大家應該也可以理解arc的角度計算方向是與數學相反的。要想畫一個位於上方的小半圓?止角設為-120度,繪製方向true即可。
這裡羅嗦這麼多就是希望剛接觸的朋友們少走彎路,不像我們研究半天。
繪製陰影:
var ctx=document.getElementById("container").getContext("2d"); ctx.beginPath(); ctx.fillStyle="gray"; ctx.shadowOffsetX=5; ctx.shadowOffsetY=5; ctx.shadowColor="gold"; ctx.shadowBlur=5; ctx.fillRect(10,10,100,100); ctx.closePath(); ctx.stroke();
shadowOffsetX、shadowOffsetY表示陰影橫、縱向位移量,shadowColor表示陰影顏色,shadowBlur表示模糊等級。
由於在之前CSS3相關博文中已經講了不少關於陰影的東西了,這裡就一筆帶過。依然需要注意的是,先設定樣式,最後再繪製矩形,順序反了效果會渲染不上。
繪製漸層:
線性漸層:
ctx.beginPath(); var Color=ctx.createLinearGradient(500,500,500,0); Color.addColorStop(0.3,"orange"); Color.addColorStop(0.5,"yellow"); Color.addColorStop(1,"gray"); ctx.fillStyle=Color; ctx.fillRect(0,0,1200,500); ctx.closePath(); ctx.stroke();
寫法為:將ctx.createLinearGradient()賦值給一顏色變數,顏色變數可以添加多個漸層顏色,addColorStop其共有兩個參數,1.位移量(0-1)2.顏色。最後將顏色變數賦給fillStyle。
createLinearGradient()共有四個參數:1、2表示起始面,3、4表示終於面。
放射狀漸層:
ctx.beginPath(); ctx.arc(500,300,100,0,360*Math.PI/180,true); var Color=ctx.createRadialGradient(500,300,30,500,300,100); Color.addColorStop(0,"red"); Color.addColorStop(0.5,"orange"); Color.addColorStop(1,"yellow"); ctx.fillStyle=Color; ctx.fill(); ctx.closePath(); ctx.stroke();
與線性漸層比較相似,不同的是其名為createRadialGradient()中有六個參數:1、2.漸層開始圓的圓心座標,3.漸層開始圓的半徑,4、5.漸層結束圓的圓心座標,6.漸層結束圓的半徑。
繪製文字:
ctx.beginPath();ctx.strokeStyle="gold";ctx.fillStyle="bule";ctx.font="50px 微軟雅黑";ctx.strokeText("hello world!",700,200);ctx.font="30px 幼圓";ctx.fillText("hello kitty?",700,300);ctx.fill();ctx.closePath();ctx.stroke();fillText(text,x,y,[maxwidth])繪製字串,text表示文字內容,x,y文字座標位置。[maxwidth]可選,設定字元最大寬大防止溢出。font設定字型。其它參數:textAlign 設定文字水平對齊 value 為 start|end|left|right|center 預設值為starttextBaseline 設定文字垂直對齊 value 為 top|hanging|middle|alphabetic|ideographic|bootom 預設為alphabetic大家有興趣自己試試吧。
圖片繪製:呼.....寫了半天終於寫到正題了,相對於上面簡單圖形的繪製,圖片繪製要用的更多一些,尤其是在遊戲中。這裡介紹一種較簡單的方法,首先在body中寫上:
<div class="hide"> <img src="" id="myImg"> </div>
將你想要繪製的圖片先加入body中,然後將父級div隱藏,一個隱藏的div中可以放入一個項目中所有需要繪製的圖片甚至是音頻檔案,就好像一個別人看不見的素材庫。
然後:
var ctx = document.getElementById("mycanvas").getContext("2d"); var img=document.getElementById("myImg"); ctx.beginPath(); ctx.drawImage(img,x,y); ctx.closePath(); ctx.stroke();
得到你想要繪製的圖片對象,通過drawImage來繪製。這裡drawImage()可以有3個參數,5個參數,9個參數。
3個參數:1.需要繪製的圖片對象 2,3.圖片座標;
5個參數:1.需要繪製的圖片對象 2,3.圖片座標 4,5.圖片寬高;
9個參數:1.需要繪製的圖片對象 2,3.繪製圖片的橫縱向切割點 4.橫向切割寬度 5.縱向切割高度 6,7.切割好的圖片座標 8,9.切割好的圖片寬高。
前兩個比較好理解,第三種參數模式怎麼用呢?這裡舉個例子:在最開始展示的遊戲中,會走路的怪物並不是gif,而是如下的背景透明的PNG格式:
我們通過一定的時間間隔截取圖片中不同的地區,連貫起來就成了動畫的效果了。說起切割圖片,學過Web效能最佳化的人很容易想起 Spirite,它就是通過把一網頁上的所需的圖片全部彙集到一張圖上,用哪部分就截取哪部分。
扯遠了,現在我們試著讓這種綠怪物走起來:
var ctx=document.getElementById("container").getContext("2d"); var img=document.getElementById("myImg"); var X=0; var countNum=0; function picRun(){ ctx.clearRect(0,0,1200,1000); countNum++; if(countNum==10){ X+=129; countNum=0; } if(X>=387){ X=0; } ctx.beginPath(); ctx.drawImage(img,X,0,129,135,100,100,129,135); ctx.closePath(); ctx.stroke(); } window.setInterval(picRun,30);
*** 首先加入圖片,擷取圖片對象。分析下怪物走路那張圖片,寬為515px,高為135px,也就是說每個單獨的怪物寬為四分之一即129px,高為135px。
將橫向切割點設為變數X,由於此圖只需橫切不需要縱切,縱向切割點設為常量,實際上做法一樣。
在drawImage中填入參數,就本例而言只有橫向切割點一個變數。通過setInterval來迴圈執行picRun函數,每30毫秒執行一次。countNum俗稱計數器,在做遊戲中比較常見,目的是為了控製圖片的切換頻率。
(由於一個遊戲中通常有多個動作頻率不同的對象,所以當然不能隨便改變setInterval的執行頻率。加入了計數器,就能很好的控制各個對象的動作頻率了)
本例中圖片切換頻率為30*10即300毫秒一次,切換時橫向切割點右移135px即怪物寬度,當橫向切割點大於3個怪物寬度時回0座標重新切割。
clearRect()是為了清除之前的圖層,始終只顯示一張圖片,否則每次切出的新圖會不停疊加。
結果:
本文到此結束,下篇介紹HTML另一核心工具——本機存放區,敬請期待。