gpt4 book ai didi

javascript - 在 HTML5 Canvas 中沿路径旋转移动对象

转载 作者:行者123 更新时间:2023-11-30 10:25:44 28 4
gpt4 key购买 nike

我在 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>

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

最佳答案

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

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

这是一个演示: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 个多点——较短的线将按比例减少多点)你可以确定有多少个多点每行通过取任何较短的行与最长的行的长度比。

关于javascript - 在 HTML5 Canvas 中沿路径旋转移动对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19635258/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com