關(guān)鍵字:canvas
繪制
線
矩形
文字
圓形
曲線
圖片
畫(huà)布
變形
陰影
簡(jiǎn)介
IE8以下不支持
HTML5新標(biāo)簽 使用JS API
canvas不適用CSS設(shè)置樣式,使用自身的width和height屬性設(shè)置
作用
- 繪制線
- 繪制三角形
- 繪制矩形
- 繪制文字
- 繪制圓形
- 繪制圖片
- 繪制視頻
- 繪制圖片陰影
<canvas id="canvas" width="500" height="500">
您的瀏覽器不支持canvas露戒,請(qǐng)升級(jí)至最新版
</canvas>
常用方法
獲取元素
大多數(shù)時(shí)候都在操作ctx對(duì)象
var canvas=document.getElementById("canvas");
獲取上下文對(duì)象(畫(huà)筆)
var ctx=canvas.getContext("2d");
暫時(shí)不涉及3d
繪制線
- 1腿准、開(kāi)始繪制
- 2容燕、繪制起點(diǎn)
- 3操软、繪制后續(xù)的點(diǎn)
- 4详瑞、繪制結(jié)束
-
closePath()
也叫關(guān)閉路徑遗嗽,會(huì)把終點(diǎn)和起點(diǎn)連接起來(lái)進(jìn)行繪制 - 當(dāng)需要終點(diǎn)和起點(diǎn)連接粘我,才使用
closePath()
-
- 5、畫(huà)(填)
- 設(shè)置畫(huà)線顏色
- 設(shè)置畫(huà)線的寬度
- 畫(huà)線
- 設(shè)置填充顏色
- 填充
- 繪制的線和填充的內(nèi)容會(huì)發(fā)生覆蓋的情況痹换,沒(méi)有優(yōu)先級(jí)征字,由代碼順序決定(后面設(shè)置的會(huì)覆蓋前面設(shè)置的)
//1都弹、開(kāi)始繪制
ctx.beginPath();
//2、繪制起點(diǎn)
ctx.moveTo(250,250);
//3匙姜、繪制后續(xù)的點(diǎn)
ctx.lineTo(500,0);
ctx.lineTo(450,450);
//4缔杉、繪制結(jié)束
//closePath()也叫關(guān)閉路徑,會(huì)把終點(diǎn)和起點(diǎn)連接起來(lái)進(jìn)行繪制
//當(dāng)需要終點(diǎn)和起點(diǎn)連接搁料,才使用closePath()
ctx.closePath();
//5或详、畫(huà)(填)
//設(shè)置畫(huà)線顏色
ctx.strokeStyle="red";
//設(shè)置畫(huà)線的寬度
ctx.lineWidth=5;
//畫(huà)線
ctx.stroke();
//設(shè)置填充顏色
ctx.fillStyle="blue";
//填充
ctx.fill();
//繪制的線和填充的內(nèi)容會(huì)發(fā)生覆蓋的情況,沒(méi)有優(yōu)先級(jí)郭计,由代碼順序決定(后面設(shè)置的會(huì)覆蓋前面設(shè)置的)
繪制矩形
按照矩形畫(huà)線
ctx.strokeRect(x,y,w,h);
按照矩形填充ctx.fillRect(x,y,w,h);
//按照矩形畫(huà)線
ctx.strokeRect(0,0,100,100);
//按照矩形填充
ctx.fillRect(0,100,100,100);
繪制文字
- 參數(shù)4:最大寬度霸琴,可寫(xiě)可不寫(xiě)
描邊文字
ctx.strokeText(text,x,y,maxwidth?);
填充文字ctx.fillText(text,x,y,maxwidth?);
ctx.font="50px 黑體";
ctx.strokeText("hello world",100,100);
ctx.fillText("hello world",100,100);
繪制圓形
ctx.arc(x,y,r,startAngle,endAngle,direction)
- 參數(shù)1:圓心的x
- 參數(shù)2:圓心的y
- 參數(shù)3:圓的半徑
- 參數(shù)4:起點(diǎn)的位置昭伸,根據(jù)右側(cè)和設(shè)置的弧度制找到起點(diǎn)
- 參數(shù)5:終點(diǎn)的位置梧乘,根據(jù)右側(cè)和設(shè)置的弧度制找到終點(diǎn)
- 參數(shù)6:繪制的方向,true表示逆時(shí)針庐杨,false表示順時(shí)針
ctx.arc(250, 250, 200, Math.PI, Math.PI / 2, true);
ctx.stroke();
繪制曲線
- 使用
moveTo
設(shè)置起點(diǎn) - 使用
quadraticCurveTo()
放置基準(zhǔn)點(diǎn)和終點(diǎn)
二次貝塞爾曲線
- 參數(shù)1:基準(zhǔn)點(diǎn)的x
- 參數(shù)2:基準(zhǔn)點(diǎn)的y
- 參數(shù)3:終點(diǎn)的x
- 參數(shù)4:終點(diǎn)的y
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.moveTo(500,0);
ctx.quadraticCurveTo(0, 250, 500, 500);
ctx.stroke();
三次貝塞爾曲線的特點(diǎn)是有兩個(gè)基準(zhǔn)點(diǎn)
- 參數(shù)1:基準(zhǔn)點(diǎn)1的x
- 參數(shù)2:基準(zhǔn)點(diǎn)1的y
- 參數(shù)3:基準(zhǔn)點(diǎn)2的x
- 參數(shù)4:基準(zhǔn)點(diǎn)2的y
- 參數(shù)5:終點(diǎn)的x
- 參數(shù)6:終點(diǎn)的y
ctx.moveTo(0, 0);
ctx.bezierCurveTo(500, 0, 0, 500, 500, 500);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.bezierCurveTo(0, 500, 500, 0, 500, 500);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(500, 0);
ctx.bezierCurveTo(0, 0, 500, 500, 0, 500);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(500, 0);
ctx.bezierCurveTo(500, 500, 0, 0, 0, 500);
ctx.stroke();
繪制圖片
- 如果想把圖像畫(huà)到
canvas
中选调,需要先創(chuàng)建image
對(duì)象
var img = new Image();
img.src = './imgs/img.png';
img.onload = function () {
// 必須等圖片加載完成之后,才可以進(jìn)行繪制
ctx.drawImage(img, 100, 100);
// ctx.drawImage(img, 100, 100, 200, 200);
// ctx.drawImage(img, 100, 100, 260, 260, 100, 96, 260, 260);
// 清除畫(huà)布
ctx.clearRect(250, 250, 200, 200);
// 四個(gè)參數(shù): x, y, w, h
// 用戶(hù)清除畫(huà)布中已有的內(nèi)容
};
變形
注意:改變不了坐標(biāo)系
不會(huì)影響已經(jīng)繪制的內(nèi)容
- 位移
ctx.translate(x,y);
- 縮放
ctx.scale(scaleX,scaleY)
- 旋轉(zhuǎn)灵份、弧度
ctx.rotate();
代碼練習(xí)
ctx.translate(100, 100);
ctx.scale(2, 2);
ctx.rotate(Math.PI / 8);
ctx.fillRect(100, 100, 300, 100);
ctx.rotate(Math.PI / 2);
ctx.translate(200, 100);
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 300, 100);
代碼示例
// 繪制表盤(pán)
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();
//因?yàn)楸肀P(pán)上所有的刻度都是圍繞中心展開(kāi)的仁堪,所以,先把坐標(biāo)系原點(diǎn) 平移 到canvas中心的位置填渠,然后在使用 負(fù)的y值 進(jìn)行繪制弦聂,每次繪制前,進(jìn)行30度的旋轉(zhuǎn)即可氛什,持續(xù)12次莺葫。 第一個(gè)繪制的并非是12刻度,而是刻度1
}
判斷是否點(diǎn)中
-
var res=ctx.isPointInPath(x,y);
- 判斷是否點(diǎn)了某個(gè)區(qū)域
- 注意點(diǎn):如果進(jìn)行了描邊枪眉,點(diǎn)擊內(nèi)部也會(huì)觸發(fā)
-
var res=ctx.isPointInStroke(x,y);
- 判斷是否點(diǎn)中了邊框
常用屬性
顏色捺檬、線
- 設(shè)置顏色
ctx.strokeStyle = 'red';
- 設(shè)置線的寬度
ctx.lineWidth = 50;
- 設(shè)置線的頭部和尾部進(jìn)行圓角處理
ctx.lineCap = 'round';
- 設(shè)置線的交互處進(jìn)行圓角處理
ctx.lineJoin = 'round';
ctx.strokeStyle = 'red';
ctx.lineWidth = 50;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.stroke();
文字
- 設(shè)置文字字體
ctx.font = '50px 黑體';
注意:?jiǎn)为?dú)設(shè)置字體大小不起作用,需要同時(shí)設(shè)置字體
- 設(shè)置水平對(duì)齊方式
ctx.textAlign = 'left';
- textAlign的參數(shù)
start|left
/center
/end|right
- textAlign的參數(shù)
- 設(shè)置垂直對(duì)齊方式
ctx.textBaseline = 'middle';
- textBaseline的參數(shù)
top
/middle
/bottom
- textBaseline的參數(shù)
ctx.font = '50px 黑體';
ctx.textAlign = 'left';
ctx.textBaseline = 'middle';
ctx.fillText('l j k m n p q', 100, 100);
ctx.strokeRect(100, 100, 300, 100);
陰影
- 設(shè)置陰影顏色
ctx.shadowColor = 'blue';
- 設(shè)置陰影X軸偏移量
ctx.shadowOffsetX = 10;
- 設(shè)置陰影Y軸偏移量
ctx.shadowOffsetY = 10;
- 設(shè)置陰影模糊程度
ctx.shadowBlur = 10;
代碼示例
ctx.shadowColor = 'blue';
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowBlur = 10;
ctx.fillRect(250, 250, 200, 200);
動(dòng)畫(huà)
動(dòng)畫(huà)的原理:擦出-繪制-擦出-繪制-擦出-繪制-擦出-繪制
- 使用
setInterval();
切換選項(xiàng)卡的時(shí)候 - 使用
setTimeout();
實(shí)現(xiàn)setInterval();
-
requestAnimationFrame();
幀動(dòng)畫(huà)
學(xué)習(xí)應(yīng)用——躁動(dòng)的小球
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>躁動(dòng)的小球</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
html,body{
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="canvas" width="300" height="300">
<p>您的瀏覽器不支持canvas贸铜,請(qǐng)<a href="#">點(diǎn)擊</a>下載最新版瀏覽器</p>
</canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
var canvasWidth=canvas.width;
var canvasHeight=canvas.height;
function random(min,max){
return parseInt(Math.random()*(max-min+1)+min);
}
function randomColor(){
var r=random(0,255);
var g=random(0,255);
var b=random(0,255);
var a=Math.random(0,1)+0.3;
return "rgba("+r+","+g+","+b+","+a+")";
}
var balls=[];
for (var i=0;i<500;i++) {
var ball={};
ball.r=random(10,30);
ball.x=random(ball.r,canvasWidth-ball.r);
ball.y=random(ball.r,canvasHeight-ball.r);
ball.color=randomColor();
ball.speedX=random(1,5);
ball.speedY=random(1,5);
balls.push(ball);
}
setInterval(function(){
ctx.clearRect(0,0,canvasWidth,canvasHeight);
for (var i=0;i<balls.length;i++) {
var ball=balls[i];
ball.x+=ball.speedX;
ball.y+=ball.speedY;
if (ball.x>=canvasWidth-ball.r||ball.x<=ball.r) {
ball.speedX*=-1;
}
if (ball.y>=canvasHeight-ball.r||ball.y<=ball.r) {
ball.speedY*=-1;
}
ctx.beginPath();
ctx.arc(ball.x,ball.y,ball.r,0,Math.PI*2,false);
ctx.closePath();
ctx.fillStyle=ball.color;
ctx.fill();
}
},20)
</script>
</html>