DEV Community

Andreas Iosifelis
Andreas Iosifelis

Posted on

4 2

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

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more