DEV Community

Andreas Iosifelis
Andreas Iosifelis

Posted on

HTML5 Canvas driving

I thought I'd make a little driving agent with html5 canvas. This circle can be manipulated with the up, down, left and right keys. Maybe it'll give you some ideas for your next html5 canvas project. Have fun!

HTML

<canvas></canvas>
Enter fullscreen mode Exit fullscreen mode

CSS

* {
   padding: 0;
   margin: 0;
}
html, body, canvas {
   position: fixed;
   width: 100%;
   height: 100%;
}
Enter fullscreen mode Exit fullscreen mode

Javascript - Setup the canvas

const ctx = document.querySelector("canvas").getContext("2d");

window.onload = function () {
    try {
        ctx.W = document.documentElement.clientWidth;
        ctx.H = document.documentElement.clientHeight;
        ctx.keyState = {};
        ctx.keys = {
            LEFT: 37,
            UP: 38,
            RIGHT: 39,
            DOWN: 40,
            SPACE: 32,
        };
        ctx.frameCount = 0;
        ctx.mouseX = 0;
        ctx.mouseY = 0;
        ctx.mouseDown = false;

        ctx.randomNumber = function (min, max) {
            return Math.random() * (max - min) + min;
        };

        ctx.frame = function () {
            window.requestAnimationFrame(ctx.frame);
            ctx.fit();
            ctx.clearRect(0, 0, ctx.W, ctx.H);
            ctx.screen.update();
            ctx.screen.render();
            ctx.frameCount++;
        };

        ctx.fit = function () {
            ctx.W = document.documentElement.clientWidth;
            ctx.H = document.documentElement.clientHeight;
            ctx.canvas.width = ctx.W;
            ctx.canvas.height = ctx.H;
        };

        ctx.input = function () {
            document.body.onmousedown = function () {
                ctx.mouseDown = true;
            };

            document.body.onmouseup = function () {
                ctx.mouseDown = false;
            };

            document.body.ontouchstart = function () {
                ctx.mouseDown = true;
            };

            document.body.ontouchend = function () {
                ctx.mouseDown = true;
            };

            document.body.onmousemove = function (e) {
                ctx.mouseX = e.clientX;
                ctx.mouseY = e.clientY;
            };

            document.body.onkeydown = function (e) {
                ctx.keyState[e.keyCode] = true;
            };

            document.body.onkeyup = function (e) {
                delete ctx.keyState[e.keyCode];
            };
        };

        ctx.screen = new Screen();

        ctx.input();
        ctx.fit();
        ctx.frame();
    } catch (error) {
        console.error(error);
        console.error("Please provide a Screen constructor");
    }
};

Enter fullscreen mode Exit fullscreen mode

Javascript - Driving code

function Screen() {
    this.circle = {
        x: ctx.W / 2,
        y: ctx.H / 2,
        r: 40,
    };
    this.wheel = {
        x: 0,
        y: 0,
        r: 10,
    };

    this.xv = 1.1;
    this.yv = 1.1;

    this.angle = 0;
    this.speed = 0.05;
}

Screen.prototype.render = function () {
    ctx.fillStyle = "#555555";
    ctx.fillRect(0, 0, ctx.W, ctx.H);

    ctx.beginPath();
    ctx.strokeStyle = "#ffffff";
    ctx.arc(this.circle.x, this.circle.y, this.circle.r, 0, Math.PI * 2);
    ctx.stroke();

    ctx.beginPath();
    ctx.fillStyle = "#ffffff";
    ctx.arc(this.wheel.x, this.wheel.y, this.wheel.r, 0, Math.PI * 2);
    ctx.fill();
};

Screen.prototype.update = function () {
    this.wheel.x = this.circle.x + this.circle.r * Math.cos(this.angle);
    this.wheel.y = this.circle.y + this.circle.r * Math.sin(this.angle);
    if (ctx.keyState[ctx.keys.LEFT]) {
        this.angle -= this.speed;
    }
    if (ctx.keyState[ctx.keys.RIGHT]) {
        this.angle += this.speed;
    }

    if (ctx.keyState[ctx.keys.UP]) {
        this.circle.x += this.xv * Math.cos(this.angle);
        this.circle.y += this.yv * Math.sin(this.angle);
    }

    if (ctx.keyState[ctx.keys.DOWN]) {
        this.circle.x -= this.xv * Math.cos(this.angle);
        this.circle.y -= this.yv * Math.sin(this.angle);
    }
};

Enter fullscreen mode Exit fullscreen mode

Finished Project

Take a look at the finished project here
https://codepen.io/aiosifelisl1/pen/mdOzRpY

Discussion (0)