Немного упростил и осовременил (с Promise и async/await)
<div id="moved" style="position: absolute;width:30px;height: 30px;background: red;"></div>
<br>
<input type="button" onclick="but1()" value="кнопка 1"> <br>
<script type="text/javascript">
function but1 (){
const element = document.getElementById("moved");
animateMove( element , 800 , 100 , 1500)
.then ( () => animateMove( element , -750 , 10 , 200) )
.then ( () => animateMove( element , 150 , -60 , 1000) )
.then ( () => {
element.style.background = ("#" + ( Math.random() * (999-100)+100 )).substr(0,4) ;
element.style.top = "30px";
element.style.left = "100px";
})
}
/* С async/await
async function but1 (){
const element = document.getElementById("moved");
await animateMove( element , 800 , 100 , 1500);
await animateMove( element , -750 , 10 , 200);
await animateMove( element , 150 , -60 , 1000);
element.style.background = ("#" + ( Math.random() * (999-100)+100 )).substr(0,4) ;
element.style.top = "30px";
element.style.left = "100px";
}
*/
function animateMove ( element , x , y , time = 1000){
const statrX = element.offsetLeft;
const startY = element.offsetTop;
const startTime = performance.now();
return new Promise ( (resolve) => {
const animate = function (timenow){
const EA = (timenow - startTime) / time;
if (EA > 1) {
resolve();
} else {
element.style.left = startX + (x * EA) + "px";
element.style.top = startY + (y * EA) + "px";
requestAnimationFrame(animate );
}
};
animate(startTime);
})
}
</script>