課程內容
3.1.Canvas 進階
3.1.1.canvas 回顧
什麼是canvas 元素?作用是什麼?
在HTML5中,Canvas元素用於在網頁上繪製圖形,該元素強大之處在於可以直接在HTML上進行圖形操作,具有極大的應用價值。
canvas 元素使用腳本JavaScript 在網頁上繪製圖像。
canvas 元素是一個畫布,而畫布是一個矩形區域,可以控制其每一像素。
canvas 元素擁有繪製路徑、矩形、圓形、字符以及添加圖像的方法,可以創建豐富的圖形引用。
eg:
<canvas id="canvas" width="800" height="600" style="border:1px solid #000;"></canvas>
使用canvas 繪製圖形
在繪製圖形之前,首先建立一個畫布,獲取上下文
代碼如下:
<canvas id="canvas" width="800" height="600" style="border:1px solid #000;"></canvas>
<script>
window.onload = function(){
var canvas = document.getElementById('canvas').getContext('2d');
}
</script>
繪製直線
繪製直線
moveTo(x,y);
lineTo(x,y);
strokeStyle = "black"
stroke();
代碼:
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.moveTo(50,50);
cxt.lineTo(750,550);
cxt.strokeStyle = "black";
cxt.stroke();
</script>
ctx.lineWidth :
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.moveTo(0,0);
10
cxt.lineTo(350,150);
cxt.lineWidth = 5;
cxt.strokeStyle = "black";
cxt.stroke();
</script>
繪製矩形
繪製矩形
cxt.fillRect(x,y,width,height)
x:左上角的x軸座標
y:左上角的y軸座標
width:矩形寬度
height:矩形高度
線條繪製矩形
繪製矩形
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.moveTo(50,50);
cxt.lineTo(200,50);
cxt.lineTo(200,200);
cxt.lineTo(50,200);
cxt.lineTo(50,50);
cxt.strokeStyle = "black";
cxt.stroke();
</script>
11
填充繪製矩形
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.moveTo(50,50);
cxt.lineTo(200,50);
cxt.lineTo(200,200);
cxt.lineTo(50,200);
cxt.lineTo(50,50);
cxt.fillStyle = "black";
cxt.fill();
</script>
給填充繪製的矩形加邊框
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.moveTo(50,50);
cxt.lineTo(200,50);
cxt.lineTo(200,200);
cxt.lineTo(50,200);
cxt.lineTo(50,50);
cxt.lineWidth = 5;
cxt.strokeStyle = "red";
12
cxt.fillStyle = "black";
cxt.stroke();
cxt.fill();
</script>
3.1.2.canvas 高級內容(一)
繪製圓形
繪製圓形
cxt.arc(x,y,r,stratAngle,endAngle,counterclockwise);
x:圓心的x座標
y:圓心的y座標
r:圓的半徑
startAngle:起始角,以弧度記(時鐘的3點鐘方向位置),開始爲0
endAngle:結束角,以弧度記
counterclockwise:有兩個值,一個是true 爲逆時針,一個是false 爲順時針,默認值爲false
,想要順時針的話,可以不填
繪製弧線
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.arc(200,200,100,0,0.5*Math.PI);
cxt.lineWidth = 5;
cxt.strokeStyle = "block"
cxt.stroke();
</script>
13
繪製圓
線條圓
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.arc(200,200,100,0,Math.PI*2);
cxt.strokeStyle = "block"
cxt.stroke();
</script>
填充圓
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.arc(200,200,100,0,Math.PI*2);
cxt.fillStyle = "block"
cxt.fill();
</script>
14
路徑繪製圖形
beginPath();//丟棄任何當前定義的路徑並且開始一條新的路徑。它把當前的點設置爲 (0,0)。
closePath();//如果畫布的子路徑是打開的,closePath()
通過添加一條線條連接當前點和子路徑起始點來關閉它。如果子路徑已經閉合了,這個方法不做任何事
情。
沒有beginPath()的情況下
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.fillStyle = "block"
cxt.arc(200,200,100,0,Math.PI*2);
cxt.fill();
cxt.fillStyle = "blueviolet"
cxt.arc(300,300,50,0,Math.PI*2);
cxt.fill();
</script>
15
有beginPath()的情況下:
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.fillStyle = "block"
cxt.arc(200,200,200,0,Math.PI*2);
cxt.fill();
cxt.beginPath();
cxt.fillStyle = "red"
cxt.arc(400,400,100,0,Math.PI*2);
cxt.fill();
</script>
16
繪製多邊形
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.strokeStyle = "block"
cxt.beginPath()
cxt.moveTo(100,100)
cxt.lineTo(400,200)
cxt.lineTo(300,300)
cxt.lineTo(140,200)
cxt.closePath();
cxt.stroke();
</script>
繪製弧線
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.strokeStyle = "block"
cxt.beginPath()
cxt.arc(200,200,200,0,Math.PI*0.5);
cxt.closePath();
cxt.stroke();
</script>
17
canvas 圖像操作
通過js來獲取圖片
<canvas id="canvas" width="650" height="550" style="border:1px solid #000;"></canvas>
<script>
var canvas = document.getElementById('canvas');
var cxt = canvas.getContext('2d');
var img = new Image();
img.src = "img/bg.png";
img.onload = function(){
cxt.drawImage(img,0,0)
}
</script>
<img src="img/bg.png" id="img" style="display: none;" />
<canvas id="canvas" width="650" height="550" style="border:1px solid #000;"></canvas>
<script>
window.onload = function(){
var canvas = document.getElementById('canvas');
var cxt = canvas.getContext('2d');
var img = document.getElementById('img');
cxt.drawImage(img,0,0)
}
</script>
在畫布上定位圖像
canvas圖像
圖像:
圖像是由掃描儀、攝像機等輸入設備捕捉實際畫面而產生的數字圖像,是由像素點陣構成的位圖。
在畫布上定位圖像的語法:
cxt.drawImage(image,dx,dy)
注意:與createPattern(img,repeat-
style)圖像填充不同,context.drawImage(image,dx,dy)創建的是一個對象,createPattern(img,repeat-
style)是把圖片當成背景圖片填充。
例:
18
image :規定要使用的圖像、畫布或視頻。
x : 在畫布上放置圖像的 x 座標位置。
y : 在畫布上放置圖像的 y 座標位置。
在畫布上定位圖像,並規定圖像的寬度和高度的語法
19
canvas圖像
圖像:
圖像是由掃描儀、攝像機等輸入設備捕捉實際畫面而產生的數字圖像,是由像素點陣構成的位圖。
在畫布上定位圖像,並規定圖像的寬度和高度的語法:
cxt.drawImage(img,x,y,width,height);
document.getElementById("pic").onload=function(){
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("pic");
ctx.drawImage(img,10,10,240,160);
};
image :規定要使用的圖像、畫布或視頻。
x : 在畫布上放置圖像的 x 座標位置。
y : 在畫布上放置圖像的 y 座標位置。
width : 可選。要使用的圖像的寬度。(伸展或縮小圖像)
height : 可選。要使用的圖像的高度。(伸展或縮小圖像)
剪切圖像,並在畫布上定位被剪切的部分的語法
canvas圖像
圖像:
圖像是由掃描儀、攝像機等輸入設備捕捉實際畫面而產生的數字圖像,是由像素點陣構成的位圖。
剪切圖像,並在畫布上定位被剪切的部分的語法:
cxt.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
20
img : 規定要使用的圖像、畫布或視頻。
sx : 可選。開始剪切的 x 座標位置。
sy : 可選。開始剪切的 y 座標位置。
swidth : 可選。被剪切圖像的寬度。
sheight : 可選。被剪切圖像的高度。
x : 在畫布上放置圖像的 x 座標位置
y : 在畫布上放置圖像的 y 座標位置。
width : 可選。要使用的圖像的寬度。(伸展或縮小圖像)
height : 可選。要使用的圖像的高度。(伸展或縮小圖像)
var c=document.getElementById("canvas");
var ctx=c.getContext("2d");
var img=document.getElementById("pic");
ctx.drawImage(img,90,130,90,80,20,20,90,80);
image :規定要使用的圖像、畫布或視頻。
sx : 可選。開始剪切的 x 座標位置。
sy : 可選。開始剪切的 y 座標位置。
swidth : 可選。被剪切圖像的寬度。
sheight : 可選。被剪切圖像的高度。
x : 在畫布上放置圖像的 x 座標位置。
y : 在畫布上放置圖像的 y 座標位置。
width : 可選。要使用的圖像的寬度。(伸展或縮小圖像)
height : 可選。要使用的圖像的高度。(伸展或縮小圖像)
在canvas 裏面顯示視頻畫面
21
<video id="video" controls width="270" >
<source src="video/mov_bbb.mp4" type='video/mp4'>
<source src="video/mov_bbb.ogg" type='video/ogg'>
</video>
<script>
var v=document.getElementById("video");
var c=document.getElementById("myCanvas");
ctx=c.getContext('2d');
v.addEventListener('play', function() {
var i=window.setInterval(function() {
ctx.drawImage(v,0,0,270,135)
},20);
},false);
v.addEventListener('pause',function() {
window.clearInterval(i);
},false);
v.addEventListener('ended',function() {
clearInterval(i);
},false);
</script>
3.2.Canvas 進階
3.2.1.canvas 高級內容(二)
在canvas 裏面繪製文字
fillText:繪製文字
fillText(string,x,y)
<script>
var canvas = document.getElementById('canvas');
var cxt = canvas.getContext("2d");
window.onload = function(){
canvas.width = 1420;
canvas.height = 768;
drawText(cxt,'你好,美女!',200,100,"orange");
22
}
function drawText(cxt,string,x,y,color){
cxt.fillStyle = color
cxt.font = "bold 72px 微軟雅黑";
cxt.fillText(string,x,y);
}
</script>
font-style 規定字體樣式
存在值:normal | italic//斜體 | oblique//傾斜
font-variant 規定字體變體
存在值:normal | small-caps //小型大寫
font-weight 規定字體的粗細
存在值:normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
font-size / line-height 規定字號和行高,以像素計。
font-family 規定字體系列
isPointInPath()
isPointInPath
context.isPointInPath(x,y)
用於判斷一個點是否在規劃的當前路徑內
x:測試的 x 座標
y:測試的 y 座標
23
clearRect()
clearRect()
clearRect() 方法清空給定矩形內的指定像素。
語法:
context.clearRect(x,y,width,height);
x : 要清除的矩形左上角的 x 座標
y : 要清除的矩形左上角的 y 座標
width : 要清除的矩形的寬度,以像素計
height : 要清除的矩形的高度,以像素計
點擊獲取鼠標位置
getBoundingClientRect()方法
語法:這個方法沒有參數
rectObject = object.getBoundingClientRect();
返回值類型:TextRectangle對象,每個矩形具有四個整數性質( 上, 右 , 下,和左
)表示的座標的矩形,以像素爲單位。
在canvas獲取鼠標點擊後的位置的方法(canvas標準方法)
var x = event.clientX - canvas.getBoundingClientRect().left;
var y = event.clientY - canvas.getBoundingClientRect().top;
3.3.Canvas 進階
3.3.1.canvas 高級內容(三)
剪輯區域
剪輯區域
24
定義和用法:
clip() 方法從原始畫布中剪切任意形狀和尺寸。
一旦剪切了某個區域,則所有之後的繪圖都會被限制在被剪切的區域內(不能訪問畫布上的其他區域
)。
語法:
context.clip()
使用剛纔的路徑,把它剪切爲當前的繪製環境
例:
25
globalCompositeOperation
globalCompositeOperation
globalCompositeOperation = "source-over" (default)
值:destination-over source-atop source-in source-out destination-over destination-atop destination-in
destination-out lighter copy xor
globalCompositeOperation當指繪製的圖像發生重疊時所產生的效果
source-
over:這是非常符合常理的覆蓋形態,就是說若圖形發生重疊時,後面繪製的圖形會覆蓋到前面繪製的圖
形
26
source-over : 默認。在目標圖像上顯示源圖像。
source-atop
: 在目標圖像頂部顯示源圖像。源圖像位於目標圖像之外的部分是不可見的
source-in
: 在目標圖像中顯示源圖像。只有目標圖像內的源圖像部分會顯示,目標圖
像是透明的。
source-out
: 在目標圖像之外顯示源圖像。只會顯示目標圖像之外源圖像部分,目標圖
像是透明的。
destination-over : 在源圖像上方顯示目標圖像。
destination-atop
: 在源圖像頂部顯示目標圖像。源圖像之外的目標圖像部分不會被顯示。
destination-in
: 在源圖像中顯示目標圖像。只有源圖像內的目標圖像部分會被顯示,源圖
像是透明的。
destination-out
: 在源圖像外顯示目標圖像。只有源圖像外的目標圖像部分會被顯示,源圖
像是透明的。
lighter : 顯示源圖像 + 目標圖像。
copy : 顯示源圖像。忽略目標圖像。
xor : 顯示源圖像和目標圖像不相交的地方,相交處透明
27
陰影
陰影
例:
28
shadowColor 設置或返回用於陰影的顏色
shadowOffsetX 設置或返回陰影距形狀的水平距離
shadowOffsetY 設置或返回陰影距形狀的垂直距離
shadowBlur 設置或返回用於陰影的模糊級別
路徑方向和剪紙效果
路徑方向和剪紙效果
例:
29
globalAlpha
globalAlpha
globalAlpha=1;(default)
默認是1,用於設置圖形透明度 透明數值範圍(0-1)
例:
30
貝塞爾曲線
二次貝塞爾曲線 quadraticCurveTo()
定義和用法
quadraticCurveTo() 方法通過使用表示二次貝塞爾曲線的指定控制點,向當前路徑添加一個點。
31
二次貝塞爾曲線需要兩個點。第一個點是用於二次貝塞爾計算中的控制點,第二個點是曲線的結束
點。曲線的開始點是當前路徑中最後一個點。如果路徑不存在,那麼請使用 beginPath() 和 moveTo()
方法來定義開始點。
語法:
cxt.quadraticCurveTo(cpx,cpy,x,y)
cpx:貝塞爾控制點的 x 座標
cpy:貝塞爾控制點的 y 座標
x: 貝塞爾結束點的 x 座標
y: 貝塞爾結束點的 y 座標
三次貝塞爾曲線 bezierCurveTo()
定義和用法
bezierCurveTo() 方法通過使用表示三次貝塞爾曲線的指定控制點,向當前路徑添加一個點。
三次貝塞爾曲線需要三個點。前兩個點是用於三次貝塞爾計算中的控制點,第三個點是曲線的結束
點。曲線的開始點是當前路徑中最後一個點。如果路徑不存在,那麼請使用 beginPath() 和 moveTo()
方法來定義開始點。
語法:
cxt.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)
32
cp1x : 第一個貝塞爾控制點的 x 座標
cp2x : 第二個貝塞爾控制點的 x 座標
x : 結束點的 x 座標
cp1y : 第一個貝塞爾控制點的 y 座標
cp2y : 第二個貝塞爾控制點的 y 座標
y : 結束點的 y 座標
3.4.Canvas 進階
3.4.1.canvas 高級內容(四)
canvas 動畫效果
canvas動畫效果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d')
var y = 0
var color = "black"
setInterval(function(){
33
y++
fillArc(y,color)
},20)
function fillArc(y,color){
ctx.clearRect(0,0,600,600)
ctx.beginPath()
ctx.arc(300,300-y,5,0,2*Math.PI)
ctx.fillStyle = color
ctx.fill()
}
fillArc(y)
</script>
</body>
</html>
碰撞運動
碰撞運動
所謂碰撞運動即是當物體碰撞到地板或者牆壁邊緣時發生的速度的改變。
我們可以想象一下,假設一個有一定質量的小球從高空做自由落體運動,然後碰撞到地板之後速度就
會發生變化,小球就會彈起來。在這個碰撞過程中,我們讓小球有一個能量的損失,由這個想象,我們就
來模擬這個實驗:
首頁我們需要最簡單的幾步:(創建一個畫布)
34
我們要想讓小球有運動,那麼就需要改變小球在Y軸上的值,所以我們首先需要定義一個全局變量,
這個變量就是小球的一個對象。
當我們創建好畫布之後,我們可以先來寫幾個函數,我們先想象一下我們需要幾個函數,首先,假如
我們就直接在畫布上畫一個圓,但是我們的運動是發生在這個小圓身上的,如果直接這樣繪製,則無法
獲取到這個圓,所以這裏我們用函數進行一個繪製,假設這個函數名爲render,但是如果用函數繪製小圓
,我們就會發現當我們調用setInterval()函數的時候,會每執行一次動畫就會調用一次這個render,也就是
說沒執行一次就會創建一個新的小圓,那樣當動畫開始執行的時候,我們就會看到畫布上會創建很多的
小圓,那麼這樣的效果就不是我們想要的效果的了,這時候我們應該怎麼做呢?那麼這時候,我們就需
要當動畫沒執行一次就對畫布進行一次刷新操作,我們就引進了context.clearRect()函數,該函數對一個
矩形控件內的圖像進行一次刷新操作。
這樣,我們這個畫小球的操作就完成了。
接下來我們還需要一個函數,這個函數就是記載了小球做自由落體運動的軌跡,我們給一個函數名叫
update;
那麼這個函數所需要做的事就是記錄這個小球的運動軌跡,我們讓小球的起始Y座標點的值,加上這
個速度,就可以讓小球運動起來了,然後我們需要注意的是,假設畫布的底部就是地板,那麼小球到達地
板後就會被反彈,這時,我們就需要改變這個小球的運動方向。所以這個函數我們可以這麼寫
35
我們來解釋一下這段代碼:
ball.vy +=
ball.g:我們學過物理的之後,我們做自由落體的時候是有一個重力加速度的,假設沒有這句代碼,那麼
小球做的則是勻速直接運動,而並不是自由落體運動,所以我們讓速度加上這個重力加速度,那麼小球
在Y軸上的速度就會有一個加速度,就模擬了自由落體運動。
ball.y = 768-ball.r:這句代碼是小球碰撞到地板後,以該點作爲小球的起始點然後向上反彈。
ball.vy = -ball.vy *
0.7:這句代碼就是把速度重新賦值爲一個負值,而且模擬一個摩擦係數爲0.7,這樣就會有能量損失,小
球就會往反方向運動。
那麼其他代碼就很好理解了。
最後我們需要用setInterval()函數調用這兩個函數。
由這個動畫我們可以擴展另一個動畫,假設canvas畫布每個邊緣都是牆壁,還有小球在運動的過程中
不會有任何能量的損失,也就是說上述例子ball.vy = -ball.vy *
0.7這句代碼去掉0.7這個摩擦係數,那麼就可以實現小球一旦碰到牆壁就會反彈的效果,小球就會在這
個畫布裏無休息的進行運動。