How to Build QR Code Scanner or Reader using JavaScript

qrcode scanner

In this guide, we’ll walk through the process of creating a QR Code Scanner or Reader using HTML, CSS, and JavaScript. We’ll dissect the provided code to understand its structure, styling, and functionality.

HTML Structure:

The HTML structure defines the layout and components of the QR Code Scanner. Let’s break it down:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8" />
    <title>QR Code Scanner or Reader</title>
    <link rel="stylesheet" href="style.css" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"
    />
  </head>
  <body>
    <div class="wrapper">
      <form action="#">
        <input type="file" hidden />
        <img src="#" alt="qr-code" />
        <div class="content">
          <i class="fas fa-cloud-upload"></i>
          <p>Upload QR Code to Read</p>
        </div>
      </form>
      <div class="details">
        <textarea spellcheck="false" disabled></textarea>
        <div class="buttons">
          <button class="close">Close</button>
          <button class="copy">Copy Text</button>
        </div>
      </div>
    </div>
  </body>
</html>
HTML
  • Document Type Declaration and Head Section:
    • Defines the document type and includes metadata like character set, title, viewport settings, and links to external stylesheets and icon libraries.
  • Body Section:
    • Contains a .wrapper div that wraps the entire scanner interface.
    • Inside the wrapper, there’s a form element for selecting and uploading the QR Code image file.
    • Additionally, there’s a textarea to display the scanned QR Code content and buttons for closing the scanner and copying the text.

CSS Styling:

The CSS styling is responsible for the visual appearance and layout of the QR Code Scanner. Here’s a breakdown of the key styles:

@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap");
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}
body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 0 10px;
  background: #1e1c27;
}
.wrapper {
  height: 270px;
  width: 420px;
  border-radius: 7px;
  background: #0b85ff;
  padding: 30px 30px 35px;
  transition: height 0.2s ease;
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
.wrapper.active {
  height: 525px;
}
.wrapper form {
  height: 210px;
  display: flex;
  cursor: pointer;
  user-select: none;
  text-align: center;
  border-radius: 7px;
  background: #fff;
  align-items: center;
  justify-content: center;
  transition: height 0.2s ease;
}
.wrapper.active form {
  height: 225px;
  pointer-events: none;
}
form img {
  display: none;
  max-width: 148px;
}
.wrapper.active form img {
  display: block;
}
.wrapper.active form .content {
  display: none;
}
form .content i {
  color: #0b85ff;
  font-size: 55px;
}
form .content p {
  color: #0b85ff;
  margin-top: 15px;
  font-size: 16px;
}
.wrapper .details {
  opacity: 0;
  margin-top: 25px;
  pointer-events: none;
}
.wrapper.active .details {
  opacity: 1;
  pointer-events: auto;
  transition: opacity 0.5s 0.05s ease;
}
.details textarea {
  width: 100%;
  height: 128px;
  outline: none;
  resize: none;
  color: #fff;
  font-size: 18px;
  background: none;
  border-radius: 5px;
  padding: 10px 15px;
  border: 1px solid #fff;
}
textarea::-webkit-scrollbar {
  width: 0px;
}
textarea:hover::-webkit-scrollbar {
  width: 5px;
}
textarea:hover::-webkit-scrollbar-track {
  background: none;
}
textarea:hover::-webkit-scrollbar-thumb {
  background: #fff;
  border-radius: 8px;
}
.details .buttons {
  display: flex;
  margin-top: 20px;
  align-items: center;
  justify-content: space-between;
}
.buttons button {
  height: 55px;
  outline: none;
  border: none;
  font-weight: 500;
  font-size: 16px;
  cursor: pointer;
  color: #0b85ff;
  border-radius: 5px;
  background: #fff;
  transition: transform 0.3s ease;
  width: calc(100% / 2 - 10px);
}
.buttons button:active {
  transform: scale(0.95);
}

@media (max-width: 450px) {
  .wrapper {
    padding: 25px;
    height: 260px;
  }
  .wrapper.active {
    height: 520px;
  }
}
CSS
  • Global Styles:
    • Resets default browser styles and sets the font family.
    • Defines a minimum height for the body and sets the background color.
  • Wrapper Styles:
    • Sets the dimensions, border radius, background color, and shadow of the scanner container.
    • Provides transition effects for smooth height adjustments.
  • Form Styles:
    • Styles the form element to display as a clickable area with an icon and text prompting the user to upload a QR Code image.
    • Adjusts styles when the scanner is active, such as hiding the content and displaying the uploaded QR Code image.
  • Details Styles:
    • Styles the textarea to display scanned QR Code content.
    • Provides styling for buttons to close the scanner and copy the scanned text.

JavaScript Functionality:

The JavaScript code adds interactivity and functionality to the QR Code Scanner. Key functionalities include:

const wrapper = document.querySelector(".wrapper"),
  form = document.querySelector("form"),
  fileInp = form.querySelector("input"),
  infoText = form.querySelector("p"),
  closeBtn = document.querySelector(".close"),
  copyBtn = document.querySelector(".copy");

function fetchRequest(file, formData) {
  infoText.innerText = "Scanning QR Code...";
  fetch("http://api.qrserver.com/v1/read-qr-code/", {
    method: "POST",
    body: formData,
  })
    .then((res) => res.json())
    .then((result) => {
      result = result[0].symbol[0].data;
      infoText.innerText = result
        ? "Upload QR Code to Scan"
        : "Couldn't scan QR Code";
      if (!result) return;
      document.querySelector("textarea").innerText = result;
      form.querySelector("img").src = URL.createObjectURL(file);
      wrapper.classList.add("active");
    })
    .catch(() => {
      infoText.innerText = "Couldn't scan QR Code";
    });
}

fileInp.addEventListener("change", async (e) => {
  let file = e.target.files[0];
  if (!file) return;
  let formData = new FormData();
  formData.append("file", file);
  fetchRequest(file, formData);
});

copyBtn.addEventListener("click", () => {
  let text = document.querySelector("textarea").textContent;
  navigator.clipboard.writeText(text);
});

form.addEventListener("click", () => fileInp.click());
closeBtn.addEventListener("click", () =>
  wrapper.classList.remove("active")
);
JavaScript
  • File Upload and Scanning:
    • Listens for changes in the file input and triggers a fetch request to scan the uploaded QR Code image.
    • Displays the scanned QR Code content in the textarea and the uploaded image in the form when successful.
  • Copying Scanned Text:
    • Listens for clicks on the copy button and copies the scanned text to the clipboard.
  • Opening and Closing Scanner:
    • Allows users to open the scanner by clicking on the form and close it using the close button.

Conclusion:

In this guide, we’ve explored the creation of a QR Code Scanner using HTML, CSS, and JavaScript. By understanding the structure, styling, and functionality of each component, you can customize and enhance the scanner to meet your requirements. Whether you’re building a standalone scanner or integrating it into a larger application, this guide provides a solid foundation to get started.

Happy Coding!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *