start . me .
Directory path . web , canvas .

HTML Document File : vector.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>vector</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>

<canvas id="surface" style="border:1px solid black;"></canvas>

<div> use arrow keys: < & > head rotation, ^ go ahead. </div>

<div class="controls">
<button data-event="left">left</button>
<button data-event="right">right</button>
<button data-event="forward">ahead</button>
</div>
<style> .controls button { padding: 2em; user-select: none; } </style>

<script>
var surface = document.querySelector("canvas#surface")
var ctx = surface.getContext("2d")

var position = [surface.width/2, surface.height/2]
var rotation = 3*Math.PI/2

function draw_surface(){

    ctx.clearRect(0, 0, surface.width, surface.height)

    ctx.beginPath()
    ctx.arc(position[0], position[1], 8, 0, 2 * Math.PI)
    ctx.stroke()

    var direction=[ Math.cos(rotation), Math.sin(rotation) ]
    ctx.moveTo(position[0], position[1])
    ctx.lineTo(position[0] + direction[0]*30, position[1] + direction[1]*30)
    ctx.stroke()

}
draw_surface()

var associations={ "ArrowLeft":"left", "ArrowRight":"right", "ArrowUp":"forward" }

var events={left,right,forward}
var eventInterval = {}

function startEvent(eventType){
    stopEvent(eventType)
    if(eventType=="left") stopEvent("right"); if(eventType=="right") stopEvent("left")
    function intervalCallback(){ events[eventType]() }
    intervalCallback()
    eventInterval[eventType] = setInterval( intervalCallback , 100 )
}
function stopEvent(eventType){
    clearInterval(eventInterval[eventType])
}

for(var button of document.querySelectorAll(".controls button")){
    
    function buttonEventType(eventListened){
        var button = eventListened.target
        var eventType = button.dataset.event
        return eventType
    }

    function buttonDown(eventListened){ 
        startEvent(buttonEventType(eventListened))
    }
    function buttonUp(eventListened){
        stopEvent(buttonEventType(eventListened))
    }

    button.addEventListener("touchstart", buttonDown )
    button.addEventListener("touchend", buttonUp )

    button.addEventListener("mousedown", buttonDown )
    button.addEventListener("mouseup", buttonUp )
}

var keyboardKeys = {}

document.addEventListener("keyup", function(eventKeyboard) {
    keyboardKeys[eventKeyboard.key] = false

    if(eventKeyboard.key in associations) stopEvent( associations[eventKeyboard.key] )
})

document.addEventListener("keydown", function(eventKeyboard) {
    if(eventKeyboard.key in keyboardKeys && keyboardKeys[eventKeyboard.key]==true ) return
    keyboardKeys[eventKeyboard.key] = true

    if(eventKeyboard.key in associations) startEvent( associations[eventKeyboard.key] )
})

function left(){
    rotation -= Math.PI/32
    draw_surface()
}
function right(){
    rotation += Math.PI/32
    draw_surface()
}

function forward(){
    var direction = [ Math.cos(rotation), Math.sin(rotation) ]
    position[0] += direction[0]*3
    position[1] += direction[1]*3
    draw_surface()
}
</script>

<script src="/web/show-source.js"></script>

</body>
</html>