Create a Custom Upload Button in JavaScript

For my pixel art app, Pixel V, I want to make it easy to use a reference image layered behind or on top of the user’s drawing. For this tutorial, I’m going to go over how to upload files to a website with HTML and JavaScript, as well as how to style that button with CSS.

In HTML, there’s an <input type=”file”/> which we’ll use for getting our file, but it’s not straightforward to style it. So, we’ll create a label for it and style the label instead, while hiding the input element itself.

<label for="file-upload" class="custom-file-upload btn">
Upload Background
</label>
<input type="file" id="file-upload"/>
input[type="file"] {
display: none;
}
.custom-file-upload {
display: inline-block;
margin-left: 24px;
font-size: 20px;
width: 232px;
height: auto;
cursor: pointer;
}

Most of this CSS is totally up to you, but the important part is that input[type="file"] has display: none;.

let uploadBtn = document.querySelector("#file-upload");uploadBtn.addEventListener("change", changeBG);function changeBG() {
let reader;
if (this.files && this.files[0]) {
reader = new FileReader();
reader.onload = (e) => {
bgObject.img.src = e.target.result;
drawCanvas();
};
reader.readAsDataURL(this.files[0]);
}
}

After you select your file, changing the input, this function runs that first confirms there is indeed a file to read, then creates a new FileReader object which you use to read the file, in this case an image file. Because we want the image file as a DataURL, we use .readAsDataURL to read the file. Then in the asynchronous onload function we can set that image as the source for the Image object that we want. In my case, since it’s part of an HTML Canvas set up, I then trigger a re-render of the canvas.