Files
cardconjurer/print/print.js
2021-12-15 15:28:06 -08:00

226 lines
8.5 KiB
JavaScript

//Configure sizes
var ppi = 600;
var page = [8.5, 11];
//card size
var cardWidth = parseInt(document.querySelector("#cardWidth").value);
var cardHeight = parseInt(document.querySelector("#cardHeight").value);
//bleed edge
var cardPaddingX = parseInt(document.querySelector("#cardPadding").value);
var cardPaddingY = cardPaddingX;
//whitespace
var cardMarginX = parseInt(document.querySelector("#cardMargin").value);
var cardMarginY = cardMarginX;
//booleans
var imgIncludesBleedEdge = true;
var useCuttingAids = false;
//Prepare variables/canvas/context
var imageList = [];
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
drawSheet();
//svgs
var cuttingGuides = new Image();
cuttingGuides.src = 'cuttingGuides.svg';
function uploadCard(card, filename) {
var img = new Image();
img.crossOrigin = 'anonymous';
img.onload = function() {imageList.push(this); drawSheet();}
img.filename = filename.replace('filename=', '');
img.src = card;
}
//buffer to avoid drawing the sheet *too* many times when uploading multiple images at the same time
var drawingSheet;
function drawSheet() {
clearTimeout(drawingSheet);
drawingSheet = setTimeout(drawSheetReal, 500);
}
function drawSheetReal() {
//Prepare canvases
canvas.width = page[0] * ppi;
canvas.height = page[1] * ppi;
context.clearRect(0, 0, page[0] * ppi, page[1] * ppi);
//Calc actual card size
const cw = cardWidth + 2 * cardPaddingX + cardMarginX;
const ch = cardHeight + 2 * cardPaddingY + cardMarginY;
//Calc number of cards that fit on the sheet
const cardsX = Math.floor(page[0] / (cw / ppi));
const cardsY = Math.floor(page[1] / (ch / ppi));
//Calc page margins
const pageMarginX = Math.floor((page[0] * ppi - cardsX * cw) / 2);
const pageMarginY = Math.floor((page[1] * ppi - cardsY * ch) / 2);
//Iterate through every viable space and draw the card there
var count = 0;
for (var i = imageList.length - 1; i >= 0 && count < cardsX * cardsY; i--) {
if (imageList[i].width > 1) {
try {
//Calc upper-left corner of card *image* (accounts for bleed edge and margins)
var x = pageMarginX + (count % cardsX) * (cw) + Math.floor(cardMarginX / 2) + cardPaddingX;
var y = pageMarginY + (Math.floor(count / cardsX) % cardsY) * (ch) + Math.floor(cardMarginY / 2) + cardPaddingY;
var w = cardWidth;
var h = cardHeight;
if (imgIncludesBleedEdge) {
context.drawImage(imageList[i], x - cardPaddingX, y - cardPaddingY, w + 2 * cardPaddingX, h + 2 * cardPaddingY);
} else {
context.fillRect(x - cardPaddingX, y - cardPaddingY, w + 2 * cardPaddingX, h + 2 * cardPaddingY);
context.drawImage(imageList[i], x, y, w, h);
}
if (useCuttingAids) {
context.drawImage(cuttingGuides, x, y, w, h);
}
count ++;
} catch {
console.log('image failed.');
}
}
}
}
function downloadCanvas() {
var download = document.createElement('a');
download.download = 'print.png';
download.href = canvas.toDataURL();
document.body.appendChild(download);
download.click();
download.remove();
}
function downloadPDF() {
var pageOrientation = 'portrait';
if (page[0] > page[1]) {
pageOrientation = 'landscape';
}
var doc = new jsPDF({
orientation: pageOrientation,
unit: 'in',
format: [page[0], page[1]]
});
//create a single black pixel for default padding
var defaultPadding = document.createElement("canvas");
defaultPadding.width = 1;
defaultPadding.height = 1;
var defaultPaddingContext = defaultPadding.getContext("2d");
defaultPaddingContext.fillRect(0, 0, 1, 1);
//Calc actual card size
const cw = cardWidth + 2 * cardPaddingX + cardMarginX;
const ch = cardHeight + 2 * cardPaddingY + cardMarginY;
//Calc number of cards that fit on the sheet
const cardsX = Math.floor(page[0] / (cw / ppi));
const cardsY = Math.floor(page[1] / (ch / ppi));
//Calc page margins
const pageMarginX = Math.floor((page[0] * ppi - cardsX * cw) / 2);
const pageMarginY = Math.floor((page[1] * ppi - cardsY * ch) / 2);
//Iterate through every viable space and draw the card there
var count = 0;
for (var i = imageList.length - 1; i >= 0 && count < cardsX * cardsY; i--) {
if (imageList[i].width > 1) {
try {
//Calc upper-left corner of card *image* (accounts for bleed edge and margins)
var x = pageMarginX + (count % cardsX) * (cw) + Math.floor(cardMarginX / 2) + cardPaddingX;
var y = pageMarginY + (Math.floor(count / cardsX) % cardsY) * (ch) + Math.floor(cardMarginY / 2) + cardPaddingY;
var w = cardWidth;
var h = cardHeight;
if (imgIncludesBleedEdge) {
doc.addImage(imageList[i], "PNG", (x - cardPaddingX) / ppi, (y - cardPaddingY) / ppi, (w + 2 * cardPaddingX) / ppi, (h + 2 * cardPaddingY) / ppi);
} else {
doc.addImage(defaultPadding, "PNG", (x - cardPaddingX) / ppi, (y - cardPaddingY) / ppi, (w + 2 * cardPaddingX) / ppi, (h + 2 * cardPaddingY) / ppi);
doc.addImage(imageList[i], "PNG", x / ppi, y / ppi, w / ppi, h / ppi);
}
if (useCuttingAids) {
doc.addImage(cuttingGuides, "PNG", x / ppi, y / ppi, w / ppi, h / ppi);
}
count ++;
} catch {
console.log('image failed.');
}
}
}
doc.save('print.pdf');
}
//Manages page
function setPageSize(size = [8.5, 11]) {
page[0] = parseFloat(size[0]);
page[1] = parseFloat(size[1]);
drawSheet();
}
function changeOrientation() {
setPageSize([page[1], page[0]]);
}
//Sets PPI, recalculates card measurements
function setPPI(inputPPI) {
var oldPPI = ppi;
ppi = parseInt(inputPPI);
var scale = ppi / oldPPI;
cardWidth *= scale;
cardHeight *= scale;
drawSheet();
}
//Sets specific card dimensions
function setCardSize(size) {
if (size) {
document.querySelector("#cardWidth").value = Math.round(size[0] * ppi);
document.querySelector("#cardHeight").value = Math.round(size[1] * ppi);
}
cardWidth = parseInt(document.querySelector("#cardWidth").value);
cardHeight = parseInt(document.querySelector("#cardHeight").value);
drawSheet();
}
function setPaddingSize(size) {
cardPaddingX = parseInt(size);
cardPaddingY = cardPaddingX;
drawSheet();
}
function setMarginSize(size) {
cardMarginX = parseInt(size);
cardMarginY = cardMarginX;
drawSheet();
}
//Sets booleans
function setBleedEdge(bool) {
imgIncludesBleedEdge = bool;
drawSheet();
}
function setCuttingAids(bool) {
useCuttingAids = bool;
drawSheet();
}
//Default print configurations
function saveDefaults() {
var cardObject = {
ppi:ppi,
page:page,
cardWidth:cardWidth,
cardHeight:cardHeight,
cardMarginX:cardMarginX,
cardMarginY:cardMarginY,
cardPaddingX:cardPaddingX,
cardPaddingY:cardPaddingY,
bleedEdge:imgIncludesBleedEdge,
cuttingAids:useCuttingAids
}
localStorage.setItem("cardPrintConfig", JSON.stringify(cardObject));
}
function loadDefaults() {
var cardObject = JSON.parse(localStorage.getItem("cardPrintConfig"))
if (cardObject && cardObject != {}) {
ppi = cardObject.ppi;
document.querySelector("#cardPPI").value = ppi;
page = cardObject.page;
cardWidth = cardObject.cardWidth;
document.querySelector("#cardWidth").value = cardWidth;
cardHeight = cardObject.cardHeight;
document.querySelector("#cardHeight").value = cardHeight;
cardMarginX = cardObject.cardMarginX;
cardMarginY = cardObject.cardMarginY;
document.querySelector("#cardMargin").value = cardMarginX;
cardPaddingX = cardObject.cardPaddingX;
cardPaddingY = cardObject.cardPaddingY;
document.querySelector("#cardPadding").value = cardPaddingX;
imgIncludesBleedEdge = cardObject.bleedEdge;
document.querySelector("#bleedEdgeCheckbox").checked = imgIncludesBleedEdge;
useCuttingAids = cardObject.cuttingAids;
document.querySelector("#cuttingAidsCheckbox").checked = useCuttingAids;
}
}
loadDefaults();