如何通过调用 javascript 函数平滑地移动对象

问题描述 投票:0回答:1

我希望能够将对象从 {x= 0, y= 0, z= 0} 移动到 {x= 5, y= 0, z= 0} 到 {x= 5, y= 5, z= 0} 例如(通过在我的脚本中调用诸如changeX(5)之类的函数)。我通过使用 setInterval (和其他一些方法)创建一个 javascript 循环来尝试这一点。但 setInterval 是一个非阻塞函数,所以当我这样做时:

changeX(5);

changeY(5);

,我的对象从 {x= 0, y= 0, z= 0} 移动到 {x= 5, y= 5, z= 0},但没有经过 {x= 5, y= 0, z= 0}。 changeX(n) 将变量 xCo 调整为 (xCo + n) 并且我有一个循环:

function render() {
    sphere.setAttribute('position', coords());
    requestAnimationFrame(render);
}
function coords() {
    return `${xCo} ${yCo} ${zCo}`;
}

将对象放置在右侧坐标上。

有没有办法解决这个问题/有没有办法在运行时添加 A 帧动画,可以解决这个问题吗?

javascript webgl aframe
1个回答
0
投票

您可以使用最常见的动画技术,即关键帧动画,并进行线性插值。

let keyframe = new Array();
// Keyframe components: Time and X,Y,Z coordinates for that time
keyframe.push({t:0.0,x:0,y:0,z:0});
keyframe.push({t:1.5,x:5,y:5,z:0});
keyframe.push({t:2.4,x:3,y:0,z:1});

插值函数:

function getInterpolation(out, time) {

  // select proper segment
  let j = 1;
  while(time >= keyframe[j].t && j < (keyframe.length-1)) j++;
  let i = (j - 1) % keyframe.length;

  // Time phase 0 to 1 between keyframes
  let T = (time - keyframe[i].t) / (keyframe[j].t - keyframe[i].t);

  // linear interpolation
  out.x = keyframe[i].x + T * (keyframe[j].x - keyframe[i].x);
  out.y = keyframe[i].y + T * (keyframe[j].y - keyframe[i].y);
  out.z = keyframe[i].z + T * (keyframe[j].z - keyframe[i].z);
}

使用方法:

let time = 0.0;
let coords = {x:0,y:0,z:0};

function render() {

  time += 0.016667; // fake clock

  getInterpolation(coords, time);

  sphere.setAttribute('position', coords);
  requestAnimationFrame(render);
}

你对它的工作原理有了大概的了解,你可以优化一些部分,使其更加模块化,你还可以实现一个实时计时器,添加一个循环过程。您还可以使用线性插值之外的其他插值,但这将是另一个(更数学的)主题。

© www.soinside.com 2019 - 2024. All rights reserved.