Mosaic Thumbnail
Creates a mosaic from a list of images. Tries to keep the ratio as much as it can. Between one and 4 images, the mosaic will used cropped versions if it needs to. After 4 images it will pick and choose given their original ratio.
by Virginie LE GUEN BERTHEAUME
HTML
<div class="thethumbnailwillgohere"></div>
<div class="alltheimages">
<img src="https://loremflickr.com/320/240?random=1&lock=1" />
<img src="https://loremflickr.com/320/240?random=2&lock=2" />
<img src="https://loremflickr.com/320/240?random=3&lock=3" />
<img src="https://loremflickr.com/320/240?random=4&lock=4" />
<img src="https://loremflickr.com/320/240?random=5&lock=5" />
<img src="https://loremflickr.com/320/240?random=6&lock=6" />
<img src="https://loremflickr.com/100/400?random=1&lock=7" />
<img src="https://loremflickr.com/200/400?random=1&lock=8" />
<img src="https://loremflickr.com/200/400?random=2&lock=9" />
<img src="https://loremflickr.com/500/500?random=1&lock=10" />
<img src="https://loremflickr.com/500/500?random=2&lock=11" />
<img src="https://loremflickr.com/500/500?random=3&lock=12" />
</div>
CSS
body {
margin: 0;
padding: 0;
}
.thethumbnailwillgohere {
margin: 10px;
border: 5px solid purple;
}
.alltheimages>img {
display: block;
width: 100%;
}
.atscript-thumbnail {
position: relative;
width: 100%;
padding-bottom: 100%;
height: 0;
}
.atscript-thumbnail[class*="comb"]>div {
display: grid;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.atscript-thumbnail.comb1>div {
grid-template: 'div1 div2' 3fr 'div3 div4' 3fr / 3fr 3fr;
}
.atscript-thumbnail.comb2>div {
grid-template: 'div1 div2' 3fr 'div1 div3' 3fr / 3fr 3fr;
}
.atscript-thumbnail.comb2.sym>div {
grid-template: 'div2 div1' 3fr 'div3 div1' 3fr / 3fr 3fr;
}
.atscript-thumbnail.comb3>div {
grid-template: 'div1 div1' 3fr 'div2 div3' 3fr / 6fr 6fr;
}
.atscript-thumbnail.comb3.sym>div {
grid-template: 'div2 div3' 3fr 'div1 div1' 3fr / 6fr 6fr;
}
.atscript-thumbnail.comb4>div {
grid-template: 'div1 div1 div1' 3fr 'div2 div3 div4' 3fr / 2fr 2fr 2fr;
}
.atscript-thumbnail.comb4.sym>div {
grid-template: 'div2 div3 div4' 3fr 'div1 div1 div1' 3fr / 2fr 2fr 2fr;
}
.atscript-thumbnail.comb5>div {
grid-template: 'div1 div2' 2fr 'div1 div3' 2fr 'div1 div4' 2fr / 3fr 3fr;
}
.atscript-thumbnail.comb5.sym>div {
grid-template: 'div2 div1' 2fr 'div3 div1' 2fr 'div3 div1' 2fr / 3fr 3fr;
}
.atscript-thumbnail.comb6>div {
grid-template: 'div1 div2' 3fr 'div1 div3' 1fr 'div4 div3' 2fr / 4fr 2fr;
}
.atscript-thumbnail.comb6.sym>div {
grid-template: 'div2 div1' 3fr 'div3 div1' 1fr 'div3 div4' 2fr / 2fr 4fr;
}
.atscript-thumbnail.comb7>div {
grid-template: 'div1 div2' 6fr / 3fr 3fr;
}
.atscript-thumbnail.comb8>div {
grid-template: 'div1' 3fr 'div2' 3fr / 6fr;
}
.atscript-thumbnail.comb9>div {
grid-template: 'div1 div2' 3fr 'div1 div3' 3fr / 4fr 2fr;
}
.atscript-thumbnail.comb9.sym>div {
grid-template: 'div2 div1' 3fr 'div3 div1' 3fr / 2fr 4fr;
}
.atscript-thumbnail.comb10>div {
grid-template: 'div1 div1' 4fr 'div2 div3' 2fr /...
JavaScript
function createATThumbnail($imgs, toDataUrl) {
function mapNb(n, start1, stop1, start2, stop2) {
return ((n - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
}
var $newDiv = $('<div class="atscript-thumbnail"><div></div></div>');
if ($imgs.length > 0) {
var portrait = {
1: [],
2: [],
3: [],
4: [],
5: [],
6: []
};
var landscape = {
1: [],
2: [],
3: [],
4: [],
5: [],
6: []
};
for (var i = 0; i < $imgs.length; i++) {
var $hiddenParents = $($imgs[i]).parents('.hidden');
$hiddenParents.removeClass('hidden');
var ar = Math.trunc(($imgs[i].clientWidth / $imgs[i].clientHeight) * 6);
if (ar > 6) {
ar = Math.trunc(($imgs[i].clientHeight / $imgs[i].clientWidth) * 6);
if (!(ar in landscape))
landscape[ar] = [];
landscape[ar].push(i);
} else {
if (!(ar in portrait))
portrait[ar] = [];
portrait[ar].push(i);
}
$hiddenParents.addClass('hidden');
}
var comb = [];
if (portrait[6].length >= 4) {
comb.push(1, 1, 1, 1);
}
if (portrait[3].length >= 1 && portrait[6].length >= 2 && $imgs.length == 3) {
comb.push(2, 2, 2);
}
if (landscape[3].length >= 1 && portrait[6].length >= 2 && $imgs.length == 3) {
comb.push(3, 3, 3);
}
if (landscape[3].length >= 1 && portrait[4].length >= 3) {
comb.push(4, 4, 4, 4);
}
if (portrait[3].length >= 1 && landscape[4].length >= 3) {
comb.push(5, 5, 5, 5);
}
if (portrait[6].length >= 1 && portrait[4].length >= 2 && landscape[3].length >= 1) {
comb.push(6, 6, 6, 6);
}
if (portrait[3].length >= 2 && $imgs.length == 2) {
comb.push(7, 7);
}
if (landscape[3].length >= 2 && $imgs.length == 2) {
comb.push(8, 8);
}
if (portrait[4].length >= 3 && $imgs.length == 3) {
comb.push(9, 9, 9);
}
if (landscape[4].length >= 3...