【學習筆記十】- 使用繪圖 《js高程》15 筆記

寫在前面:

這篇大部分內容是《js高程》第6-7章的代碼筆記,記在網上也是方便自己以後隨時隨地可以回看。

直接上代碼,詳見代碼註釋。

下面的代碼是在sublime text3上編輯運行過的。


<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Canvas</title>
</head>
<body>
	<canvas id="drawing" width="500" height="600">A drawing of sth.</canvas>
	<!--canvas默認寬300高150,不建議用css指定寬高-->

	<script type="text/javascript">
		var drawing=document.getElementById('drawing');
		if(drawing.getContext){

			var context=drawing.getContext("2d");//獲得渲染上下文的對象


			
			/*填充和描邊
			兩個屬性:fillStyle、strokeStyle
			值可以是字符串、漸變對象、模式對象,默認"#000000"
			context.strokeStyle='red';
			context.fillStyle='#0000ff';
			所有涉及描邊和填充的操作都將使用這兩個樣式*/


			
			/*繪製矩形*/
			
			//方法:fillRect()、strokeRect()、clearRect():都接受4個參數(x,y,寬,高)
			
			context.fillStyle='#ff0000';
			context.fillRect(0,0,50,50);

			context.fillStyle="rgba(0,0,255,0.5)";
			context.fillRect(25,25,50,50);

			context.strokeStyle='#ff0000';
			context.strokeRect(100,25,50,50);

			context.strokeStyle="rgba(0,0,255,0.5)";
			context.lineWidth=5;
			context.lineJoin="round";
			context.strokeRect(125,50,50,50);

			//描邊寬度由lineWidth控制,值爲任意整數
			//lineCap:"butt"、"round"、"square"控制線條末端形狀平頭、圓頭、方頭
			//lineJoin:"round"、"bevel"、"miter"控制線條相交方式圓交、斜交、斜接
			
			//clearRect()用於清除畫布上的矩形區域,本質上,把繪製上下文中的某一矩形區域變透明
			
			context.clearRect(30,30,15,15);



			/*繪製路徑*/

			//首先調用beginPath()方法表示要開始繪製新路徑
			//再調用下列方法來實際繪製路徑
			//繪製弧線,最後一個參數布爾值表示是否逆時針計算起始角度arc(x,y,r.startAngle,endAngle,counterclockwise)
			//從上一點開始繪製曲線到(x2,y2)爲止,給定半徑穿過(x1,y1)arcTo(x1,y1,x2,y2,r)
			//從上一點到(x,y),以(c1x,c1y)(c2x,c2y)爲控制點bezierCurveTo(c1x,c1y,c2x,c2y,x,y)
			//lineTo(x,y)
			//moveTo(x,y)將繪圖遊標移動,不畫線
			//從上一點開始繪製二次曲線,到(x,y),(cx,cy)爲控制點quadraticCurveTo(cx,cy,x,y)
			//矩形路徑,rect(x,y,width,height)
			//創建路徑後,若要連接到起點,調用closePath(),
			//如果路徑已完成,fill()填充,stroke()描邊,
			//可以調用clip()剪切區域

			//繪製一個不帶數字的時鐘表盤
			
			context.beginPath();
			
			//外圓
			context.arc(120,250,100,0,2*Math.PI,false);

			//內圓
			context.moveTo(215,250);
			context.arc(120,250,95,0,2*Math.PI,false);

			//分針
			context.moveTo(120,250);
			context.lineTo(120,165);

			//時針
			context.moveTo(120,250);
			context.lineTo(55,250);

			context.strokeStyle="black";
			context.lineWidth=1;
			context.stroke();

			//isPointInPath(x,y)方法用於在路徑被關閉之前確定畫布上某一點是否位於路徑上
			
			if(context.isPointInPath(120,250)){
				alert("Point (120,250) is in the path.");
			}



			/*繪製文本*/
			
			//fillText()、strokeText(),4個參數('string',x,y,width)
			//分別用fillStyle和strokeStyle屬性,更多使用fillText()
			//以3個屬性爲基礎:
			//font:樣式、大小、字體
			//textAlign:對齊方式"start""end""left""right""center"(建議"start""end")
			//textBaseline:文本基線"top""hanging""middle""alphabetic""ideographic""bottom"

			context.font="bold 14px Arial";
			context.textAlign="center";
			context.textBaseline="middle";
			context.fillStyle="black";
			context.fillText("12",120,165);

			//輔助確定文本大小的方法measureText(),接收要繪製的文本爲參數,返回一個TextMetrics對象,有一個width屬性
			


			/*變換*/

			//rotate(angle):圍繞原點旋轉圖像angle弧度
			//scale(scaleX,scaleY):縮放,在各自軸上乘以縮放倍數,默認1.0
			//translate(x,y):將原點移動到(x,y),此後(0,0)會變成之前的(x,y)
			//transform(m1_1,m1_2,m2_1,m2_2,dx,dy):修改變換矩陣,方式是乘以如下矩陣:
			/*m1_1 m1_2 dx
			  m2_1 m2_1 dy
			  0    0    1 */
			 //setTransform(m1_1,m1_2,m2_1,m2_2,dx,dy):將變換矩陣重置爲默認狀態,然後再調用transform()

			 context.beginPath();
			
			//外圓
			context.arc(350,100,99,0,2*Math.PI,false);

			//內圓
			context.moveTo(444,100);
			context.arc(350,100,94,0,2*Math.PI,false);

			//在變換原點與設置旋轉弧度之前保存環境
			context.save();

			//變換原點
			context.translate(350,100);

			//旋轉錶針
			//以弧度爲單位,360°角=2π弧度,1弧度=57.3°角,1°角=π/180弧度
			context.rotate(1);

			//分針
			context.moveTo(0,0);
			context.lineTo(0,-85);

			//時針
			context.moveTo(0,0);
			context.lineTo(-65,0);

			context.strokeStyle="black";
			context.lineWidth=1;
			context.stroke();



			/*
			save()、restore()可以跟蹤上下文的狀態變化,
			save保存設置到一個棧結構,restore恢復前一級保存的狀態
			 */
			context.restore();//回到變換原點與設置旋轉弧度之前

			context.translate(300,250);
			context.fillStyle="yellow";
			context.save();

			context.fillStyle="green";
			context.save();

			context.fillStyle="brown";
			context.fillRect(0,0,50,50);

			context.restore();//回到green
			context.fillRect(50,0,50,50);

			context.restore();//回到yellow
			context.fillRect(0,50,50,50);
			


			/*陰影*/

			//根據下面的屬性值,爲形狀或路徑繪製陰影
			//shadowColor:默認黑絲
			//shadowOffsetX:x軸陰影偏移量,默認0
			//shadowOffsetY:y軸陰影偏移量,默認0
			//shadowBlur:模糊像素,默認0,即不模糊

			context.translate(-300,-250);
			context.save();

			context.shadowOffsetX=5;
			context.shadowOffsetY=5;
			context.shadowBlur=4;
			context.shadowColor="rgba(0,0,0,0.5)";

			context.fillStyle='#00ff00';
			context.fillRect(0,400,50,50);

			context.fillStyle="rgba(0,0,255,0.5)";
			context.fillRect(25,425,50,50);



			/*漸變*/

			//漸變由CanvasGradient實例表示,通過createLinearGradient()方法創建一個新的線性漸變,四個參數(x1,y1,x2,y2)
			//用addColorStop()指定色標,兩個參數(0-1之間的色標位置,顏色值)
			
			var gradient1=context.createLinearGradient(100,400,140,440);
			gradient1.addColorStop(0,"white");
			gradient1.addColorStop(1,"brown");

			context.fillStyle=gradient1;
			context.fillRect(100,400,80,80);

			//徑向漸變(放射漸變),用createRadialGradient()
			//6個參數(起始兩個圓的圓心和半徑)

			context.shadowOffsetX=0;
			context.shadowOffsetY=0;	

			var gradient2=context.createRadialGradient(250,450,0,250,450,50);
			gradient2.addColorStop(0,"white");
			gradient2.addColorStop(1,"grey");

			context.fillStyle=gradient2;
			context.fillRect(200,400,100,100);



			/*
			使用toDataURL()可以導出在<canvas>上繪製的圖像,
			默認PNG,
			Firefox和Opera支持基於"image/jpeg"的JPEG格式,IE9+、Firefox3.5、Opera10,
			toDataURL()是Canvas對象的方法,不是上下文對象的方法。
			
			var imgURI=drawing.doDataURL("image/png");//取得圖像數據的URI
			var image=document.createElement("img");
			image.src=imgURI;
			document.body.appendChild(image);	*/



			/*繪製圖像

			drawImage()方法,三種不同的參數組合:
			
			var image=document.images[0];
			1、
			context.drawImage(image,10,10);
			傳入一個html<img>元素,和起始位置
			2、
			context.drawImage(image,10,10,50,100);
			後兩個參數設置寬高
			3、
			context.drawImage(image,0,0,100,100,0,400,100,100);
			把圖像的0,0,100,100的區域,畫到上下文的0,400的位置,大小爲100,100
			
			也可以傳入另一個<canvas>	*/
			


			/*模式
			
			模式其實就是重複的圖像,可用於填充或描邊。
			createPattern(),兩個參數(image,"repeat"/"repeat-x"/"repeat-y"/"no-repeat")
			第一個參數可以是<video><canvas>

			var image=document.images[0],
				pattern=context.createPattern(image,"repeat");
			context.fillStyle=pattern;
			context.fillRect(0,0,100,100);

			注意:將填充樣式設爲模式對象,只表示在某個區域內顯示重複的圖像,不是要從某個位置開始繪製重複的圖像。
			 */
			


			/*使用圖像數據
			
			通過getImageData(x,y,width,height)取得原始圖像數據,
			返回一個ImageData實例,有三個屬性:width、height、data,
			其中data是一個數組,保存每個像素的數據,
			每一個像素用4個元素來保存,分別是r、g、b、a,每個值在[0,255]之間
			
			創建一個簡單的灰階過濾器

			 var imageData,data,i,len,average,red,green,blue,alpha;
			 context.drawImage(image,0,0);
			 imageData=context.getImageData(0,0,image.width,image.height);
			 data=imageData.data;

			 for (i = 0,len=data.length; i < len; i+=4) {
			 	red=data[i];
			 	green=data[i+1];
			 	blue=data[i+2];
			 	alpha=data[i+3];

			 	average=Math.floor((red+green+blue)/3);

			 	data[i]=average;
			 	data[i+1]=average;
			 	data[i+2]=average;
			 	//透明度不變
			 }

			 imageData.data=data;
			 context.putImageData(imageData,0,0);
			 */
			


			/*合成
			
			2D上下文的另兩個屬性:globalAlpha、globalCompositionOperation
			globalAlpha:[0,1]之間,指定所有繪製的透明度
			globalCompositionOperation:表示後繪製的圖形怎樣與先繪製的結合
			*/

		}
	</script>
</body>
</html>

再插一個之前看網易微專業前端開發視頻課程的筆記,忽略醜字......



PS:

emmmm......

有沒有人能告訴我怎麼把圖縮小......


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