2013-10-28 165 views
1

我在画布元素的一个图层中创建了一个静态背景,然后尝试移动我创建的矩形对象以穿过圆柱体,管道然后它应该落入管道末端的小圆筒内。我可以沿着一条直线移动它,但是我必须旋转物体(比如-25度),然后水平移动(180度,当它在管道内沿y方向行进时)。 代码:在HTML5画布中沿着路径旋转移动的对象

<!doctype html> 
<html lang="en"> 
<head> 
<meta charset="UTF-8"/> 

</head> 
<body> 

<section> 
<div id="canvasesdiv" style="position:relative; width:650px; height:600px"> 
<canvas id="layer1" 
style="z-index: 1; 
position:absolute; 
left:0px; 
top:0px; 
" height="600px" width="650"> 
</canvas> 

<canvas id="layer2" 
style="z-index: 2; 
position:absolute; 
left:0px; 
top:0px; 
" height="600px" width="650"> 
</canvas> 
</div> 

<button onclick="start()">Start</button> 
<button onclick="stop()">Stop</button> 

<script type="text/javascript"> 



var requestId = 0; 
var animationStartTime=0; 
var speed=1; 
var posX=160; //for cylinder 
var posY=posX+50; //for cylinder 
var x=160; //for packets 
var y=230; //for packetsvar time=1000; 
//var time=1000; 
var layer1; 
var layer2; 
var ctx; 
var ctx2; 

var pack=setInterval(drawPacket,1500); 

function packet(){ 
layer1 = document.getElementById("layer1"); 
ctx = layer1.getContext("2d"); 

layer2 = document.getElementById("layer2"); 
ctx2 = layer2.getContext("2d"); 
window.onload=drawScreen(); 

} 

function animate() { 
ctx2.clearRect(0,0,layer2.width,layer2.height); 
requestAnimationFrame = window.mozRequestAnimationFrame || 
       window.webkitRequestAnimationFrame || 
       window.msRequestAnimationFrame  || 
       window.oRequestAnimationFrame 
       ; 
requestId = window.requestAnimationFrame(animate); 

anime(); 
} 

function anime(){ 
if (x>=0 || x<=445){ 
drawPacket(); 
x+=speed; 
} 

if(posXX==445 && posYY==230){ 
y+=-speed; 
}} 

function drawPacket(){ 
ctx2.beginPath(); 
ctx2.clearRect(0,0,layer2.width,layer2.height); 
ctx2.rect(x,y, 10, 30); 
ctx2.closePath(); 
ctx2.stroke(); 
ctx2.restore(); 
} 

function redrawPacket(){ 
ctx2.beginPath(); 
ctx2.clearRect(0,0,layer2.width,layer2.height); 
ctx2.rotate((Math.PI/180) * -25); //rotate 25 degrees. 
ctx2.rect(x,y, 10, 30); 
ctx2.closePath(); 
ctx2.stroke(); 
} 

function start() { 
requestId = window.requestAnimationFrame(animate); 
} 

function stop() { 
    if (requestId) 
    window.cancelAnimationFrame(requestId); 
    requestId = 0; 
} 

