Is it possible to pause functions?

I want to create a series of overlapping videos using P5JS, each one slightly more delayed than the previous and with delays that change their values. The issue I am finding is that there does not appear to be an easy way to pause functions.

The solution I am working on is using a for loop where millis is used with a modulo (e.g., % 5000). However, that doesn’t seem to work. I suspect because the function runs multiple times within 1 millisecond.

I’m very much at a loss. I thought timing like this would be easy in P5JS but unless I’m missing something it’s actually quite hard.

Any help would be greatly appreciated!

Thanks

It is not practical to pause functions in p5.js because the sketch is run in a single thread and if a function is paused it will affect the frame time interval and therefor the frame-rate.

If I have understood the problem correctly then the sketch below demonstrates one possible solution. NOTE: the sketch creates 20 images to use instead of videos so I can create something that can be copied and executed.

        function setup() {
            let p5canvas = createCanvas(400, 400);
            // Create 20 images to represent videos
            videos = createVideos(20);
            actionSet = new Set();
            minNbrActions = 20;
            updateActions();
        }

        function draw() {
            background(190);
            updateActions();
            // display all current videos
            [...actionSet].forEach(a => {
                if (a.visible)
                    image(a.video, a.x, a.y);
            });
        }

        function updateActions() {
            // Remove old actions
            [...actionSet].forEach(a => {
                if (a.startTime + a.duration < millis())
                    actionSet.delete(a);
            });
            // Make sure we have a store of new actions
            while (actionSet.size < minNbrActions) {
                let v = videos[floor(random(videos.length))];
                let x = random(10, width - 20 - v.width);
                let y = random(10, height - 20 - v.height);
                let st = millis() + random(500, 10000);
                let dur = random(10000, 20000);
                actionSet.add(new Action(x, y, st, dur, v));
            }
            // See which videos are visible
            [...actionSet].forEach(a => {
                if (a.startTime < millis())
                    a.visible = a.startTime > millis();
            });
        }

        // Create some images instead of videos
        function createVideos(n) {
            let v = [];
            for (let i = 0; i < n; i++) {
                let pg = createGraphics(random(70) + 70, random(70) + 70);
                let c = color(random(128) + 128, random(128) + 128, random(128) + 128);
                pg.background(c)
                pg.fill(0); pg.stroke(0);
                pg.textSize(40); pg.textAlign(CENTER, CENTER);
                pg.text(i, 0, 0, pg.width, pg.height);
                v.push(pg);
            }
            return v;
        }

        // An action details where and when a video is to be shown
        class Action {
            constructor(x, y, startTime, duration, video) {
                this.x = x;
                this.y = y;
                this.startTime = startTime;
                this.duration = duration;
                this.video = video;
                this.visible = false;
            }
        }
2 Likes

Hi Quark,

I can’t thank you enough for writing out so much code - I was expecting a pointer in the right direction, not such generous offering. I’ve read it about 15 times and I’m still trying to make sense of it. I’m clearly not that good at P5JS.

It’s way more complicated to do what I’d hope for and expected, although you explain clearly why, and it makes sense. I’m from a music background where timing is perhaps more important.

It’s led me to think that my architecture is far too complicated and I’m taking the wrong approach here. Instead of trying to sequence events in p5js I am going to use my Supercollider patch to do so and send the messages by osc to Processing.

I’m very grateful though as this code is helping to understanding p5js and how to approach such things.

1 Like