DEV Community

Cover image for Build a Placeholder Image Generator with JavaScript 📷 🔥
Dom (dcode)
Dom (dcode)

Posted on

Build a Placeholder Image Generator with JavaScript 📷 🔥

Everybody love's "vanilla JavaScript" so today we'll be building a Placeholder Image Generator with the help of HTML Canvas.

Video Tutorial

As always, if you prefer this tutorial in video format, feel free to watch the tutorial on my YouTube channel, dcode:

Adding the HTML

Let's start with the HTML for the user interface and input fields.

<h1>Placeholder Image Generator</h1>
<h3>Dimensions</h3>
<input type="number" class="input" id="inputWidth" value="400">
x
<input type="number" class="input" id="inputHeight" value="300">
<button id="buttonGenerate" type="button">Generate</button>

<h3>Data URL</h3>
<input type="text" class="input" id="inputDataUrl" placeholder="Please generate a placeholder image!" readonly>

<h3>Preview</h3>
<img alt="Preview Image" id="imagePreview" style="display: none">
Enter fullscreen mode Exit fullscreen mode

With this code, we've got a couple of important elements:

  • both input fields for width and height
  • a button to generate the placeholder image
  • an input field to store the generated data URL for the image
  • an image preview

Next, styling up our HTML

We can add some very basic CSS to make things look a bit prettier.

body {
    font-family: sans-serif;
}

.input {
    height: 30px;
    box-sizing: border-box;
}

#inputWidth,
#inputHeight {
    width: 100px;
}

#inputDataUrl {
    width: 100%;
    max-width: 600px;
}

#imagePreview {
    width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

Note the usage of box-sizing for the input fields. This ensures they are 30px in height no matter if we add any borders or padding. See box-sizing for more info.

Also take note of the properties in #inputDataUrl - with these properties, we are saying "let the input field take up 100% width, but don't let it go over 600px". This helps with mobile responsiveness.

Writing the JavaScript

The main function

Now that we're onto the JavaScript, our first object is to write a function which will generate a canvas element which we can size accordingly and add a background, plus text.

function createPlaceholderCanvas(width, height) {
    const element = document.createElement("canvas");
    const context = element.getContext("2d");

    element.width = width;
    element.height = height;

    // Fill in the background
    context.fillStyle = "#aaaaaa";
    context.fillRect(0, 0, element.width, element.height);

    // Place the text
    context.font = "bold 90px sans-serif";
    context.fillStyle = "#333333";
    context.textAlign = "center";
    context.textBaseline = "middle";
    context.fillText(`${width}x${height}`, element.width / 2, element.height / 2);

    return element;
}
Enter fullscreen mode Exit fullscreen mode

On the first line of this function, we're simply creating a brand new HTML canvas element which we can work on. The second line is grabbing the 2D context which we can then call methods on to add our background and text.

The next two lines are pretty self-explanatory, we're setting the desired width and height for the canvas which will be inputted by the user.

To fill in the background, we're setting a dark grey color as the fillStyle. This means the next fill command will use that color.

Speaking of, we are then using fillRect to paint the background of the canvas, starting at the top left corner and spanning the entire width and height of our canvas.

The last chunk of our function adds the text to the placeholder image. We set the font on the context, as well as the color and text-alignment options.

Now that we've defined what our font will look like, we add the text using fillText, taking advantage of template strings to generate a string which could look something like this: 400x300. By passing through a width and height divided by 2, it ensures our text gets drawn in the center.

On the last line, we're simply returning our newly-created HTML canvas element.

Making the user interface work

Now that we've written the core of the logic, we can get a reference to each of our important HTML elements:

const inputWidth = document.getElementById("inputWidth");
const inputHeight = document.getElementById("inputHeight");
const inputDataUrl = document.getElementById("inputDataUrl");
const imagePreview = document.getElementById("imagePreview");
Enter fullscreen mode Exit fullscreen mode

Next, we can react to when the "Generate" button is clicked:

document.getElementById("buttonGenerate").addEventListener("click", () => {
    const MIN_SIDE_LENGTH = 200;

    // Validation
    if (
        isNaN(inputWidth.value)
        || isNaN(inputHeight.value)
        || inputWidth.value < MIN_SIDE_LENGTH
        || inputHeight.value < MIN_SIDE_LENGTH
    ) {
        alert(`Please enter a valid image size. The minimum length is ${MIN_SIDE_LENGTH}px`);
        return;
    }

    const canvasElement = createPlaceholderCanvas(inputWidth.value, inputHeight.value);
    const dataUrl = canvasElement.toDataURL();

    inputDataUrl.value = dataUrl;
    imagePreview.src = dataUrl;
    imagePreview.style.display = "block";
    imagePreview.style.maxWidth = `${inputWidth.value}px`;
});
Enter fullscreen mode Exit fullscreen mode

As we can see, we're defining a minimum side length on the first line. If the user enters a width or height less than 200, we don't want to proceed with the generation of the placeholder image. You can change this, of course 🙂

Next, we are doing some basic validation. We check if the user has actually given us a valid number for the width and height, and if those numbers are less than the minimum side length.

If our validation fails, we tell the user and stop the execution of the function with an early return.

Once validation passes, we create the canvas element using the function defined above, and grab the data URL for the image.

The last few lines of the code involve presenting the data URL to the user and displaying the preview image to the user using the img tag. We also set a maximum width so a low resolution image doesn't stretch.

And that's it! Hope you enjoyed this tutorial. If you liked, consider checking out my YouTube channel, dcode 😁

Discussion (0)