function drawScreen() { 

ctx.beginPath(); 
{ 
//top line 
ctx.moveTo(250,215); 
ctx.lineTo(390,215); 


//bottom line 
ctx.moveTo(250,315); 
ctx.lineTo(390,315); 

//front curve 
ctx.moveTo(230,230); 
ctx.quadraticCurveTo(250,200,269,230); 

//bottom curve 
ctx.moveTo(230,300); 
ctx.quadraticCurveTo(250,330,268,300); 


//front arc joining top and bottom opp curve 
ctx.moveTo(230,230); 
ctx.quadraticCurveTo(214,265,230,300); 


//front opp arc joining top and bottom opp curve 
ctx.moveTo(269,230); 
ctx.quadraticCurveTo(286,265,268,300); 

//ctx.moveTo(230,230); 
//ctx.fillRect(230,230,188.80,170); 

//back small top curve 
ctx.moveTo(390,215); 
ctx.quadraticCurveTo(407,218,414,230); 

//back small bottom curve 
ctx.moveTo(390,315); 
ctx.quadraticCurveTo(405,314,414,300); 

//back arc 
ctx.moveTo(414,230); 
ctx.quadraticCurveTo(435,263,414,300); 

ctx.stroke(); 
ctx.closePath(); 
} 

ctx.beginPath(); 

{ 
//First Cylinder 
//First cylinder 1st line of rect 
ctx.moveTo(574,130); 
ctx.lineTo(574,195); 

//First cylinder opp line of rect 
ctx.moveTo(614,130); 
ctx.lineTo(614,195); 

//First cylinder bottom arc 
ctx.moveTo(574,195); 
ctx.quadraticCurveTo(594,205,614,195); 

//First cylinder top-top arc 
ctx.moveTo(574,130); 
ctx.quadraticCurveTo(594,119,614,130); 

//First cylinder top-bottom arc 
ctx.moveTo(574,130); 
ctx.quadraticCurveTo(594,142,614,130); 
ctx.stroke(); 
ctx.closePath(); 
} 

ctx.beginPath(); 
{ 
//Second Cylinder 
//Second cylinder 1st line of rect 
ctx.moveTo(574,428); 
ctx.lineTo(574,493); 

//Second cylinder opp line of rect 
ctx.moveTo(614,428); 
ctx.lineTo(614,493); 

//drawellipse(574,428,10,2,0.5) 

//Second cylinder bottom arc 
ctx.moveTo(574,493); 
ctx.quadraticCurveTo(594,503,614,493); 

//Second cylinder top-top arc 
ctx.moveTo(574,428); 
ctx.quadraticCurveTo(594,417,614,428); 

//Second cylinder top-bottom arc 
ctx.moveTo(574,428); 
ctx.quadraticCurveTo(594,440,614,428);  
ctx.stroke(); 
ctx.closePath(); 
} 


ctx.beginPath(); 

{ 
//Pipe to cylinder 1 
//top line from main cylinder 
ctx.moveTo(408,222); 
ctx.lineTo(436,222); 

//left line from main cylinder 
ctx.moveTo(436,222); 
ctx.lineTo(436,32); 

//bottom line from main cylinder 
ctx.moveTo(423,266); 
ctx.lineTo(486,266); 

//right line from main cylinder 
ctx.moveTo(486,266); 
ctx.lineTo(486,82); 

//top line from left line 
ctx.moveTo(436,32); 
ctx.lineTo(619,32); 

//bottom line from right line 
ctx.moveTo(486,82); 
ctx.lineTo(566,82); 

//drop line to cylinder right 
ctx.moveTo(619,32); 
ctx.lineTo(619,112); 

//drop line to cylinder left 
ctx.moveTo(566,82); 
ctx.lineTo(566,112); 
//closing the pipe 
ctx.moveTo(566,112); 
ctx.quadraticCurveTo(592,128,619,112); 
ctx.moveTo(566,112); 
ctx.quadraticCurveTo(592,96,619,112); 
ctx.stroke(); 
ctx.closePath(); 
} 
} 
packet(); 
</script> 
</body> 
</html> 

请帮我解决这个问题..提前 谢谢..

回答

4

的一种方式,以动画对象沿路径是沿着这条路径计算polypoints。

然后对于每个动画循环,将对象前移到下一个聚点。

这里是一个演示:http://jsfiddle.net/m1erickson/RtXq6/

例如,你的汽缸管路径可能有一些像这样定义线段:

var pathArray=[] 
pathArray.push({x:25, y:250}); 
pathArray.push({x:150,y:250}); 
pathArray.push({x:150,y:50}); 
pathArray.push({x:250,y:50}); 
pathArray.push({x:250,y:100}); 

可以沿该系列的计算polypoints线段如下:

function makePolyPoints(pathArray){ 

    var points=[]; 

    for(var i=1;i<pathArray.length;i++){ 
     var startPt=pathArray[i-1]; 
     var endPt=pathArray[i]; 
     var dx = endPt.x-startPt.x; 
     var dy = endPt.y-startPt.y; 
     for(var n=0;n<=100;n++){ 
      var x= startPt.x + dx * n/100; 
      var y= startPt.y + dy * n/100; 
      points.push({x:x,y:y}); 
     } 
    } 
    return(points); 
} 

然后你可以沿着这样的路径的每个polypoint动画的对象:

 var width=15; 
     var height=30; 
     var position=0; 
     var speed=2; 
     var rotation=0; 
     var rotationSpeed=Math.PI/60; 
     animate(); 

     var fps = 60; 
     function animate() { 
      setTimeout(function() { 
       requestAnimFrame(animate); 

       // calc new position 
       position+=speed; 
       if(position>polypoints.length-1){ 
        return; 
       } 
       var pt=polypoints[position]; 

       rotation+=rotationSpeed; 

       // draw 
       ctx.clearRect(0,0,canvas.width,canvas.height); 
       ctx.save(); 
       ctx.beginPath(); 
       ctx.translate(pt.x,pt.y); 
       ctx.rotate(rotation); 
       ctx.rect(-width/2,-height/2,15,30); 
       ctx.fill(); 
       ctx.stroke();   
       ctx.restore(); 

      }, 1000/fps); 
     } 

这个例子创建沿着各5个线段100个polypoints。由于每个线段的长度不同,因此对于较长的线段,动画将更快,对于较短的线段,动画会更慢。

如果想要更均匀的节奏动画,可以在较短的线段上计算少于100个聚点(最长的线段将有100个聚点 - 较短的线段将具有成比例的较少的聚点)您可以确定通过取任何较短的线与最长的线的长度比来确定每线的聚点。

+0

非常感谢你......现在它可以工作。我成功完成了我的项目:) – user2928041

+0

如何用bezier路径实现同样的效果? – Anubhav

+0

@Anubhav。您可以使用De Casteljau的算法绘制每个Bezier曲线上的点。干杯! – markE