use requestAnimationFrame instead of setTimeout