JSFiddle - React, Tailwind, and code Playground
HTML
<div class="starship" id="starship"></div>
CSS
#starship {
position: absolute;
width: 100px;
height: 100px;
background-color: blue;
}
JavaScript
window.onerror = alert;
var right = false,
left = false,
top = false,
bottom = false,
moving = false,
last,
el = document.getElementById('starship');
window.addEventListener('keydown', function(e) {
switch (e.keyCode) {
case 37:
if (!right) left = true;
start();
break;
case 38:
if (!bottom) top = true;
start();
break;
case 39:
if (!left) right = true;
start();
break;
case 40:
if (!top) bottom = true;
start();
break;
}
});
window.addEventListener('keyup', function(e) {
switch (e.keyCode) {
case 37:
left = false;
stop();
break;
case 38:
top = false;
stop();
break;
case 39:
right = false;
stop();
break;
case 40:
bottom = false;
stop();
break;
}
})
function start() {
if (moving) return;
if (!(left || top || bottom || right)) return;
moving = true;
last = performance.now();
requestAnimationFrame(i);
}
function stop() {
if (!moving) return;
if (left || right || top || bottom) return;
moving = false;
}
function i(now) {
t = now - last;
if (left)
el.style.left = (parseFloat(el.style.left || 0) - 0.25 * t) + 'px';
if (right)
el.style.left = (parseFloat(el.style.left || 0) + 0.25 * t) + 'px';
if (top)
el.style.top = (parseFloat(el.style.top || 0) - 0.25 * t) + 'px';
if (bottom)
el.style.top = (parseFloat(el.style.top || 0) + 0.25 * t) + 'px';
last = now;
if (moving) requestAnimationFrame(i);
}