我有一个对象数组,其中每个对象都包含特定矩形的详细信息。我制作了一个动画矩形函数,这样当给函数 targetX 和 targetY 位置以及数组中对象的索引时,它会将矩形动画到该位置。
函数这样做是成功的,但是当我将该索引(比如 0)与数组的另一个索引(让它为 1)交换时,那个特定的矩形(索引 1 的矩形)也移动到我为前一个矩形设置动画的位置(索引 0 的矩形)。它就像索引链接到那个特定位置。
这是我的代码的最小可重现示例
let arr = [
{
value:3,
height: -204,
width: 50,
posX: 315,
posY: 350,
color: '#8D72E1'
},
{
value: 1,
height: -68,
width: 50,
posX: 365,
posY: 350,
color: '#8D72E1'
}
];
function setup() {
createCanvas(windowWidth, windowHeight * 2);
background(220);
button = createButton("Swap");
button.position(0,0);
button.mousePressed(swap);
}
function addElement()
{
drawObj();
moveRectToPosition(200, 200, 0.09, 0);
}
function moveRectToPosition(targetX, targetY, speed, index) {
let isAnimationRunning = true;
function animate() {
if (!isAnimationRunning) {
return;
}
let distanceX = targetX - arr[index].posX;
let distanceY = targetY - arr[index].posY;
let distance = dist(arr[index].posX, arr[index].posY, targetX, targetY);
if (distance === 0) {
isAnimationRunning = false;
return;
}
let moveX = distanceX * speed;
let moveY = distanceY * speed;
arr[index].posX += moveX;
arr[index].posY += moveY;
background(220);
drawObj();
requestAnimationFrame(animate);
}
animate();
}
function drawObj()
{
for(let i=0;i<arr.length;i++)
{
fill(arr[i].color);
rect(arr[i].posX,arr[i].posY,arr[i].width,arr[i].height,8);
}
}
function swap()
{
let temp = arr[1];
arr[1] = arr[0];
arr[0] = temp;
}
setTimeout(() => {
addElement();
},500);
html, body { margin: 0; padding: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>
这是这段代码的预览: https://editor.p5js.org/ayushap05/full/hm4ty5Qck
当按下交换按钮时,第二个矩形也从它的位置移动到第一个矩形的位置。
我认为问题可能出在交换对象时,但是在交换前后进行控制台日志后我发现交换对象后,动画函数开始自动调用。
一个问题是距离在这里永远不会完全达到零:
let distance = dist(arr[index].posX, arr[index].posY, targetX, targetY);
if (distance === 0) {
isAnimationRunning = false;
return;
}
浮点的性质是这样的,当你将位置越来越接近目标,剩余距离的一小部分:
let moveX = distanceX * speed;
let moveY = distanceY * speed;
arr[index].posX += moveX;
arr[index].posY += moveY;
distance
的值逐渐变小,但不会达到零。因此,当您交换数组中的两个元素时,animate
函数仍在运行,并将索引 0 处的任何内容移动到原始调用中指定的位置 moveRectToPosition
:
let arr = [
{
value:3,
height: -204,
width: 50,
posX: 315,
posY: 350,
color: '#8D72E1'
},
{
value: 1,
height: -68,
width: 50,
posX: 365,
posY: 350,
color: '#8D72E1'
}
];
let distDisp;
function setup() {
createCanvas(windowWidth, windowHeight * 2);
background(220);
button = createButton("Swap");
button.position(10,10);
button.mousePressed(swap);
distDisp = createInput('');
distDisp.position(10, 50);
distDisp.size(200);
}
function addElement()
{
drawObj();
moveRectToPosition(200, 200, 0.09, 0);
}
function moveRectToPosition(targetX, targetY, speed, index) {
let isAnimationRunning = true;
function animate() {
if (!isAnimationRunning) {
return;
}
let distanceX = targetX - arr[index].posX;
let distanceY = targetY - arr[index].posY;
let distance = dist(arr[index].posX, arr[index].posY, targetX, targetY);
if (distance === 0) {
isAnimationRunning = false;
distDisp.value('ZERO');
return;
} else {
distDisp.value(distance);
}
let moveX = distanceX * speed;
let moveY = distanceY * speed;
arr[index].posX += moveX;
arr[index].posY += moveY;
background(220);
drawObj();
requestAnimationFrame(animate);
}
animate();
}
function drawObj()
{
for(let i=0;i<arr.length;i++)
{
fill(arr[i].color);
rect(arr[i].posX,arr[i].posY,arr[i].width,arr[i].height,8);
}
}
function swap()
{
let temp = arr[1];
arr[1] = arr[0];
arr[0] = temp;
}
setTimeout(() => {
addElement();
},500);
html, body { margin: 0; padding: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>