15-创建立方贝塞尔曲线环
5.3.5 创建立方贝塞尔曲线环
利用立方贝塞尔曲线的4个点可以创建出很多非常有意思的路径,其中有一种就是环形。为创建环形,只需确保这些点形成一个“X”形交叉,p0和p1形成一个对角线,p2和p3形成另一个相交的对角线。p0和p3必须比p1或p2离画布中心更近。下面是例5-13中创建效果的这些点。
var p0 = {x:150, y:440};
var p1 = {x:450, y:10};
var p2 = {x:50, y:10};
var p3 = {x:325, y:450};
对于立方贝塞尔曲线来说,演示比讲解容易得多,如图5-17所示。该图显示了例5-13在Web浏览器中的运行效果。
提示
这个效果只能通过立方贝塞尔曲线的4个点来创建。还有三点式的贝塞尔曲线称为平方贝塞尔曲线。使用平方贝塞尔曲线无法创建循环或者S形曲线,因为3个点无法达到立方贝塞尔曲线的4个点的精确度。
由于这个示例的代码与例5-12基本相同(除了4个点以外),因此例5-13将改变的代码突出为粗体。这样做也是为了向读者说明一点:使用立方贝塞尔曲线,仅需简单地改变代码就可以创建很好的动画效果。
例5-13 贝塞尔曲线循环
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CH5EX13: Bezier Curve Loop </title>
<script src="modernizr.js"></script>
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);
var bullseye;
function eventWindowLoaded(){
bullseye = new Image();
bullseye.src = "bullseye.png"
bullseye.onload = eventAssetsLoaded;
}
function eventAssetsLoaded(){
canvasApp();
}
function canvasSupport (){
return Modernizr.canvas;
}
function canvasApp(){
if (!canvasSupport()){
return;
}
var pointImage = new Image();
pointImage.src = "point.png";
function drawScreen (){
context.fillStyle = '#EEEEEE';
context.fillRect(0, 0, theCanvas.width, theCanvas.height);
//边框
context.strokeStyle = '#000000';
context.strokeRect(1, 1, theCanvas.width-2, theCanvas.height-2);
var t = player.t;
var cx = 3 * (p1.x - p0.x)
var bx = 3 * (p2.x - p1.x)- cx;
var ax = p3.x - p0.x - cx - bx;
var cy = 3 * (p1.y - p0.y);
var by = 3 * (p2.y - p1.y)- cy;
var ay = p3.y - p0.y - cy - by;
var xt = ax*(t*t*t)+ bx*(t*t)+ cx*t + p0.x;
var yt = ay*(t*t*t)+ by*(t*t)+ cy*t + p0.y;
player.t += player.speed;
if (player.t > 1){
player.t = 1;
}
//绘制点
context.font = "10px sans";
context.fillStyle = "#FF0000";
context.beginPath();
context.arc(p0.x,p0.y,8,0,Math.PI*2,true);
context.closePath();
context.fill();
context.fillStyle = "#FFFFFF";
context.fillText("0",p0.x-2,p0.y+2);
context.fillStyle = "#FF0000";
context.beginPath();
context.arc(p1.x,p1.y,8,0,Math.PI*2,true);
context.closePath();
context.fill();
context.fillStyle = "#FFFFFF";
context.fillText("1",p1.x-2,p1.y+2);
context.fillStyle = "#FF0000";
context.beginPath();
context.arc(p2.x,p2.y,8,0,Math.PI*2,true);
context.closePath();
context.fill();
context.fillStyle = "#FFFFFF";
context.fillText("2",p2.x-2, p2.y+2);
context.fillStyle = "#FF0000";
context.beginPath();
context.arc(p3.x,p3.y,8,0,Math.PI*2,true);
context.closePath();
context.fill();
context.fillStyle = "#FFFFFF";
context.fillText("3",p3.x-2, p3.y+2);
points.push({x:xt,y:yt});
for (var i = 0; i< points.length; i++){
context.drawImage(pointImage, points[i].x, points[i].y,1,1);
}
context.closePath();
player.x = xt-bullseye.width/2;
player.y = yt-bullseye.height/2;
context.drawImage(bullseye,player.x,player.y);
}
var p0 = {x:150, y:440};
var p1 = {x:450, y:10};
var p2 = {x:50, y:10};
var p3 = {x:325, y:450};
var player = {x:0, y:0, speed:.01, t:0};
var points = new Array();
theCanvas = document.getElementById("canvasOne");
context = theCanvas.getContext("2d");
function gameLoop() {
window.setTimeout(gameLoop, 20);
drawScreen();
}
gameLoop();
}
</script>
</head>
<body>
<div style="position: absolute; top: 50px; left: 50px;">
<canvas id="canvasOne" width="500" height="500">
Your browser does not support HTML5 Canvas.
</canvas>
</div>
</body>
</html>