paperjs / paper.js

The Swiss Army Knife of Vector Graphics Scripting – Scriptographer ported to JavaScript and the browser, using HTML5 Canvas. Created by @lehni & @puckey
http://paperjs.org
Other
14.42k stars 1.22k forks source link

Feature Request: option to specify frame rate of animation #1581

Open stefanuddenberg opened 5 years ago

stefanuddenberg commented 5 years ago

Although the Paper.js docs say that the "onFrame" event is called up to 60 times per second, I noticed that animations go much faster on monitors with higher refresh rates, presumably since it's relying on "requestAnimationFrame". Since more and more people are using high refresh-rate monitors, it would be nice to be able to specify the frame rate, so that every user gets a consistent experience. Right now I'm resorting to some cludgy work-arounds for such monitors (e.g., checking if the time elapsed since the last frame request is large enough)...

lehni commented 5 years ago

Yes we probably should add this now. Here's a starting point: https://stackoverflow.com/a/19772220

stefanuddenberg commented 5 years ago

Here's my current solution. It takes a second or two to settle on the target frame rate, and works well on my hardware, but I still need to test it on other machines:

let last_frame_time = -1;
let curr_fps;
let frame_offset = 1.20;
const target_fps = 60;
const target_frame_duration = 1000/target_fps;
const frame_offset_increment = 0.001;
const times = []; // array of frame display times

canvas.scope.view.onFrame = function(event) {
    let now = performance.now();
    let delta = now - last_frame_time;
    if (delta >= (target_frame_duration/frame_offset)) {
        drawTheThings();

        // make sure our last frame time is a multiple of our frame duration
        last_frame_time = now - (delta % target_frame_duration);  

        // remove old frame times
        while (times.length > 0 && times[0] <= now - 1000) {
            times.shift();
        }

        times.push(last_frame_time);

        // frame rate is simply the length of frame times
        curr_fps = times.length;

        // adjust frame offset to bring fps closer to target
        if (curr_fps > target_fps) {
            frame_offset -= frame_offset_increment;
        } else if (curr_fps < target_fps) {
            frame_offset += frame_offset_increment;
        }
    }
};
christopherball commented 9 months ago

Is this request going to be addressed by chance? For example, I have a 100hz monitor, and the nearest divisible whole number <= to the hard-coded 60 fps cap is 50 in my case. This means I can't exceed 50fps no matter the performance of my system or efficiency of my code.