0

I would like to calculate the position of $x to give an acceleration / deceleration effect to a square in this animated gif.

Currently, the only thing I can do is a constant displacement of this square.

How to find the value of $x to give this acceleration / deceleration effect for each animated GIF frame?

$fps = 25;

$initialVelocity = 5;
$finalVelocity = 0;
$duration = 2000;
$distance = 300;

$nbFrames = $duration / 1000 * $fps;

$imFrames = new Imagick();
for ($i = 0; $i < $nbFrames; $i++)
{
    $currentTime = $duration / ($nbFrames - 1) * $i;
        
    $x = $distance / $duration * $currentTime; // How i can apply velocity on the $x coordinate ?
    
    $draw = new ImagickDraw();
    $draw->setFillColor('#ff0000');
    $draw->rectangle(
        $x,
        10,
        $x + 10,
        20
    );
    
    $imFrame = new Imagick();
    $imFrame->newImage(400, 40, '#5b5b5b');
    $imFrame->drawImage($draw);
    $imFrame->setImageDelay(100 / $fps);
    $imFrame->setImageFormat('gif');
    $imFrame->setImageDispose(3); // clean previous frame
    
    $imFrames->addImage($imFrame);
}

header('Content-type: image/gif');
$imFrames->setFormat('gif');
echo $imFrames->getImagesBlob();
exit();

EDIT :

I do not happen.

I would like it to move from 0 to x but my square makes back trips.

animated.gif

$fps = 25;

$initialVelocity = 6;
$finalVelocity = 0;
$duration = 2000;
$distance = 100;
$acceleration = ($finalVelocity - $initialVelocity) / $duration;
$nbFrames = $duration / 1000 * $fps;

$imFrames = new imagick();
for ($i = 0; $i < $nbFrames; $i++)
{
    $timePerFrame = $duration / ($nbFrames - 1);
    $currentTime = $timePerFrame * $i;
        
    $velocity = $initialVelocity + ($acceleration * $currentTime);
    $x = $distance / $duration * $currentTime;
    $x *= $velocity;
        
    $draw = new ImagickDraw();
    $draw->setFillColor('#ff0000');
    $draw->rectangle(
        $x,
        10,
        $x + 10,
        20
    );
    
    $imFrame = new Imagick();
    $imFrame->newImage(400, 40, '#5b5b5b');
    $imFrame->drawImage($draw);
    $imFrame->setImageDelay(100 / $fps);
    $imFrame->setImageFormat('gif');
    $imFrame->setImageDispose(3); // clean previous
    
    $imFrames->addImage($imFrame);
}

header('Content-type: image/gif');
$imFrames->setFormat('gif');
echo $imFrames->getImagesBlob();
exit();
Nicolas
  • 11
  • 1
  • 1
    Did you just erase your question to repost it? Please don't do that. The comments on your previous question actually contained huge hints on how you could have solved your problem. But you just erased them. – Stef Sep 07 '21 at 09:35
  • You need to vary the velocity in constant increments. Then you add to x the current speed times the time increment. E.g. velocities 10, 20, 30, 40, 50 and displacements 1000, 1010, 1030, 1060, 1100, 1150. –  Sep 07 '21 at 09:36
  • @Step I did not erase anything. Are you sure it's my post? – Nicolas Sep 07 '21 at 10:05
  • @YvesDaoust I have a hard time putting it in place. Could you give me an example with the code I gave? – Nicolas Sep 07 '21 at 10:07
  • see https://stackoverflow.com/a/53637567/2521214 ... you need to have `acc=???; vel+=acc*dt; pos+=vel*dt;` instead of just `pos=...` – Spektre Sep 07 '21 at 10:34
  • @Spektre I updated my question to explain where I can not do what I want. – Nicolas Sep 07 '21 at 21:02
  • @Nicolas you still did it wrong ... the velocity is computed OK however you still need to integrate (`$x+=...`) the position instead of computing it from scract (`$x=...`) each frame (or you would need to convert your formula to finite time integral like you did for velocity) you should have something like this: `$x += $velocity/$fps;` without the `$x *= $velocity;` The velocity could be computed in this manner too so something like this `$velocity += $acceleration/$fps;` and do not forget to init both values before the for loop. – Spektre Sep 08 '21 at 06:32

0 Answers0