How to Draw on Canvas and Save the Result Using Vanilla JavaScript

πŸ™‚ Like
πŸ™‚Like πŸ₯°Love 🧐Watching this 🀨Suspicious πŸ˜’Meh 😑Angry

This was part of a complex drawing project, which is not relevant right now. The idea was to have a fully configurable canvas, where you could pick colours and sizes to write and draw anything.

I’m sure this has been done before, so I tried to keep my code to a minimum, while making sure the code has no dependencies and it’s modern and fast.

Here’s the HTML structure:

<div class="container">
    <canvas width="800%" height="400px" id="art"></canvas>
    <div id="buttons">
        <a id="reset">Restart</a>

        <div id="red" class="color"></div>
        <div id="blue" class="color"></div>
        <div id="green" class="color"></div>
        <div id="purple" class="color"></div>
        <div id="orange" class="color"></div>
        <div id="black" class="color"></div>
        <div id="white" class="color"></div>

        <div id="default" class="color">1</div>
        <div id="three" class="color">3</div>
        <div id="five" class="color">5</div>
        <div id="ten" class="color">10</div>
        <div id="fifteen" class="color">15</div>
        <div id="twenty" class="color">20</div>

        <a id="downloadLnk" class="color" href="#" download="illustration.png">Export</a>
    </div>
</div>

Here’s the CSS:

canvas {
    border: 1px solid #cbcbcb;
    background: #ecf0f1;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.25);
    cursor: crosshair;
}
.container {
    position: relative;
}
#buttons {
    position: absolute;
    top: 5px;
    left: 10px;
}
#reset {
    font-size: 24px;
    margin: 10px 10px 0 10px;
    float: left;
    cursor: pointer;
    color: #7f8c8d;
}
#downloadLnk {
    margin: 10px 10px 0 10px;
    color: #7f8c8d;
}
.color {
    color: #7f8c8d;
    width: 26px;
    height: 26px;
    line-height: 26px;
    float: left;
    margin: 10px 1px 0 0;
    cursor: pointer;
    text-align: center;
}
#red {
    background-color: #e74c3c;
}
#blue {
    background-color: #3498db;
}
#green {
    background-color: #2ecc71;
}
#purple {
    background-color: #9b59b6;
}
#orange {
    background-color: #f39c12;
}
#black {
    background-color: black;
}
#white {
    background-color: white;
}

And here’s the JavaScript functionality:

const canvas = document.getElementById('art');
const ctx = canvas.getContext('2d');

function getMousePos(canvas, evt) {
    let rect = canvas.getBoundingClientRect();
    return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
    };
}

function mouseMove(evt) {
    let mousePos = getMousePos(canvas, evt);

    ctx.lineTo(mousePos.x, mousePos.y);
    ctx.stroke();
}

canvas.addEventListener('mousedown', (evt) => {
    let mousePos = getMousePos(canvas, evt);

    ctx.beginPath();
    ctx.moveTo(mousePos.x, mousePos.y);
    evt.preventDefault();
    canvas.addEventListener('mousemove', mouseMove, false);
});

canvas.addEventListener('mouseup', () => {
    canvas.removeEventListener('mousemove', mouseMove, false);
}, false);

document.getElementById('reset').addEventListener('click', () => {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
}, false);

const colors = ['red', 'blue', 'green', 'purple', 'orange', 'black', 'white'];
const size = [1, 3, 5, 10, 15, 20];
const sizeNames = ['default', 'three', 'five', 'ten', 'fifteen', 'twenty'];

function listener(i) {
    document.getElementById(colors[i]).addEventListener('click', () => {
        ctx.strokeStyle = colors[i];
    }, false);
}

function fontSizes(i) {
    document.getElementById(sizeNames[i]).addEventListener('click', () => {
        ctx.lineWidth = size[i];
    }, false);
}

for (let i = 0; i < colors.length; i++) {
    listener(i);
}

for (let i = 0; i < size.length; i++) {
    fontSizes(i);
}

document.getElementById('downloadLnk').addEventListener('click', () => {
    let image = canvas.toDataURL("image/png");
    this.href = image;
});

See a live demo here.

While I’m not particularly happy with the CSS and I know there’s room for improvement, the code is pretty fast and does the job. It’s also mobile compatible.

Find more JavaScript tutorials, code snippets and samples here or more jQuery tutorials, code snippets and samples here.

Added by Ciprian on Saturday, October 3, 2020 in Blog, JavaScript

Unlimited Automated Page Speed Monitoring & Tracking.
Use SpeedFactor to track your website. It’s simple and reliable.
See how real people experience the speed of your website. Then find (and fix) your web performance problems.
Get Started

Related Articles

%d bloggers like this:
Privacy Policy