1

我在画布元素的一层中创建了一个静态背景,然后尝试移动我创建的矩形对象以穿过圆柱体、管道,然后它应该落入管道末端的小圆柱体中。我可以沿直线移动它,但我必须旋转物体(比如 -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>

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

4

1 回答 1

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 个多点 - 较短的线将按比例减少多点)您可以通过以下方式确定每条线的多点数取任何较短线与最长线的长度比。

于 2013-10-28T17:51:51.233 回答