use requestAnimationFrame for better animations