Create an Image Slicer Using JavaScript

How to Split an Image Into Pieces Using JavaScript

How to Split an Image Into Pieces Using JavaScript


In this Javascript Tutorial, we will see how to create a responsive Image Slicer web application using pure HTML, CSS, and JavaScript.
When a user selects an image and specifies the number of slices, our JavaScript handles all the functionality including file reading, image processing, and dynamic grid generation.




Project Source Code:



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"> <!-- Set character encoding -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Slicer</title>
<style>

:root{
--primary-color:#3498db;
--secondary-color:#2ecc71;
--background-color:#f4f6f8;
--text-color:#2c3e50;
--card-background:#fff;
--slice-background:#ecf0f1;
--input-background:#e0e5ec;
--shadow-color:rgba(0,0,0,0.1);
}

*{ box-sizing:border-box; margin: 0; padding: 0; }

body{
font-family: 'Courier New', Courier, monospace;
background-color: var(--background-color);
color: var(--text-color);
display: flex; justify-content: center;
align-items: center;
min-height: 100vh; padding: 20px;
}

.container{
background-color: var(--card-background);
padding: 40px; border-radius: 20px;
box-shadow: 0 10px 30px var(--shadow-color);
max-width: 800px; width: 100%;
text-align: center;
}

h1{
margin-bottom: 30px; font-size: 36px; font-weight: 700;
color: var(--primary-color);
}

.file-input-wrapper{
position: relative; display: inline-block;
margin-bottom: 30px
}

.file-input-wrapper input[type="file"]{
position: absolute; left: -9999px;
}

.file-input-wrapper label{
display: inline-block; padding: 12px 24px;
color: #fff; background-color: var(--primary-color);
font-size: 16px; font-weight: 600;
border-radius: 30px; cursor: pointer;
transition: all 0.3s ease;
}

.file-input-wrapper label:hover{
background-color: var(--secondary-color);
transform: translateY(-2px);
box-shadow: 0 4px 10px var(--secondary-color);
}

.slice-input{
display: flex; justify-content: center;
align-items: center; margin-bottom: 30px;
}

.slice-input label{
margin-right: 15px; font-weight: 600; font-size: 18px;
}

.slice-input input{
width: 80px; padding: 10px; border: none; border-radius: 15px;
background-color: var(--input-background);
color: var(--text-color); font-size: 18px;
text-align: center; transition: all 0.3s ease;
}

.slice-input input:focus{
outline: none; box-shadow: 0 0 0 2px var(--primary-color);
}

.slice-container{
display: grid; grid-gap: 5px; margin-top: 30px;
}

.slice{
position: relative; border-radius: 5px;
background-color: var(--slice-background);
box-shadow: 0 4px 10px var(--shadow-color);
overflow: hidden; transition: all 0.3s ease;
}

.slice img{
width: 100%; height: auto; object-fit: cover; display: block;
}

@keyframes fadeInUp{
from{ opacity: 0; transform: translateY(20px); }
to{ opacity: 1; transform: translateY(0); }
}

.slice{ animation: fadeInUp 0.5s ease forwards; }

</style>
</head>
<body>


<div class="container">

<h1>Image Slicer</h1>

<div class="file-input-wrapper">
<input type="file" id="fileInput" accept="image/*">
<label for="fileInput">Choose an image</label>
</div>

<div class="slice-input">
<label for="sliceNumber">Slices:</label>
<input type="number" id="sliceNumber" min="2" max="100" value="4">
</div>

<div class="slice-container" id="sliceContainer"></div>

</div>


<script>
// Get DOM elements
const fileInput = document.getElementById('fileInput');
const sliceNumber = document.getElementById('sliceNumber');
const sliceContainer = document.getElementById('sliceContainer');
let currentImage = null;

// Add event listeners to handle user interactions
fileInput.addEventListener("change", handleFileUpload);
fileInput.addEventListener("change", handleSliceNumberChange);
sliceNumber.addEventListener("change", handleSliceNumberChange);

/**
* Handles the file upload and slicing process
* @param {Event} event - The change event from the file input
*/
function handleFileUpload(event){
// Gets the first uploaded file
const file = event.target.files[0];
if(file){
// Creates a new FileReader to read the file
const reader = new FileReader();
// Executes when file reading is complete
reader.onload = function(e){
// Creates a new Image object
const img = new Image();
// Sets the image source to the loaded file
img.src = e.target.result;
// Executes when the image is fully loaded
img.onload = function(){
// Stores the loaded image for later use
currentImage = img;
// Calls function to slice the image based on the input value
sliceImage(img, parseInt(sliceNumber.value));
}
}
reader.readAsDataURL(file);
}
}


/**
* Handles changes in the number of slices
*/
function handleSliceNumberChange(){
// Checks if there is a currently loaded image
if(currentImage){
// Re-slices the current image based on the new number
sliceImage(currentImage, parseInt(sliceNumber.value));
}
}


/**
* Slices the image into a grid of smaller images
* @param {Image} image - The image to be sliced
* @param {number} slices - The number of slices per side (e.g., 4 for a 4x4 grid)
*/
function sliceImage(image, slices){

// Clears previous slices from the container
sliceContainer.innerHTML = '';
// Sets up the grid layout for the slices
sliceContainer.style.gridTemplateColumns = `repeat(${slices}, 1fr)`;
// Creates a new canvas element to draw slices
const canvas = document.createElement('canvas');
// Gets the 2D drawing context for the canvas
const ctx = canvas.getContext('2d');
// Calculates the width of each slice
const sliceWidth = image.width / slices;
// Calculates the height of each slice
const sliceHeight = image.height / slices;
// Sets the canvas width to the slice width
canvas.width = sliceWidth;
// Sets the canvas height to the slice height
canvas.height = sliceHeight;
// Loop through each row and column to create individual slices
for(let row = 0; row < slices; row++){
for(let col = 0; col < slices; col++){
// Clears the canvas for the next slice
ctx.clearRect(0, 0, sliceWidth, sliceHeight);
// Draws the current slice from the original image onto the canvas
ctx.drawImage(image, col * sliceWidth, row * sliceHeight,
sliceWidth, sliceHeight, 0, 0, sliceWidth, sliceHeight);

// Creates an image element for the slice
const sliceImage = document.createElement('img');
// Converts the canvas to a Data URL and sets it as the image source
sliceImage.src = canvas.toDataURL();
// Creates a div to hold the slice image
const sliceDiv = document.createElement('div');
// Assigns the 'slice' class for styling
sliceDiv.className = 'slice';
// Sets a delay for each slice's animation for a staggered effect
sliceDiv.style.animationDelay = `${(row * slices + col) * 0.05}s`;
// Appends the image to the slice div
sliceDiv.appendChild(sliceImage);
// Appends the slice div to the main slice container
sliceContainer.appendChild(sliceDiv);
}
}


}

</script>

</body>
</html>




OUTPUT:

Sliced Image Using Javascript 1

Sliced Image Using Javascript 2

Sliced Image Using Javascript 3







Share this

Related Posts

Previous
Next Post »