- HTML5的canvas元素使用JavaScript畫圖;
<canvas width="600" height="400"> </canvas>
canvas畫圖的基本框架
- 畫布預設背景顏色為白色,大小為300*150;
- 若要設定畫布大小,不建議在style的樣式設定尺寸,效果相當於將原本300*150的畫布等比例放大縮小,包括裡面畫的圖;
- 建議在元素本身設定;
<body>
<!-- 準備畫布 -->
<canvas width="600" height="400"></canvas>
<!-- 準備繪製工具 -->
<!-- 利用工具繪圖 -->
<script>
// 獲取元素
var myCanvas=document.querySelector('canvas');
// 獲取上下文,繪製工具箱
var ctx=myCanvas.getContext('2d');
// 移動畫筆
ctx.moveTo(100,100);
// 繪製直線(軌跡,繪製路徑)
ctx.lineTo(200,100);
// 描邊
ctx.stroke();
</script>
</body>
關於線條的問題
- 預設寬度為1px
- 預設顏色黑色
- 但是顯示是灰色,2px寬度,原因是對其點是線的中心位置,會把線分成兩個0.5px,顯示的會是不飽和增加寬度;
- 解決方法:前或後移動0.5px即可;
- 當要畫多條不同樣式的平行線時,存在樣式覆蓋問題,需要開闢新路徑;
<body>
<canvas width="600" height="400"></canvas>
<script>
var myCanvas=document.querySelector("canvas");
var ctx=myCanvas.getContext("2d");
// 畫平行線
// 藍色 10px
ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.strokeStyle="blue";
ctx.lineWidth=10;
ctx.stroke();
// 紅色 20px
ctx.beginPath();//開闢新路徑
ctx.moveTo(100,200);
ctx.lineTo(200,200);
ctx.strokeStyle="red";
ctx.lineWidth=20;
ctx.stroke();
// 綠色 30px
ctx.beginPath();//開闢新路徑
ctx.moveTo(100,300);
ctx.lineTo(200,300);
ctx.strokeStyle="green";
ctx.lineWidth=30;
ctx.stroke();
</script>
</body>
- 當繪製圖形,需要填充顏色時,使用fill()函式;預設填充顏色為黑色;
<body>
<canvas width="600" height="400"></canvas>
<script>
var myCanvas = document.querySelector("canvas");
var ctx = myCanvas.getContext("2d");
// 繪製一個三角形
ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.lineTo(200,200);
ctx.lineTo(100,100);
// 描邊
ctx.stroke();
// 填充
ctx.fill();
</script>
</body>
- 當繪製封閉圖形時,會出現起始點和lineTo的結束點無法完全閉合,有缺角
- 解決方法:使用canvas的自動閉合路徑closePath();
<canvas width="600" height="400"></canvas>
<script>
var myCanvas = document.querySelector("canvas");
var ctx = myCanvas.getContext("2d");
// 繪製一個三角形
ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.lineTo(200,200);
// 起始點和lineTo的結束點無法完全閉合,有缺角;
// ctx.lineTo(100,100);
// 使用canvas自動閉合
ctx.closePath();
ctx.lineWidth=10;
// 描邊
ctx.stroke();
</script>
填充規則(非零環繞)
- 看一塊區域是否被填充,從區域畫一條直線,看和這條直線相交的軌跡;
- 如果是順時針就+1,逆時針就-1;
- 計算所有軌跡的和,如果非0就填充,是0就不填充;
- 如上圖1區域:軌跡和為1,填充;2區域:軌跡和為2,填充;3區域:軌跡和為0,不填充;
畫虛線
<script>
var myCanvas = document.querySelector("canvas");
var ctx = myCanvas.getContext("2d");
// 畫線
ctx.moveTo(100.5, 100.5);
ctx.lineTo(300, 100.5);
ctx.setLineDash([5,10,15]);
ctx.stroke();
</script>
- 畫虛線:通過陣列描述虛線的排列方式;
- 獲取虛線的排列方式,獲取的是不重複的那一段的排列方式;
- 例如:console.log(ctx.setLineDash());獲取的是5 10 15 5 10 15;
- 括號裡數字為[數字長度,空格長度,數字長度,空格長度…];
畫漸變矩形(例如黑白漸變)
- 主要利用for迴圈,逐漸改變線條顏色,矩形通過多個線條拼湊;
<body>
<canvas width="600" height="400"></canvas>
<script>
var myCanvas = document.querySelector("canvas");
var ctx = myCanvas.getContext("2d");
// 繪製一個矩形
// ctx.moveTo(100, 100);
// ctx.lineTo(255,100);
// ctx.lineWidth='30';
// // 顏色填充
// ctx.strokeStyle='#fff';
// // 從黑到白
// ctx.stroke();
// 線是由點構成的
ctx.lineWidth = '30';
//起始位置
// ctx.moveTo(100, 100);
for (var i = 0; i < 255; i++) {
//畫255條1px長的線;
//每次開闢一條新路徑,不然會樣式覆蓋
ctx.beginPath();
//起始位置
ctx.moveTo(100 + i - 1, 100);
//結束位置
ctx.lineTo(100 + i, 100);
ctx.strokeStyle = 'rgb(' + i + ',' + i + ',' + i + ')';
//描邊
ctx.stroke();
}
</script>
</body>
網格、座標系、點的繪製
- 網格即多條線按一定的規則排列組成;
- 座標系繪製兩條相互垂直的有向線段,箭頭自己計算畫三角形,進行填充即可;
- 點的繪製
- 需要注意的是,點的座標要先定下來,用物件儲存
- 點的繪製就是以點的座標為中心,繪製一個正方形,進行填充,點的大小可以控制;
<body>
<canvas width="600" height="400"></canvas>
<script>
var myCanvas = document.querySelector('canvas');
var ctx = myCanvas.getContext('2d');
//繪製點
//點的尺寸
//以座標中心繪製點
//點座標
var coordinate = {
x: 146,
y: 357
}
//點尺寸
var dottedSize = 6;
ctx.moveTo(coordinate.x - dottedSize / 2, coordinate.y - dottedSize / 2);
ctx.lineTo(coordinate.x + dottedSize / 2, coordinate.y - dottedSize / 2);
ctx.lineTo(coordinate.x + dottedSize / 2, coordinate.y + dottedSize / 2);
ctx.lineTo(coordinate.x - dottedSize / 2, coordinate.y + dottedSize / 2);
ctx.closePath();
ctx.fill();
</script>
</body>
圖形繪製
- 引數(x,y)為座標,(w,h)為寬高;
弧度繪製
- 什麼是弧度?
- 一種長度的描述單位,一個圓有2Π個弧度,一個角度等於Π/180弧度
<body>
<canvas width="600" height="400"></canvas>
<script>
var myCanvas = document.querySelector('canvas');
var ctx = myCanvas.getContext('2d');
//繪製圓弧
//1.確定圓心
//2.確定圓的半徑
//3.確定起始位置和結束位置,確定圓弧長度和位置
//4.確定繪製方向(一般是預設的順時針)direction
var w=ctx.canvas.width;
var h=ctx.canvas.height;
//在中心位置畫一個半徑150px的圓弧右下角(橫座標,縱座標,半徑,起始角度,結束角度)
ctx.arc(w/2,h/2,150,0,Math.PI/2);
ctx.stroke();
</script>
</body>
- 繪製扇形時,圓心的確定要放在畫弧形的前面;
繪製文字
- ctx.font='微軟雅黑’設定字型;
- strokeText(text,x,y,maxWidth);
- fillText(text,x,y,maxWidth);
- text即要繪製的文字;
- x,y為文字繪製的座標(文字左下角);
- maxWidth設定文字的最大寬度,可選引數;
- ctx.textAlign文字水平對齊方式,相對繪製座標來說;
- 可取值有 left center right start預設 end
- ctx.direction屬性css(rtl ltr)start和end與此相關;
- 若為ltr則start和left表現一致;
- 若為rtl則start和right表現一致;
- ctx.textBaseline設定基線(垂直對齊方式);
- top文字的基線處於文字的正上方,並且有一段距離;
- middle文字的基線處於文字的正中間
- bottom文字的基線處於文字的正下方,並且有一段距離;
- hanging文字的基線處於文字的正上方,並且與文字粘合;
- alphabetic預設值,文字的基線處於文字的正下方,並且穿過文字;
- ideographic和bottom相似,但是不一樣;
- measureText()獲取文字的寬度obj.width;
- 注意
- 文字樣式設定要在文字描邊或者填充之前;
- 左右對齊方式的對齊基準是文字描繪的起始座標;
圖片繪製
- drawImage()
- 三個引數drawImage( image, x , y);
- img圖片物件、canvas物件、video物件
- x,y影像繪製的左上角
- 五個引數drawImage( image, x , y , w, h);
- w,h分別為圖形的寬高設定,是縮放,不是擷取,其餘引數意義同上;
- 九個引數drawImage( image, x , y , w , h, x1, y1 ,w1, h1);
- image是圖片物件,x,y是圖片定位的座標(即原圖片上圖片從哪開始擷取),w,h是在原圖片上的圖片擷取區域大小,x1,y1是繪製在畫布上的座標,w1,h1是繪製圖片的大小,繪製的圖片不是裁剪而是前面擷取圖片的縮放
canvas的2d轉換
- 移動, translate(x,y);移動的是座標軸,不是繪製的內容
- 縮放,scale(0.5,1),表示橫座標縮放0.5倍,縱座標縮放1倍,縮放的是座標軸,不是繪製的內容
- 旋轉,rotate(),旋轉中心預設是座標原點;