setTimeout не дает точного запуска функции через указанное количество миллисекунд,
поэтому для анимаций, вместо setTimeout используйте
window.requestAnimationFrame;
плюс ко всему, смещение на момент времени должно расчитываться на основании времени, прошедшего с момента старта.