Running an easing animation to completion every time mouse is clicked

Im trying to get the line to rotate and ease to the target degree (targetX) then stop only when the mouse is clicked once. Subsequent mouse clicks should pick up where the last target degree and rotate the additional amount of target degrees.

Heres what I have so far. I’m not at which point in the code targetX should be reassigned or what else if any other conditionals, if any should be added. I’m using the “Easing” example, but I dont know quite know how to use the mouseClicked(or mousePressed) func in this situation.


let x = 0;
let easing = 0.05;
let targetX = 45;
    
let pressed = false;

function setup() {
  createCanvas(400, 400);
  strokeWeight(5);
}

function draw() {
  background(100);
  translate(200,200)
  if (pressed){
    
    let dx = targetX - x;
    x += dx * easing;
    
  }
  rotate( radians(x) )
  line(0,0,400,400);

}

function mousePressed() {
  pressed = true;
}

If I understand correctly you want your sketch to start with a stationary line.
On the first click the line should start to ease to the target.
On the second click the line should stop.
On the third click the line should continue easing from the position where it stopped previously.

If my understanding is correct I´d try changing

function mousePressed() {
  pressed = true;
}

to

function mousePressed() {
  pressed = !pressed; //toggling pressed between true and false
}

This would make any further clicking repeat the pattern of the second and third click

1 Like

PS:
I just copied your code to editor.p5js.org, made the change I proposed and added

if(dx < easing) targetX += 45;

inside the if(pressed) just to have a continuous animation and more chances of testing the clicking behaviour.

1 Like

Thanks for the assistance. I was able to find what I needed. I needed to add another value to the starting value upon mouse click.


let x = 0; // actual position
let targetX = 0; // target position
let easing = 0.05;
let step = 35; // value to add at each click

function setup() {
  createCanvas(800, 800);
  strokeWeight(5);
}

function draw() {
  background(100);
  translate(width / 2, height / 2);
  rotate(radians(x));
  let dx = targetX - x;
  x += dx * easing;
  line(0, 0, 400, 400);
}

function mousePressed() {
  targetX += step;
}

OK.
Seems like I misunderstood your goal, I thought you wanted the animation to stop or resume at it´s positition at the moment of the click.
But instead you wanted to update the targetX value with every click and let the animation finish before you click again.

I´m glad my input was of assistance none the less.

Is it the behaviour you want that a click while the line is still moving updates the target as well and leads to a jump in dx and thus a jump in speed?

And another idea.
In theory your values of x and targetX could get bigger and bigger, leading to (theoretical) multiple rotations. E.g. after 100 clicks your target would be 100 * 35 + 45 = 3545 resulting in 9 full circles + 305 degrees of rotation.
Even if this would not be an issue I´d consider to make

function mousePressed() {
  targetX += step;
}

into

function mousePressed() {
  targetX = (targetX + step) % 360;
}

accompanied with a

if(x > 360) x -= 360; // shorthand for if(x > 360) x = x % 360;

to be on the safe side.
If you consider the unlikely event of this causing a problem now it is easy to fix and won´t caus a problem. Correction: won´t cause this problem.
If you don´t fix it now and it does cause a problem (much) later on it may be hard to find the cause of the problem.
At least I found this to be true much too often…
It usually pays off to consider the extreme cases (a great number of clicks that may lead to an overflow in the transformation-matrix in this case)
On the other hand: multiple clicks in a short period of time could lead to a targetX that is more than 180 bigger than x. Without the modulo 360 this would mean quite a fast rotation clockwise. With the modulo 360 this would lead to counterclockwise rotation.
To solve both issues the same amount would have to be subtracted from both values at the same time.
Or to decide they are non-issues and you leave the modulos out.

I know I want the animation to start and go to completion after a single click. I haven’t yet decided if its more important if subsequent clicks while previous animation is running are ignored til the animation finishes, adds to the current rotation animation, or simply stops the animation in its tracks.