1、Canvas基礎
1) canvas類似于img標簽(行內塊),但是不能在css里設置寬高。
它使用自身的width和height屬性。但可以用css寫其它東西
2) 頁面中引入Canvas的方法
<canvas id="canvas" width="500" height="500">
您的瀏覽器不支持canvas,請升級最新版
</canvas>
3) 基本的canvas的操作方法
1> 獲取元素 var canvas = document.getElementById("canvas");
2> 獲取上下文對象(畫筆) var ctx = canvas.getContext("2d");
console.log(ctx);//CanvasRenderingContext2D對象
3> 基本的繪制步驟
1.開始繪制 ctx.beginPath();
2.繪制起點 ,通常只寫一次 ctx.moveTo(x,y);
3.繪制后續的點 ,可寫多次 ctx.lineTo(x,y);
4.結束繪制/關閉路徑,會把終點 和 起點 鏈接起來,進行繪制
當需要終點 和 起點鏈接起來的時候才使用,需要才寫
ctx.closePath();
5.畫(填) 先設置 后畫 填充 注意先后順序
繪制的線和填充的內容會發生覆蓋的情況,沒有優先級,
由代碼的書寫順序絕對(后面的會覆蓋前面的設置)
ctx.stroke();//畫
ctx.fill();//填 如果填的時候,沒有ctx.closePath() 則會由起點填充到終點
2、Canvas畫直線
1)填充
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(400,400);
ctx.lineTo(100,400);
ctx.closePath();
ctx.fillStyle = "green";//換填充的顏色
ctx.globalAlpha = 0.5; //全局透明度
ctx.fill();
2)描邊
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(400,400);
ctx.closePath();
ctx.strokeStyle = "red" //設置畫線顏色
ctx.lineWidth = 10; //設置線寬 里外同時擴散
ctx.stroke();//畫
3)其它屬性
ctx.lineWidth 線寬
lineCap = "round"; 線末尾的形狀 不需要ctx.closePath()
lineJoin = "round"; 兩條邊交匯時,創建圓角邊,需要ctx.closePath()
3、Canvas畫矩形
1)畫矩形:
fillRect(x,y,width,height) 按照矩形填充
strokeRect(x,y,width,height) 按照矩形畫線
2)示例:
//矩形
// ctx.beginPath();
// ctx.strokeStyle = "blue";
// ctx.strokeRect(0,400,100,50);
// ctx.stroke();
//正方形
// ctx.beginPath();
// ctx.fillStyle = "pink";
// ctx.fillRect(0,0,100,100);
// ctx.fill();
//畫多個圖形
// for(var i = 0; i < 500; i+=10){
// var x = 10,y = 10,w=50,h=50;
// ctx.strokeStyle = randomColor();
// ctx.strokeRect(x+i,y+i,w,h);
// }
4、Canvas畫文字
1)畫文字
空心 ctx.strokeText(text,x,y,maxWidth?);
實心 ctx.fillText(text,x,y,maxWidth?);
參數1:要顯示的文本信息
參數2,3文字在畫布上顯示的位置
參數4:可選參數,設置文本的最大顯示寬度,文本不會超出該寬度
2)文字的對齊方式
ctx.textAlign("left/center/right"); 水平方向
ctx.textBaseline("top/middle/bottom/baseline"); 垂直方向
3)字體大小和樣式
ctx.font = "50px 宋體";
5、Canvas畫圓
1)繪制圓形 ctx.arc(x,y,r,start,end,dir);
//參數1:圓心的x
//參數2:圓心的y
//參數3:圓的半徑
//參數4:起始點的位置,根據右側和設置的弧度找到起點
//參數5:終點的位置,根據右側和設置的弧度找到終點
//參數6:繪制的方向 true代表逆時針,false代表順時針
2)繪制同心圓 半徑由大到小 讓小得覆蓋大的
for(var i = 250; i > 20; i-=20){
ctx.beginPath();
ctx.strokeStyle = randomColor();
// ctx.fillStyle = randomColor();
ctx.arc(250,250,i,0,Math.PI*2,false);
ctx.stroke();
// ctx.fill();
}
3)繪制笑臉的幾種方法
1>一般常規畫法
ctx.arc(250,250,200,0,Math.PI*2,false);
ctx.stroke();
ctx.beginPath();
ctx.arc(200,200,30,0,Math.PI*2,false);
ctx.stroke();
ctx.beginPath();
ctx.arc(300,200,30,0,Math.PI*2,false);
ctx.stroke();
ctx.beginPath();
ctx.arc(250,270,100,0,Math.PI,false);
ctx.closePath();
ctx.stroke();
2>封裝函數思想
function draw(x,y,r,start,end,dir){
ctx.beginPath();
ctx.arc(x,y,r,start,end,dir);
ctx.closePath();
ctx.stroke();
}
//調用函數
draw(250,250,200,0,Math.PI*2,false);
draw(200,200,30,0,Math.PI*2,false);
draw(300,200,30,0,Math.PI*2,false);
draw(250,270,100,0,Math.PI,false);
3>面向對象思想 初級 和封裝函數沒什么不同
var smileArr = [
{x:250,y:250,r:200,end:Math.PI*2},
{x:200,y:200,r:30,end:Math.PI*2},
{x:300,y:200,r:30,end:Math.PI*2},
{x:250,y:270,r:100,end:Math.PI}
];
for(var i = 0; i < smileArr.length; i++){
ctx.beginPath();
ctx.arc(smileArr[i].x,smileArr[i].y,smileArr[i].r,0,smileArr[i].end,false);
ctx.closePath();
ctx.stroke();
}
4>面向對象思想 中級
function Area(x,y,r,start,end,dir){
this.x=x;
this.y=y;
this.r=r;
this.start=start;
this.end=end;
this.dir=dir;
}
//添加原型方法
Area.prototype.draw = function(){
ctx.beginPath();
ctx.arc(this.x,this.y,this.r,this.start,this.end,this.dir);
ctx.closePath();
ctx.stroke();
}
//創建實例化對象
var bigCircle = new Area(250,250,200,0,Math.PI*2,false);
var leftEyes = new Area(200,200,30,0,Math.PI*2,false);
var rightEyes = new Area(300,200,30,0,Math.PI*2,false);
var mouth = new Area(250,270,100,0,Math.PI,false);
//調用原型的方法
bigCircle.draw();
leftEyes.draw();
rightEyes.draw();
mouth.draw();
5>面向對象思想 高級
function Area(x,y,r,start,end,dir){
this.x=x;
this.y=y;
this.r=r;
this.start=start;
this.end=end;
this.dir=dir;
}
Area.prototype.draw = function(){
ctx.beginPath();
ctx.arc(this.x,this.y,this.r,this.start,this.end,this.dir);
ctx.closePath();
ctx.stroke();
}
// 數據
var smileArr = [
{x:250,y:250,r:200,end:Math.PI*2},
{x:200,y:200,r:30,end:Math.PI*2},
{x:300,y:200,r:30,end:Math.PI*2},
{x:250,y:270,r:100,end:Math.PI}
];
for(var item of smileArr){
var obj = new Area(item.x,item.y,item.r,0,item.end,false);
obj.draw();
}
6、Canvas畫曲線
1)畫曲線
ctx.quadraticCurveTo(x2,y2,x3,y3);//二次貝塞爾曲線 一對基準點 一對終點
ctx.bezierCurveTo(x2,y2,x3,y3,x4,y4);//三次貝塞爾曲線 兩對基準點 一對終點
2)示例
1> 二次貝塞爾曲線
ctx.moveTo(0,0);//繪制起點
ctx.quadraticCurveTo(250,500,500,0);
ctx.stroke();
ctx.moveTo(0,0);//繪制起點
ctx.quadraticCurveTo(500,250,0,500);
ctx.stroke();
ctx.moveTo(0,500);
ctx.quadraticCurveTo(250,0,500,500);
ctx.stroke();
// ctx.beginPath();
ctx.moveTo(500,0);
ctx.quadraticCurveTo(0,250,500,500);
ctx.stroke();
// ctx.fill();
2> 三次貝塞爾曲線
ctx.beginPath();
ctx.strokeStyle="orange";
ctx.moveTo(0,0);//繪制起點
ctx.bezierCurveTo(500,0,0,500,500,500);
ctx.stroke();
//這里上下兩條線是重合的
// ctx.beginPath();
// ctx.strokeStyle="purple";
// ctx.moveTo(500,500);//繪制起點
// ctx.bezierCurveTo(0,500,500,0,0,0);
// ctx.stroke();
//----------------------------------------
ctx.beginPath();
ctx.strokeStyle="red";
ctx.moveTo(500,0);//繪制起點
ctx.bezierCurveTo(0,0,500,500,0,500);
ctx.stroke();
//這里上下兩條線是重合的
// ctx.beginPath();
// ctx.strokeStyle="hotpink";
// ctx.moveTo(0,500);//繪制起點
// ctx.bezierCurveTo(500,500,0,0,500,0);
// ctx.stroke();
//--------------------------------
ctx.beginPath();
ctx.strokeStyle="green";
ctx.moveTo(0,500);//繪制起點
ctx.bezierCurveTo(0,0,500,500,500,0);
ctx.stroke();
//這里上下兩條線是重合的
// ctx.beginPath();
// ctx.strokeStyle="pink";
// ctx.moveTo(500,0);//繪制起點
// ctx.bezierCurveTo(500,500,0,0,0,500);
// ctx.stroke();
//--------------------------------
ctx.beginPath();
ctx.strokeStyle="blue";
ctx.moveTo(500,500);//繪制起點
ctx.bezierCurveTo(500,0,0,500,0,0);
ctx.stroke();
//這里上下兩條線是重合的
// ctx.beginPath();
// ctx.strokeStyle="red";
// ctx.moveTo(0,0);//繪制起點
// ctx.bezierCurveTo(0,500,500,0,500,500);
// ctx.stroke();
3)用二次貝塞爾曲線可以大致實現三次貝塞爾曲線的效果
例如:
//三次
ctx.beginPath();
ctx.strokeStyle="pink";
ctx.moveTo(500,0);//繪制起點
ctx.bezierCurveTo(500,500,0,0,0,500);
ctx.stroke();
//二次
ctx.moveTo(500,0);
ctx.quadraticCurveTo(500,250,250,250);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(250,250);
ctx.quadraticCurveTo(0,250,0,500);
ctx.stroke();
4)利用Canvas曲線的畫法,可以畫出肯定不合常規的圖形
例如:心、不規則三角形、太極等
//畫心
ctx.fillStyle="red";
ctx.moveTo(250,200);
ctx.quadraticCurveTo(0,50,250,450);
ctx.fill();
ctx.beginPath();
ctx.moveTo(250,200);
ctx.quadraticCurveTo(500,50,250,450);
ctx.fill();
7、Canvas畫圖片
1)畫圖片 ctx.drawImage(img,x,y,w,h,dx,dy,dw,dh);
img為要畫的圖片
img后緊鄰的四個值是在canvas中的位置,以及顯示圖片的寬高
最后面四個值是尋找的圖片中具體想顯示的區域
2)示例
如果想把圖片畫到canvas中,需要先創建image對象
var img = new Image();
img.src = "。。。。。";
img.onload = function(){
//必須等圖片加載完成再去繪制
ctx.drawImage(img,100,100,200,200,100,100,100,100);
//清除畫布 四個參數:x,y,w,h
ctx.clearRect(250,250,200,200);//用戶清除畫布中已有的內容
// ctx.clearRect(0,0,500,500); //清除整個畫布的內容
}
8、Canvas形變
1)平移 ctx.translate(x,y); 改變的是坐標系,不改變已經繪制好了的內容
2)縮放 ctx.scale(0.5,0.5); 位置以及原圖大小都會改變,縮放時密度變大,縫隙變小
3)旋轉 ctx.rotate(deg); 圍繞畫軸起點旋轉,是整個畫布的旋轉
4)示例:
//繪制表盤
ctx.translate(250,250);
for(var i = 0; i < 12; i++){
ctx.rotate(Math.PI/6);
ctx.beginPath();
ctx.moveTo(0,-200);
ctx.lineTo(0,-150);
ctx.closePath();
ctx.lineWidth = 10;
ctx.stroke();
}
9、Canvas陰影
ctx.shadowColor = "red"; 陰影顏色
ctx.shadowOffsetX = 10; 陰影X軸偏移量
ctx.shadowOffsetY = 10; 陰影y軸偏移量
ctx.shadowBlur = 10; 陰影的模糊程度
10、Canvas動畫
原理: 搽除-繪制-搽除-繪制-搽除-繪制-。。。
使用setInterval();
setTimeout()實現setInterval()
requestAnimationFrame(); 幀動畫
11、注意:
1)多個圖形之間有連線時,是因為畫筆沒有抬起,解決方法是寫上ctx.beginPath();
2)fill和stroke同時使用時會有覆蓋效果,注意先后順序
而且每個相對應的設置,都有先設置,再進行描邊或者填充,
不然