bezierCurveTo()方法繪制三次貝塞爾曲線代碼如下。
context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);
這個方法可謂是繪制波浪線的神器。根據(jù)之前的結(jié)論,n階貝塞爾曲線就有n-1個控制點,所以三次貝塞爾曲線有1個起始點、1個終止點、2個控制點。因此傳入的6個參數(shù)分別為控制點cp1 (cp1x, cp1y),控制點cp2 (cp2x, cp2y),與終止點 (x, y)。
這個方法也是不用大家去掌握參數(shù)具體是怎么填的,只要知道參數(shù)的意義就行。和quadraticCurveTo()方法一樣,bezierCurveTo()的三次貝塞爾曲線網(wǎng)上也能找到互動的網(wǎng)頁工具。這里提供一個網(wǎng)頁:Canvas Bézier Curve Example,大家可以動手試一下。

這里我們拿XP的壁紙開刀,來練習(xí)一下我們之前學(xué)習(xí)過的繪制方法。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>XP壁紙</title>
<style>
body { background: url("./images/bg3.jpg") repeat; }
#canvas { border: 1px solid #aaaaaa; display: block; margin: 50px auto; }
</style>
</head>
<body>
<div id="canvas-warp">
<canvas id="canvas">
你的瀏覽器居然不支持Canvas?!趕快換一個吧??!
</canvas>
</div>
<script>
window.onload = function(){
var canvas = document.getElementById("canvas");
canvas.width = 800;
canvas.height = 600;
var context = canvas.getContext("2d");
context.fillStyle = "#FFF";
context.fillRect(0,0,800,600);
drawPrairie(context);
drawSky(context);
for(var i=0; i <5; i++){
var x0 = 500 * Math.random() + 50;
var y0 = 200 * Math.random() + 50;
var c0 = 100 * Math.random() + 50;
drawCloud(context, x0, y0, c0);
}
};
function drawSky(cxt){
cxt.save();
cxt.beginPath();
cxt.moveTo(0, 420);
cxt.bezierCurveTo(250, 300, 350, 550, 800, 400);
cxt.lineTo(800,0);
cxt.lineTo(0,0);
cxt.closePath();
var lineStyle = cxt.createRadialGradient(400, 0, 50, 400, 0, 200);
lineStyle .addColorStop(0, "#42A9AA");
lineStyle .addColorStop(1, "#2491AA");
cxt.fillStyle = lineStyle;
cxt.fill();
cxt.restore();
}
function drawPrairie(cxt){
cxt.save();
cxt.beginPath();
cxt.moveTo(0, 420);
cxt.bezierCurveTo(250, 300, 350, 550, 800, 400);
cxt.lineTo(800,600);
cxt.lineTo(0,600);
cxt.closePath();
var lineStyle = cxt.createLinearGradient(0, 600, 600, 0);
lineStyle .addColorStop(0, "#00AA58");
lineStyle .addColorStop(0.3, "#63AA7B");
lineStyle .addColorStop(1, "#04AA00");
cxt.fillStyle = lineStyle;
cxt.fill();
cxt.restore();
}
/*渲染單個云朵
context: canvas.getContext("2d")對象
cx: 云朵X軸位置
cy: 云朵Y軸位置
cw: 云朵寬度
*/
function drawCloud(cxt, cx, cy, cw) {
//云朵移動范圍即畫布寬度
var maxWidth = 800;
//如果超過邊界從頭開始繪制
cx = cx % maxWidth;
//云朵高度為寬度的60%
var ch = cw * 0.6;
//開始繪制云朵
cxt.beginPath();
cxt.fillStyle = "white";
//創(chuàng)建漸變
var grd = cxt.createLinearGradient(0, 0, 0, cy);
grd.addColorStop(0, 'rgba(255,255,255,0.8)');
grd.addColorStop(1, 'rgba(255,255,255,0.5)');
cxt.fillStyle = grd;
//在不同位置創(chuàng)建5個圓拼接成云朵現(xiàn)狀
cxt.arc(cx, cy, cw * 0.19, 0, 360, false);
cxt.arc(cx + cw * 0.08, cy - ch * 0.3, cw * 0.11, 0, 360, false);
cxt.arc(cx + cw * 0.3, cy - ch * 0.25, cw * 0.25, 0, 360, false);
cxt.arc(cx + cw * 0.6, cy, cw * 0.21, 0, 360, false);
cxt.arc(cx + cw * 0.3, cy - ch * 0.1, cw * 0.28, 0, 360, false);
cxt.closePath();
cxt.fill();
}
</script>
</body>
</html>
運行結(jié)果:

是不是很萌?是不是非常的酷!這個案例幾乎用到了之前所傳授給你們的所有武功——三次貝塞爾曲線,徑向漸變,線性漸變,繪制圓弧等等。分開寫了三個函數(shù),一個繪制草原、一個繪制藍(lán)天、一個繪制白云……大家嘗試自己實現(xiàn)一下,當(dāng)做一次階段性復(fù)習(xí)~
這里還使用到了兩個新方法save()和restore()。之前說過了canvas是基于狀態(tài)的繪制(說了好多次,感覺自己好啰嗦)。保存(推送)當(dāng)前狀態(tài)到堆棧,調(diào)用以下函數(shù)。
context.save();
調(diào)出最后存儲的堆?;謴?fù)畫布,使用以下函數(shù)。
context.restore();
不知道大家壁紙繪制的如何,肯定非常的酷有沒有?到此為止路徑的知識和填充樣式我們已經(jīng)全部講完了,大家也畫出了很多或優(yōu)美、或抽象的藝術(shù)作品。不管怎么樣,這是屬于我們的藝術(shù),我們繼續(xù)前進(jìn)!