в цикле, который занимает менее 1 секунды.
Сколько?
все зависит от того что вы "двигаете"
Может быть все можно решить на эффектах css анимации
Про CSS написано в вопросе, про "сколько" - вопрос не по делу - это не важно.
Почему бы не добавить кастомное свойство в элементы и хранить состояние в нем?
Это интересно, как в элемент найденный getElementsByClassName() можно добавить кастомное свойство?
Но все на деле решилось проще.
Дело в том, что по сути когда происходит прокрутка, надо прекращать не один объект, а все, которые бегут.
Т.е. привязка к объекту в задаче стала не нужна.
В результате был введен счетчик и глобальный флаг досрочного выхода.
По флагу если он true организуется выход из цикла асинхронного обработчика, а в обработчике событий добавлен цикл ожидания.
Т.е. вот так.
stop = true;
do{
await timer(1); // pause on one ms to run async callbacks
}while (countOfRunning > 0);
stop = false;
И собственно все работает.
Логика решения такова, что при рандомной прокрутке по сути надо организовывать конечное состояние по последней активной прокрутке. Не важно как там работало и как было заказано до нее.
Получается отлично плавно и вполне оптимально.