沿HTML5画布中的路径旋转移动的对象

时间:2013-10-28 12:49:46

标签: javascript jquery html html5 canvas

我在canvas元素的一个层中创建了一个静态背景,然后尝试移动我创建的矩形对象来通过圆柱体,管道然后它应该落入到底部的小圆柱体中管道。我能够沿直线移动它,但我必须旋转物体(比如-25度),然后使其水平移动(180度,当它在管道内向y方向行进时)。 代码:

<!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>

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

1 个答案:

答案 0 :(得分:4)

沿路径设置对象动画的一种方法是沿该路径计算多点。

然后,对于每个动画循环,将对象前进到下一个多边形点。

这是一个演示: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});

您可以计算沿该系列线段的多点,如下所示:

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);
}

然后您可以沿着路径的每个多边形点为对象设置动画,如下所示:

        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个多点。由于每个线段的长度不同,因此对于较长的线段,动画将更快,对于较短的线段,动画将更慢。

如果你想要一个更均匀起搏的动画,你可以在较短的线段上计算少于100个多边形点(最长的线条线将有100个多边形点 - 较短的线条将具有相应较少的多边形点)你可以确定多少个多边形点通过取任何较短线与最长线的长度比来获得每条线。

相关问题