This article will show you a complete example of how to create a photo collage in HTML5 using CSS3 — from dragging and dropping images to saving the resulting photo collage image on your file. You will find all the needed files types are listed here, so can improve your photo collage skills.
In the figures below, you will see the structure of the files needed to create this application:

Getting Started
The index.html file contains the divs corresponding uploaded images that were created by dragging and dropping. You can also click in that area and an Open window will appear in which you can select your photo collage pattern. In our example, there are three patterns from which to choose, as you will see next. Another one will let you choose a background for your collage via browsing on your computer and the last option is to save your photo collage image, by pressing the link Save your collage image.
The index.html listing
<!DOCTYPE html>
<html>
<head>
<title>Collage photo's</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/styles.css" rel="stylesheet" type="text/css"/>
</head>
<body id="body">
<h1>Collage</h1>
<div class="row">
<div class="column">
<div id="leftSide">
<div id="dropZone">
<p>Drag your images from your file sau click <u>here</u>!</p>
</div>
<div id="images_preview"></div>
</div>
</div>
<div class="column">
<div id="buttonsArea">
<select id="modelSelect" onchange="modelSelect()">
<option value="">Select the pattern</option>
<option value="model1">Model 1</option>
<option value="model2">Model 2</option>
<option value="model3">Model 3</option>
</select>
<div id="singleUploadSection">
Click "Browse" to select a background image for your canvas!
<input id="singleUpload" type="file" onchange="setBackground()"/>
</div>
<a href="#" class="button" id="btn-download">Save your collage image</a>
</div>
</div>
<div id="photo">
<canvas id="background" width="600" height="600"></canvas>
</div>
<div id="images"></div>
</div>
<script src="js/jquery-3.2.1.min.js"></script>
<script src="js/fileUpload.js"></script>
<script src="js/script.js"></script>
</body>
</html>

The styles.css file
styles.css
body {
margin: 0;
background-color: #e1e6c4;
}
* {
box-sizing: border-box;
}
.column {
float: left;
}
.row:after {
content: "";
display: table;
clear: both;
}
h1 {
color: #239aca;
text-align: center;
}
h1:first-letter{
color:#1B6685;
}
#leftSide {
color: #aaa;
width: 186px;
padding: 5px;
margin: 0 20px;
overflow: auto;
background-color: #fff;
border: dashed 1px #bbb;
box-shadow: 0px 0px 0px 5px #f7f7f7, 0px 0px 2px 7px #bbb, 0px 0px 5px 5px #f7f7f7 inset;
}
#dropZone {
padding: 30px 0;
margin-bottom: 8px;
text-align: center;
}
#dropZone.dragover {
background: #DCDCDC;
}
img {
margin: 0 3px;
}
img:hover {
cursor: grab;
}
#buttonsArea {
margin: 0 15px 0 50px;
}
select {
color: #333;
display: block;
max-width: 100%;
border-radius: 3px;
height: auto !important;
border: 1px solid #e3e3e3;
line-height: 16px !important;
padding: 10px 70px 10px 13px !important;
background: #fff url("selectbox_arrow.png") right center no-repeat;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
}
#singleUploadSection {
color: #333;
width: 194px;
padding: 6px;
margin: 10px 0;
font-size: 13px;
text-align: center;
border-radius: 3px;
background-color: #fff;
}
#background {
padding: 5px;
position: absolute;
background-color: #fff;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
.layer {
padding: 5px;
position: absolute;
background-color: #fff;
}
The fileUpload.js listing
/*
* This file is used for drag & drop file upload and image preview
*/
/************************************************************
* Add the JavaScript support for drag & drop/browse upload *
***********************************************************/
function makeDroppable(element, callback) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('multiple', true);
input.style.display = 'none';
input.addEventListener('change', function (e) {
triggerCallback(e, callback);
});
element.appendChild(input);
element.addEventListener('dragover', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.add('dragover');
});
element.addEventListener('dragleave', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.remove('dragover');
});
element.addEventListener('drop', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.remove('dragover');
triggerCallback(e, callback);
});
element.addEventListener('click', function () {
input.value = null;
input.click();
});
}
function triggerCallback(e, callback) {
if (!callback || typeof callback !== 'function') {
return;
}
var files;
if (e.dataTransfer) {
files = e.dataTransfer.files;
} else if (e.target) {
files = e.target.files;
}
callback.call(null, files);
}
/*************************************************************************
* After drag & drop upload, create image elements and add image preview *
* Make images draggable to canvas and register mouse & drag events *
************************************************************************/
makeDroppable(document.querySelector('#dropZone'), function (files) {
var output = document.querySelector('#images_preview');
output.innerHTML = '';
for (var i = 0; i < files.length; i++) {
if (files[i].type.indexOf('image/') === 0) {
var reader = new FileReader();
reader.addEventListener("load", function () {
var image = new Image();
image.id = Math.random().toString(36).substr(2, 9); // Generate image ID
image.height = 80;
image.width = 80;
image.src = this.result;
image.ondragstart = function (e) { // Register drag event
e.dataTransfer.setData("text", e.target.id);
};
output.appendChild(image); // Add image preview to page
}, false);
reader.readAsDataURL(files[i]);
}
}
});

