Lerp() not working as expected in animation between array position values

Hello forum/guys/people who understand js better than me,
feels like kind of a noob question but I don’t think my knowledge at this point is sufficeint to figure out on my own. Either this or I’m blind to something. Really thankful if someone will spare the time to help, or point me in the right direction. <3

Basically I’m trying to lerp() between an array of values, that gets updated ( via push() method) when a certain condition verifies (using the mousePressed() as a simulation here).

The lerp() should happen between the .length - 2 and the last pushed value. The following code works to the extent of moving, but the interpolation does not happen, and I can’t figure out why.

Here’s the code: (and here web editor link just in case).

var x, y, easing, prevX, nextX;
var xPos = [1,10,20];

function setup() {
  createCanvas(400, 400);
  
  easing = 0.05;
  y = 50;
}

function draw() {
  background(220);
  
  
  prevX = xPos[xPos.length - 2];
  nextX = xPos[xPos.length - 1];
  
  x = lerp(prevX, nextX, easing);
  circle(x, y, 50, 50);
  
}

function mousePressed() {
  xPos.push(xPos[xPos.length - 1] + 50);
  console.log(xPos);
}

I tried googling lots of variants, but I don’t think I’m using the correct words. I’ve also tried without arrays but without much success, and still this seems the cleaner version.

Many thanks for your time!

1 Like

Hello @fpalla,

Could you explain a bit more what is the desired effect? I have a hard time understanding what you want to interpolate or to ease. Is it the movement of the ball?

The movement of the ball.

Basically everytime the mouse gets clicked, the ball moves by an X amount with an easing effect, instead of just “jumping” from point A to point B.

To have an easing effect, you need to lerp the current position with the desired final position.

The idea is to every time do a fraction of the remaining distance (that’s the easing factor) so you need everytime to consider to new position of your object.

The code below should help you understand how it works. At each mouse click, you move on frame into the movement. With the default value for easing at 0.25, the ball move, for every frame, a quarter of the remaining distance.

var startX, currentX, finalX, easing;

function setup() {
  createCanvas(500, 200);
  
  startX = 0;
  finalX = 500;
  easing = 0.25;
  
  // The intial position of the ball is at start X
  currentX = startX;
}

function draw() {
  background(20);
  
  // Draw ball at its current position
  fill(230);
  noStroke();
  circle(currentX, 100, 50, 50);
}

function mouseClicked() {
  // Get the remaining distance
  var remaining = finalX - currentX;
  
  // Get the new X position by moving of a fraction of the remaining
  var newX = currentX + easing * remaining;
  
  // Set the position of the circle to the new position
  currentX = newX;
}

The lerp function is just there to help you reduce the length of the code and it does basically what’s inside the mouseClicked() function. And actually, you can replace the mouse function by the following code anbd will will behave exactly the same:

function mouseClicked() {
  currentX = lerp(currentX, finalX, easing);
}

Hope it helps you understand better the easing effect.

2 Likes

Oh, now I get it. Also understood my issue. I wasn’t keeping the current position anywhere.
This is what I was after.

Thank you so much!

var x, y, easing, prevX, nextX;
var xPos = [1];

function setup() {
  createCanvas(400, 400);
  
  easing = 0.05;
  y = 50;
  x = 50;
}

function draw() {
  background(220);
  
  nextX = xPos[xPos.length - 1];
  
// Previously was prevX instead of x as the first argument, so basically kept resetting
  x = lerp(x, nextX, easing);
  circle(x, y, 50, 50);
  
}

function mousePressed() {
  xPos.push(xPos[xPos.length - 1] + 50);
  console.log(xPos);
}

@ jb4x Can I ask you if my question was clear? And if not, what could have been done better? I’m trying to get better at forums.

Thanks again anyway!

1 Like

Happy to see you manage to solve your issue :slightly_smiling_face:

Regarding your question it was not really clear at first because you never really explained what was the expected result. That’s what is the most important because your code logic can be completely wrong so explaining your code won’t help people understand what you want to do even though it is as important.

Generally speaking, start by explaining what you want to do, then expose and explain what you have tried and where you think it is bugging. Also use an MCVE so the problem is easier to explain and people can focus on the issue.

2 Likes