Skip to content

Instantly share code, notes, and snippets.

@claus
Last active January 24, 2021 08:30
Show Gist options
  • Save claus/b5e91bb35f64cd616b191cbf310387d1 to your computer and use it in GitHub Desktop.
Save claus/b5e91bb35f64cd616b191cbf310387d1 to your computer and use it in GitHub Desktop.
Proxy wrapper for tweenjs that automatically starts/stops requestAnimationFrame so you don't have to
import { tween } from './tween';
tween({ x: 0 })
.to({ x: 1 }, 200)
.onStart(() => { console.log('onStart') })
.onStop(() => { console.log('onStop') })
.onComplete(() => { console.log('onComplete') })
.onUpdate(tweenObj => { console.log('onUpdate', tweenObj.x) })
.start(1000)
import TWEEN from '@tweenjs/tween.js';
export function tween(from) {
if (typeof window.__tween__ !== 'object') {
window.__tween__ = {
rafid: null,
group: new TWEEN.Group(),
update: () => {
window.__tween__.group.update();
window.__tween__.rafid = requestAnimationFrame(
window.__tween__.update
);
},
};
}
function cancel() {
if (window.__tween__.group.getAll().length === 1) {
cancelAnimationFrame(window.__tween__.rafid);
window.__tween__.rafid = null;
}
}
const tween = new TWEEN.Tween(from, window.__tween__.group)
.onStop(cancel)
.onComplete(cancel);
const onStop = args => () => {
cancel();
if (args && args.length) {
args[0](tween);
}
};
const onComplete = args => () => {
cancel();
if (args && args.length) {
args[0](tween);
}
};
const handler = {
get(target, propKey) {
const origMethod = target[propKey];
switch (propKey) {
case 'onStop':
return function (...args) {
return origMethod.call(this, onStop(args));
};
case 'onComplete':
return function (...args) {
return origMethod.call(this, onComplete(args));
};
}
return origMethod;
},
};
if (window.__tween__.rafid === null) {
window.__tween__.update();
}
return new Proxy(tween, handler);
}
// Wait for all tweens to complete/stop
export function waitForTweens(tweenRefs, timeout = 0) {
const promises = tweenRefs.map(
tweenRef =>
new Promise(resolve => {
tweenRef.onComplete(resolve);
tweenRef.onStop(resolve);
})
);
if (timeout) {
promises.push(new Promise(resolve => setTimeout(resolve, timeout)));
}
return Promise.all(promises);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment