Balakrishnan Balasubramanian
12b4386f14
1. Simplify template css to use grid always and use ABCD for area names 2. Add 3 new templates 3. Set data attribute dynamically for templates 4. Minor reformatting in js files 5. Fix URL path
217 lines
5.6 KiB
JavaScript
217 lines
5.6 KiB
JavaScript
"use strict";
|
|
|
|
const pageSizes = {
|
|
"letter-portrait" : {
|
|
"ap": "85 / 110",
|
|
"width": 3264,
|
|
"height": 4224,
|
|
},
|
|
"letter-landscape" : {
|
|
"ap": "110 / 85",
|
|
"width": 4224,
|
|
"height": 3264,
|
|
},
|
|
"fiveseven-portrait" : {
|
|
"ap": "5 / 7",
|
|
"width": 2250,
|
|
"height": 3150,
|
|
},
|
|
"fiveseven-landscape" : {
|
|
"ap": "7 / 5",
|
|
"width": 3150,
|
|
"height": 2250,
|
|
},
|
|
"foursix-portrait" : {
|
|
"ap": "4 / 6",
|
|
"width": 1800,
|
|
"height": 2700,
|
|
},
|
|
"foursix-landscape" : {
|
|
"ap": "6 / 4",
|
|
"width": 2700,
|
|
"height": 1800,
|
|
},
|
|
}
|
|
|
|
// elements
|
|
|
|
/** @type {HTMLButtonElement} */
|
|
let snapButton
|
|
|
|
/** @type {HTMLDivElement} */
|
|
let collageDiv
|
|
|
|
/** @type {HTMLSelectElement} */
|
|
let pageSizeSelect
|
|
|
|
/** @type {HTMLAnchorElement} */
|
|
let collageUrlA
|
|
|
|
// collage state
|
|
|
|
let crops = [];
|
|
let pageSize = "letter-landscape";
|
|
/** @type {String[]} */
|
|
let imageUrls = []
|
|
|
|
|
|
function main() {
|
|
snapButton = document.getElementById("snapper")
|
|
collageDiv = document.getElementById("collage")
|
|
pageSizeSelect = document.getElementById("page_size_selector")
|
|
collageUrlA = document.getElementById("collage-url")
|
|
|
|
snapButton.onclick = () => snap()
|
|
pageSizeSelect.onchange = () => pageSizeChange()
|
|
|
|
for(const tmpl of document.getElementsByClassName("template")) {
|
|
// Assumes second class in the template is the collage's template
|
|
const [_, collageTemplate] = tmpl.classList
|
|
tmpl.dataset.collageTemplate = collageTemplate
|
|
tmpl.onclick = () => applyTemplate(tmpl)
|
|
}
|
|
const queryUrls = loadImageUrlsFromQuery()
|
|
// Skipping first entry in array to make the images start with index 1
|
|
imageUrls = [,].concat(queryUrls)
|
|
|
|
applyTemplate(document.getElementById("default_template"))
|
|
}
|
|
|
|
/**
|
|
* @param {HTMLDivElement} elem
|
|
* @param {string} imgUrl
|
|
*/
|
|
function makeCroppieElem(elem, imgUrl) {
|
|
const cpie = new Croppie(elem, {
|
|
viewport: {
|
|
width: elem.clientWidth,
|
|
height: elem.clientHeight,
|
|
type: 'square'
|
|
},
|
|
showZoomer: false,
|
|
});
|
|
|
|
cpie.bind({
|
|
url: imgUrl
|
|
});
|
|
|
|
return cpie
|
|
}
|
|
|
|
|
|
function initCollage() {
|
|
for(const cpie of crops) {
|
|
cpie.destroy()
|
|
}
|
|
crops = []
|
|
|
|
for(const elem of collageDiv.getElementsByClassName("img")) {
|
|
const cpie = makeCroppieElem(elem, elem.dataset.collageImageUrl)
|
|
const lastLen = crops.push(cpie)
|
|
elem.dataset.collageCropieIndex = lastLen - 1
|
|
}
|
|
}
|
|
|
|
async function makeCollage(req) {
|
|
const resp = await fetch("make-collage", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(req),
|
|
})
|
|
return await resp.text();
|
|
}
|
|
|
|
function snap() {
|
|
const col = collageDiv.offsetLeft;
|
|
const cot = collageDiv.offsetTop;
|
|
const req = {
|
|
background_image: "",
|
|
aspect: {
|
|
width: pageSizes[pageSize]["width"],
|
|
height: pageSizes[pageSize]["height"],
|
|
},
|
|
dimension: {
|
|
width: collageDiv.clientWidth,
|
|
height: collageDiv.clientHeight,
|
|
},
|
|
photos: [],
|
|
};
|
|
|
|
for(const elem of collageDiv.getElementsByClassName("img")) {
|
|
const cpie = crops[elem.dataset.collageCropieIndex]
|
|
const fsx = elem.offsetLeft - col
|
|
const fsy = elem.offsetTop - cot
|
|
const [sx, sy, ex, ey] = cpie.get().points;
|
|
const photo = {
|
|
image: elem.dataset.collageImageUrl.slice("/photos/".length),
|
|
crop: {
|
|
start: {
|
|
x: parseInt(sx),
|
|
y: parseInt(sy),
|
|
},
|
|
end: {
|
|
x: parseInt(ex),
|
|
y: parseInt(ey),
|
|
},
|
|
},
|
|
frame: {
|
|
start: {
|
|
x: fsx,
|
|
y: fsy,
|
|
},
|
|
end: {
|
|
x: fsx + elem.clientWidth,
|
|
y: fsy + elem.clientHeight,
|
|
},
|
|
},
|
|
};
|
|
req.photos.push(photo)
|
|
}
|
|
|
|
(async () => {
|
|
collageUrlA.text = "Collage is being generated...";
|
|
const collagFile = await makeCollage(req)
|
|
collageUrlA.href = `collages/${collagFile}`;
|
|
collageUrlA.text = `${collagFile} generated`;
|
|
})();
|
|
}
|
|
|
|
function pageSizeChange() {
|
|
collageDiv.style.setProperty('--collage-ap', pageSizes[pageSizeSelect.value]["ap"])
|
|
pageSize = pageSizeSelect.value
|
|
initCollage()
|
|
}
|
|
|
|
/** @param {HTMLDivElement} templateDiv */
|
|
function applyTemplate(templateDiv) {
|
|
document.getElementsByClassName("template-selected").item(0)?.classList.remove("template-selected")
|
|
/** @type {HTMLDivElement} */
|
|
const templateClone = templateDiv.cloneNode(true)
|
|
templateDiv.classList.add("template-selected")
|
|
for (const index in imageUrls) {
|
|
const url = imageUrls[index]
|
|
const imgClass = `img${index}`
|
|
|
|
const [imgDiv] = templateClone.getElementsByClassName(imgClass)
|
|
if(imgDiv === undefined) {
|
|
break;
|
|
}
|
|
imgDiv.dataset.collageImageUrl = url;
|
|
}
|
|
collageDiv.replaceChildren(...templateClone.children)
|
|
collageDiv.classList.remove(collageDiv.dataset.collageTemplate)
|
|
collageDiv.classList.add(templateDiv.dataset.collageTemplate)
|
|
collageDiv.dataset.collageTemplate = templateDiv.dataset.collageTemplate
|
|
initCollage()
|
|
}
|
|
|
|
function loadImageUrlsFromQuery() {
|
|
const params = new URLSearchParams(window.location.search)
|
|
const urlsstr = params.get('urls')
|
|
return JSON.parse(urlsstr)
|
|
}
|
|
|
|
main()
|