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...