The script.js file
function setBackground() {
var file = $("#singleUpload")[0].files[0];
var canvas = document.getElementById("background");
var context = canvas.getContext("2d");
var reader = new FileReader();
reader.addEventListener("load", function () {
var backgroundImage = new Image();
backgroundImage.src = this.result;
backgroundImage.onload = function () {
context.drawImage(backgroundImage, 0, 0, 600, 600);
image to fill canvas
};
}, false);
reader.readAsDataURL(file);
}
$("#singleUpload").val("");
$("#modelSelect").val("");
document.getElementById("background").style.visibility = "hidden";
var link = document.getElementById('btn-download');
link.addEventListener('click', function (e) {
var canvas = document.createElement('canvas');
var context = canvas.getContext("2d");
canvas.width = 605;
canvas.height = 605;
$('#photo').children('canvas').each(function () {
var image = this;
context.beginPath();
rectangles behind images on export
context.rect((image.offsetLeft - 480), (image.offsetTop - 76), image.width,
image.height);
context.fillStyle = "white";
context.fill();
context.drawImage(image, (image.offsetLeft - 480 + 5), (image.offsetTop - 76 + 5),
(image.width - 10), (image.height - 10));
});
link.href = canvas.toDataURL();
link.download = "photo.png";
}, false);
function modelSelect() {
var background = document.getElementById("background");
var photo = document.getElementById("photo");
while (photo.firstChild) {
photo.removeChild(photo.firstChild);
}
photo.appendChild(background);
var selectedModel = document.getElementById("modelSelect").value;
model value
switch (selectedModel) {
case "model1":
canvas elements as layers on top of background canvas
document.getElementById("background").style.visibility = "visible";
background canvas visible
var layer1 = document.createElement('canvas');
programmatically
layer1.className = "layer";
layer1.width = 200;
layer1.height = 200;
layer1.style.top = "130px";
layer1.style.left = "540px";
layer1.style.visibility = "visible";
var body = document.getElementById("photo");
body.appendChild(layer1);
registerEvents(layer1);
var layer2 = document.createElement('canvas');
second square canvas.. etc
layer2.className = "layer";
layer2.width = 110;
layer2.height = 110;
layer2.style.top = "180px";
layer2.style.left = "840px";
layer2.style.visibility = "visible";
var body = document.getElementById("photo");
body.appendChild(layer2);
registerEvents(layer2);
var layer3 = document.createElement('canvas');
layer3.className = "layer";
layer3.width = 340;
layer3.height = 230;
layer3.style.top = "400px";
layer3.style.left = "670px";
layer3.style.visibility = "visible";
var body = document.getElementById("photo");
body.appendChild(layer3);
registerEvents(layer3);
break;
case "model2":
as layers on top of background canvas
document.getElementById("background").style.visibility = "visible";
var layer1 = document.createElement('canvas');
layer1.className = "layer";
layer1.width = 250;
layer1.height = 250;
layer1.style.top = "81px";
layer1.style.left = "485px";
layer1.style.visibility = "visible";
var body = document.getElementById("photo");
body.appendChild(layer1);
registerEvents(layer1);
var layer2 = document.createElement('canvas');
layer2.className = "layer";
layer2.width = 150;
layer2.height = 600;
layer2.style.top = "81px";
layer2.style.left = "785px";
layer2.style.visibility = "visible";
var body = document.getElementById("photo");
body.appendChild(layer2);
registerEvents(layer2);
break;
case "model3":
as layers on top of background canvas
document.getElementById("background").style.visibility = "visible";
var layer1 = document.createElement('canvas');
layer1.className = "layer";
layer1.width = 250;
layer1.height = 250;
layer1.style.top = "81px";
layer1.style.left = "485px";
layer1.style.visibility = "visible";
var body = document.getElementById("photo");
body.appendChild(layer1);
registerEvents(layer1);
var layer2 = document.createElement('canvas');
layer2.className = "layer";
layer2.width = 300;
layer2.height = 600;
layer2.style.top = "81px";
layer2.style.left = "785px";
layer2.style.visibility = "visible";
var body = document.getElementById("photo");
body.appendChild(layer2);
registerEvents(layer2);
break;
default:
document.getElementById("background").style.visibility = "hidden";
canvas until model is selected
}
}
function registerEvents(canvas) {
canvas.ondragenter = function () {
canvas.style.border = "dashed 2px #555";
};
canvas.ondragleave = function () {
canvas.style.border = "none";
};
canvas.ondragover = function (e) {
e.preventDefault();
};
canvas.ondrop = function (e) {
e.preventDefault();
var id = e.dataTransfer.getData("text");
var dropImage = document.getElementById(id);
canvas.style.border = "none";
var context = canvas.getContext("2d");
context.drawImage(dropImage, 0, 0, canvas.width, canvas.height);
};
}
Next, are some screenshots of different photo collage options that are available using the three patterns:





Conclusion
This article has shown you how to create a photo collage with your own images using HTML5 and CSS3.