JSFiddle - React, Tailwind, and code Playground

HTML

<html>

<head>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>

<body>
  <div id="wrapper">

    <!-- filters area -->
    <div id="edit_controls">
      <li>GrayScale<br><input id="grayscale" class="range" type="range" min="0" max="100" value="0"></li>
      <li>Blur<br><input id="blur" class="range" type="range" min="0" max="10" value="0"></li>
      <li>Exposure<br><input id="exposure" class="range" type="range" min="0" max="200" value="100"></li>
      <li>Sepia<br><input id="sepia" class="range" type="range" min="0" max="100" value="0"></li>
      <li>Opacity<br><input id="opacity" class="range" type="range" min="0" max="100" value="100"></li>
    </div>

    <!-- images area -->
    <div id="images_div">
      <!-- accepting only image files -->
      <input type="file" accept="image/*" onchange="previewFiles()" style="margin-top: 20px"><br>
      <img src="" id="original_image_preview" alt="Waiting for the image to edit...">
      <br />Edited Image<br /><br />
      <canvas id="edited_image_canva">
          Your browser does not support the HTML5 canvas tag
        </canvas>
      <br />
      <button onclick="download()">Download</button>
    </div>

  </div>
</body>

</html>

CSS

body {
  text-align: center;
  width: 100%;
  margin: 0 auto;
  padding: 0px;
  font-family: Helvetica, Sans-Serif;
  background-color: #E6E6E6;
}

#wrapper {
  text-align: center;
  margin: 0 auto;
  padding: 0px;
  width: 995px;
}

#edit_controls {
  background-color: #A4A4A4;
  float: left;
  width: 500px;
  margin-left: 248px;
}

#edit_controls li {
  list-style-type: none;
  display: inline-block;
  padding: 0px;
  margin: 10px;
  color: white;
}

#images_div img {
  width: 80%;
  padding: 20px;
}

#images_div canvas {
  border: 3px solid #d3d3d3;
}

button {
  margin: 20px;
}

JavaScript

// checking activity on filters values
// calling the apply_filter method as soon as a slider is moved or set into a position
$(document).ready(function() {
  $(".range").change(apply_filter).mousemove(apply_filter);
});


// global variable
const original_image = document.getElementById('original_image_preview');


// setting canva size and return its context to drawing functions
function initializeCanva() {
  // creating the additional canva to show the filters action
  const canvas = document.getElementById('edited_image_canva');
  const ctx = canvas.getContext('2d');

  // assigning it the same size of the original image preview
  canvas.width = original_image.width;
  canvas.height = original_image.height;

  return ctx;
}

// loading and previewing the files
function previewFiles() {

  const preview = document.querySelector('img');
  const file = document.querySelector('input[type=file]').files[0];
  const reader = new FileReader();

  // the load event is fired only when a file has been read successfully, unlike loadend - because we need a success to get started
  reader.addEventListener("load", function() {
    // returning the file content
    preview.src = reader.result;

    // creating the canva to reflect the edits immediately after the original image has been loaded
    const ctx = initializeCanva();

    // drawing the original image on the canva
    ctx.drawImage(original_image, 0, 0, original_image.width, original_image.height);
  }, false);

  // reading the contents of the specified [image] file
  // when the read operation is successfully finished, the load event is triggered - at that time, the result attribute contains the data as a data: URL representing the file's data as a base64 encoded string
  if (file) {
    reader.readAsDataURL(file);
  }

}

// called everytime a slider is hovered or moved around
// atm needed also to show the canva after the original image has been loaded
function apply_filter() {

  // getting the filter values...