An example animation using setTimeout() function.

I made an animation including stop-motion with the 'p5.js'. Let me show you this simple method.

JavaScript 'setTimeout()' function

The point of this method is to use the JavaScript 'setTimeout()' function.


👉 この記事は日本語でも読めます。


What is the 'setTimeout()' function?

You can set a timer with the 'setTimeout()' that executes a function when the timer expires. The 'setTimeout()' is not the 'p5.js' own function but the JavaScript function.

It takes two parameters mainly.

setTimeout(func, delay);

It means that it sets a timer that executes 'func' when the 'delay' milliseconds expires.

 

How 'setTimeout()' works?

Suppose you set a 100 milliseconds timer with 'setTimeout()'. What happens to your program in that 100 milliseconds? Your code must stop and wait for the time will come?

The program code ordinally runs sequentially. For example, the code below does the 'x' calculation, the 'y' calculation, and then the circle drawing.


  let x = radius * cos(t);
  let y = radius * sin(t);
  circle(x, y, 10);

And then put the 'setTimeout()' like the code below. This code will set the timer and does the 'x' calculation through the circle drawing without stopping.


  setTimeout(funcA, delay);
  let x = radius * cos(t);
  let y = radius * sin(t);
  circle(x, y, 10);

The timer is ticking independent of the calculation or drawing. And it executes the 'funcA' when the timer expires.

I made an example animation without the 'draw()' function of the 'p5.js'. Try to guess this code draws what sort of animation.


function setup() {
  createCanvas(640, 640);
  noLoop();

  setTimeout(drawCircle, 3000, 64);
  setTimeout(brightBg, 2000);
  setTimeout(drawCircle, 1000, 255);

  background(0);
  rect(0, 0, 200, 200);
}

function brightBg() {
  background(240, 128);
}

function drawCircle(c) {
  fill(c);
  circle(width * 0.5, height * 0.5, 200);
}


 

Asynchronous functions

The 'setTimeout()' is an asynchronous function. The code using the asynchronous function executes the plural processes at the same time.

The asynchronous function is not only 'setTimeout()'. The 'loadImage()' of the 'p5.js' is one of the asynchronous functions too.

You might have seen the error 'There is no such object!' when you used the 'loadImage()' in the 'setup()' or the 'draw()'. That's because the code executes the 'setup()' and 'draw()' while the 'loadImage()' slowly loads the image file. So you should use 'loadImage()' in the 'preload()'.

Please read this for details about 'setTimeout()'.

setTimeout() | MDN

 







Stop-motion in p5.js

Let me show you the idea making a 'p5.js' stop-motion animation with 'setTimeout()'.

 

The p5.js regular animation

This animation is just an animation of rotating circles. These circles sometimes form into lines. I tried to pause these circles moving at that time.

 

setTimeout(), noLoop(), loop()

I tried to make a stop-motion with the code like this.


setTimeout(loop, 1000);
noLoop();

It sets the timer to execute the 'loop()' after 1000 milliseconds, and execute the 'noLoop()'. It makes the 1000 millisoconds stop-motion.

 

The 'p5.js' stop-motion example code.

Here is the example code of 'p5.js'. It makes stop-motion animation with the 'setTimeout()', 'noLoop()', and 'loop()'. The license is 'CC0'.



/**
 * p5.js stop-motion with setTimeout().
 *
 * @author @deconbatch
 * @version 0.1
 * @license CC0 https://creativecommons.org/publicdomain/zero/1.0/
 * p5.js 1.1.3
 * created 2022.05.29
 */

const w = 740;
const h = w;
const arms = 2;     // arm number
const nodes = 32;   // node number on arm
const armLen = 0.4; // arm length
const speed = 0.02;

let stopNum;
let timer;

function setup() {
  createCanvas(w, h);
  frameRate(30);
  noFill();
  stroke(32);
  strokeWeight(2);

  stopNum = 1;
}

function draw() {

  const time = frameCount * speed;
  
  background(224);
  translate(w * 0.5, h * 0.5);
  for (let node = 0; node < nodes; node++) {
    let nRatio = map(node, 0, nodes, 0.0, 1.0);
    let nSize = nRatio * w * 0.1;
    let radius = w * armLen * nRatio;
    for (let arm = 0; arm < arms; arm++) {
      let theta = TWO_PI * (arm + nRatio) / arms * time;
      let x = radius * cos(theta);
      let y = radius * sin(theta);
      circle(x, y, nSize);
    }
  }

  // stop-motion
  if (time >= stopNum) {
    clearTimeout(timer);
    timer = setTimeout(reLoop, 1000);
    noLoop();
  }

}

function reLoop() {
  stopNum++;
  loop();
}

 

Have fun!

I hope you will create some interesting work with this idea. Enjoy!

 

Next Post Previous Post
No Comment
Add Comment
comment url