aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Harris <bjh21@bjh21.me.uk>2022-10-26 10:05:04 +0100
committerBen Harris <bjh21@bjh21.me.uk>2022-11-09 21:40:27 +0000
commit7982002a644328164bf0f77bf489876ad012e90d (patch)
tree496e54d8dc6e6bd2c0fcd08f8f9a377c1021f830
parentc5a2446fae603a480de58b912fa349549bd9f247 (diff)
downloadpuzzles-7982002a644328164bf0f77bf489876ad012e90d.zip
puzzles-7982002a644328164bf0f77bf489876ad012e90d.tar.gz
puzzles-7982002a644328164bf0f77bf489876ad012e90d.tar.bz2
puzzles-7982002a644328164bf0f77bf489876ad012e90d.tar.xz
js: Switch to window.requestAnimationFrame() for timing
This is an API specifically designed for the purposes of timing animations. Unlike setInterval, it tries to synchronise with the screen refresh rate. It naturally passes us timing information, saving the need to construct a Date object every frame. It has the nice feature that browsers (at least Firefox 91) will call it less frequently when the puzzle page isn't visible, which saves CPU time in puzzles that run a timer continuously.
-rw-r--r--emcclib.js34
-rw-r--r--emccpre.js4
2 files changed, 23 insertions, 15 deletions
diff --git a/emcclib.js b/emcclib.js
index 84336f3..497451a 100644
--- a/emcclib.js
+++ b/emcclib.js
@@ -194,29 +194,37 @@ mergeInto(LibraryManager.library, {
/*
* void js_activate_timer();
*
- * Start calling the C timer_callback() function every 20ms.
+ * Start calling the C timer_callback() function every frame.
*/
js_activate_timer: function() {
- if (timer === null) {
- timer_reference_date = (new Date()).valueOf();
- timer = setInterval(function() {
- var now = (new Date()).valueOf();
- timer_callback((now - timer_reference_date) / 1000.0);
- timer_reference_date = now;
- return true;
- }, 20);
+ if (!timer_active) {
+ timer_reference = performance.now();
+ var frame = function(now) {
+ current_timer = null;
+ timer_callback((now - timer_reference) / 1000.0);
+ /* The callback may have deactivated the timer. */
+ if (timer_active) {
+ timer_reference = now;
+ current_timer = window.requestAnimationFrame(frame);
+ }
+ }
+ timer_active = true;
+ current_timer = window.requestAnimationFrame(frame);
}
},
/*
* void js_deactivate_timer();
*
- * Stop calling the C timer_callback() function every 20ms.
+ * Stop calling the C timer_callback() function every frame.
*/
js_deactivate_timer: function() {
- if (timer !== null) {
- clearInterval(timer);
- timer = null;
+ if (timer_active) {
+ timer_active = false;
+ if (current_timer !== null) {
+ window.cancelAnimationFrame(current_timer);
+ current_timer = null;
+ }
}
},
diff --git a/emccpre.js b/emccpre.js
index 22c462b..f9f0c18 100644
--- a/emccpre.js
+++ b/emccpre.js
@@ -90,8 +90,8 @@ var midpoint_test_str = "ABCDEFGHIKLMNOPRSTUVWXYZ0123456789";
var midpoint_cache = [];
// Variables used by js_activate_timer() and js_deactivate_timer().
-var timer = null;
-var timer_reference_date;
+var timer_active = false;
+var timer_reference;
// void timer_callback(double tplus);
//