Skip to content

Instantly share code, notes, and snippets.

@rhysburnie
Last active December 1, 2017 10:23
Show Gist options
  • Save rhysburnie/065452acfa4582eb0f9ebabb595be984 to your computer and use it in GitHub Desktop.
Save rhysburnie/065452acfa4582eb0f9ebabb595be984 to your computer and use it in GitHub Desktop.
Small frame looper for quick setup
function Looper(update, targetFPS = 30, autoplay = true) {
let updating = false;
this.autoplay = autoplay;
this.targetFPS = targetFPS;
const advanceFrame = () => {
updating = true;
const next = () => {
const delay = this.autoplay ? 1000 / (this.targetFPS || 30) : 0;
setTimeout(() => updating = false, delay);
};
update(next);
};
const tick = () => {
if (this.autoplay) requestAnimationFrame(tick);
if (updating) return;
advanceFrame();
};
this.start = tick;
this.advanceFrame = advanceFrame;
this.start();
// utility, if you are using dat.GUI
this.addToGUI = function addToGUI(gui, instance, label = 'Loop settings') {
if (!gui || typeof gui.addFolder !== 'function') {
return;
}
const folder = gui.addFolder(label);
folder.add(instance, 'autoplay').onChange(play => {
if (play) instance.start();
});
folder.add(instance, 'targetFPS', 1, 60);
folder.add(instance, 'advanceFrame');
};
}
'use strict';function Looper(a){var f=this,b=1<arguments.length&&arguments[1]!==void 0?arguments[1]:30,c=2<arguments.length&&arguments[2]!==void 0?arguments[2]:!0,d=!1;this.autoplay=c,this.targetFPS=b;var e=function(){d=!0;a(function h(){var i=f.autoplay?1e3/(f.targetFPS||30):0;setTimeout(function(){return d=!1},i)})},g=function(){f.autoplay&&requestAnimationFrame(g);d||e()};this.start=g,this.advanceFrame=e,this.start(),this.addToGUI=function(i,j){var k=2<arguments.length&&arguments[2]!==void 0?arguments[2]:'Loop settings';if(i&&'function'==typeof i.addFolder){var l=i.addFolder(k);l.add(j,'autoplay').onChange(function(m){m&&j.start()}),l.add(j,'targetFPS',1,60),l.add(j,'advanceFrame')}}}
@rhysburnie
Copy link
Author

For usage in jsbin, codepen etc with utility for dat.GUI control.

Example:

const gui = new dat.GUI();

function Thing() {
  this.iterations = 0;
  
  const $thing = document.createElement('div');
  $thing.classList.add('thing');
  document.body.appendChild($thing);
  this.$el = $thing;
}

const thing = new Thing();
gui.add(thing, 'iterations').listen();

function update(next) {
  thing.iterations += 1;
  thing.$el.innerHTML = thing.iterations;
  next();
}

const looper = new Looper(update, 15, true);
looper.addToGUI(gui, looper);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment