Canvas畫布學習

一、創建Canvas&繪製圖像

<canvas id="mycanvas"></canvas>
//html中創建一個canvas
var canvas=document.getElementVyId("mycanvas");
var ctx=canvas.getContext("2D");
//獲取canvas對象,獲取2d的繪製環境

1)繪製一條直線:lineTo(x,y)

moveTo(x,y)  //起始位置 ,移動的起始位置;
lineTo(x,y)     //終止位置
lineWidth      //線條的寬度
strokeStyle   //線條樣式,一般用於改變顏色
(以上四種操作是基於狀態的繪製圖形,必須使用stroke來進行實際的繪製)
stroke()         //繪製線條

2)繪製一新的圖形(開始全新的路徑):beginPath()

對於不同的路徑使用不同的樣式,修改的屬性值會被修改,不變的數據會被沿用;

3)繪製封閉的圖形:closePath()(與beginPath成對出現)

4)顏色填充:fillStyle 填充的顏色的狀態,fill() 進行顏色的實際填充;

5)rect(x,y,width,height);在x,y位置繪製指定大小的矩形;

save和restore可以保存和恢復canvas的圖形繪製環境;(保存上下文和恢復上下文)

繪製五角星函數推導如下圖所示:(繪製圖像只需要將10個頂點進行連接就行)

 通過transform進行簡單的圖形變換,transform有六個參數(每個參數的作用如下圖所示

transform具有級聯的作用最後一個應用的圖形將應用之前所有transform的圖形變化樣式,settransform可以解決此種問題; 

//星星的繪製路徑圖
	function PathStar(ctx){
		ctx.beginPath();//封閉路徑
		//初始位置就爲第一個lineto的位置
		for(var i=0;i<5;i++){
			ctx.lineTo(Math.cos((18+72*i)*Math.PI/180),
				-Math.sin((18+72*i)*Math.PI/180));
			ctx.lineTo(Math.cos((54+72*i)*Math.PI/180)/2,
				-Math.sin((54+72*i)*Math.PI/180)/2);
		}
		//標準的五角星路徑,外圓半徑爲1,內圓半徑爲1/2;
		ctx.closePath();//結束繪製路徑
	}

二、Canvas的常用API

1) fillStyle用於設置圖形樣式:(之後將newstyle賦值給fillStyle即可,strokeStyle用法與之類似)

	var newstyle=ctx.createLinearGradient(x0, y0, x1, y1);//起始和結束位置點
	newstyle.addColorStop(offset, color);//樣式顏色,offset爲起始和結束位置,範圍【0,1】

2)ctx.arc(x, y, r, startAngle, endAngle, anticlockwise)

x,y是指的圓心座標,r爲圓的半徑,startAngle和endAngle指的是起始和結束弧度,最後一個參數是代表旋轉方向;

3)貝塞爾曲線(二次):ctx.quadraticCurveTo(cpx, cpy, x, y);

二次貝塞爾曲線繪製(通過此網站可以快速生成曲線代碼以及形狀)
http://blogs.sitepointstatic.com/examples/tech/canvas-curves/quadratic-curve.html

4)貝塞爾曲線(三次):ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);

三次貝塞爾曲線的繪製樣式測試:(通過此網站可以快速生成曲線代碼以及形狀)
http://blogs.sitepointstatic.com/examples/tech/canvas-curves/bezier-curve.html

(注:三次貝塞爾曲線可以實現出花瓣的樣式)

5)清除矩形(畫布):一般用在canvas的動畫製作中,clearRect()

ctx.clearRect(x, y, w, h);
x,y矩形的起始位置,w和h指矩形的寬度

三、Finally 實戰

最後用canvas做一個貪吃蛇的小遊戲來檢驗自己的學習成果:(運行截圖如下)

遊戲代碼 (html貪吃蛇代碼,如果有什麼問題還請大家諒解)

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js "></script>
</head>
<body>
<div style="width:80%;margin:auto;background-color:#FFDEAD;">
<canvas id ="mycanvas" style="margin:auto; width:100%;" >
	/*canvas畫布*/
</canvas>
</div>
<script type="text/javascript">
	var canvas=document.getElementById("mycanvas");//獲取canvas對象
	var ctx=canvas.getContext("2d");//獲取繪製環境
	canvas.width=800;
	canvas.height=380;
	var down=0;
	var snack=[[20,20],[20,40],[20,60]];
	var foodx=80;
	var foody=80;
	var foodnum=1;
	var dirction=2;//0 1 2 3 默認向右
	checked=function(){
		if(snack[0][0]==foodx&&snack[0][1]==foody){
			snack.unshift([foodx,foody]);
			return 1;//獲取食物
		}
		else if(Find()==1){
			return 0;
		}
	}
	var timer=setInterval("Game()", 200) ;
	window.addEventListener('keydown', keydown,true);//鍵盤響應
	function Game(){
		ctx.fillStyle="red";
		ctx.clearRect(0, 0, 800, 380);//清除畫布
		if(checked()==1){//遊戲判斷
			showfood();
		}
		else if(checked()==0){
			clearInterval(timer);
			foody="";
			foodx="";
		}
		selfMove();//蛇自己移動
		ctx.fillRect(foodx,foody,20,20);//繪製食物
		showsnack();//繪製蛇
		down=0;
	}
	function selfMove(){
		if(dirction==0){
			if(snack[0][0]-20>=0)
			   snack.unshift([snack[0][0]-20,snack[0][1]]);
			else{
				snack.unshift([780,snack[0][1]]);
			}
		}
		else if(dirction==1){
			if(snack[0][1]-20>=0)
			snack.unshift([snack[0][0],snack[0][1]-20]);
		    else{
		    	snack.unshift([snack[0][0],360]);
		    }
		}
		else if(dirction==2){
			if(snack[0][0]+20<=800)
			snack.unshift([snack[0][0]+20,snack[0][1]]);
		    else{
		    	snack.unshift([0,snack[0][1]]);
		    }
		}
		else if(dirction==3){
			if(snack[0][1]+20<=360)
			snack.unshift([snack[0][0],snack[0][1]+20]);
		    else{
		    snack.unshift([snack[0][0],0]);
		    }
		}
		snack.pop();
	}
	function keydown(e){
		//left 37 up 38 right 39 down 40;
		if(e.keyCode==37&&dirction!=2){
			dirction=0;
		}
		if(e.keyCode==38&&dirction!=3){
			dirction=1;
		}
		if(e.keyCode==39&&dirction!=0){
			dirction=2;
		}
		if(e.keyCode==40&&dirction!=1){
			dirction=3;
		}//按鍵響應

	}
	function showsnack(){
		for(var i=0;i<snack.length;i++){
			ctx.fillStyle="green";
			ctx.fillRect(snack[i][0], snack[i][1], 20, 20);
		}
	}
	function showfood(){
			var x,y;
			x=Math.floor(Math.random()*29+1)*20;
			y=Math.floor(Math.random()*15+1)*20;
			foodx=x;
			foody=y;
	}
	function Find(){
		for(var i=1;i<snack.length;i++){
			if(snack[i][0]==snack[0][0]&&snack[i][1]==snack[0][1]){
				return 1;//遊戲結束
			}
		}
		return 0;//遊戲繼續
	}
</script>	
</body>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章