forked from GithubMirrors/cardconjurer
		
	added more user control
This commit is contained in:
		
							
								
								
									
										230
									
								
								print/print.js
									
									
									
									
									
								
							
							
						
						
									
										230
									
								
								print/print.js
									
									
									
									
									
								
							| @@ -1,16 +1,22 @@ | ||||
| //Configure sizes | ||||
| var ppi = 600; | ||||
| var page = [8.5, 11]; | ||||
| var cardWidth = 2.5; | ||||
| var cardHeight = 3.5; | ||||
| var cardMarginX = parseInt(document.querySelector('#cardMargin').value) / ppi; | ||||
| var cardMarginY = parseInt(document.querySelector('#cardMargin').value) / ppi; | ||||
| //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'); | ||||
| var aidCanvas = document.createElement('canvas'); | ||||
| var aidContext = aidCanvas.getContext('2d'); | ||||
| drawSheet(); | ||||
| //svgs | ||||
| var cuttingGuides = new Image(); | ||||
| @@ -23,59 +29,59 @@ function uploadCard(card, filename) { | ||||
|     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); | ||||
|     aidCanvas.width = canvas.width; | ||||
|     aidCanvas.height = canvas.height; | ||||
|     aidContext.clearRect(0, 0, page[0] * ppi, page[1] * ppi); | ||||
|     const cardsX = Math.floor(page[0] / cardWidth); | ||||
|     const cardsY = Math.floor(page[1] / cardHeight); | ||||
|     //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 --) { | ||||
|     for (var i = imageList.length - 1; i >= 0 && count < cardsX * cardsY; i--) { | ||||
|         if (imageList[i].width > 1) { | ||||
|             const cardX = (page[0] - cardsX * cardWidth) / 2 + (count % cardsX) * (cardWidth + cardMarginX) - cardMarginX; | ||||
|             const cardY = (page[1] - cardsY * cardHeight) / 2 + (Math.floor(count / cardsX) % cardsY) * (cardHeight + cardMarginY) - cardMarginY; | ||||
|             try { | ||||
|                 context.drawImage(imageList[i], cardX * ppi, cardY * ppi, cardWidth * ppi, cardHeight * ppi); | ||||
|                 if (document.querySelector('#cuttingAids').checked) { | ||||
|                     context.drawImage(cuttingGuides, cardX * ppi, cardY * ppi, cardWidth * ppi, cardHeight * ppi); | ||||
|                 //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 (document.querySelector('#cuttingAids').checked) { | ||||
|                     aidContext.fillStyle = 'black'; | ||||
|                     aidContext.fillRect(Math.floor((cardX - cardMarginX / 2) * ppi + 2), Math.floor((cardY - cardMarginY / 2) * ppi + 2), Math.ceil((cardWidth + cardMarginX) * ppi - 4), Math.ceil((cardHeight + cardMarginY) * ppi - 4)); | ||||
|                     if ((Math.floor(count / cardsX) % cardsY) == 0) { | ||||
|                         aidContext.clearRect((cardX - cardMarginX / 2) * ppi, (cardY - cardMarginY / 2) * ppi, (cardWidth + cardMarginX) * ppi, cardMarginY * ppi / 2); | ||||
|                     } else if ((Math.floor(count / cardsX) % cardsY) == cardsY - 1) { | ||||
|                         aidContext.clearRect((cardX - cardMarginX / 2) * ppi, (cardY + cardHeight) * ppi, (cardWidth + cardMarginX) * ppi, cardMarginY * ppi / 2); | ||||
|                     } | ||||
|                     if ((count % cardsX) == 0) { | ||||
|                         aidContext.clearRect((cardX - cardMarginX / 2) * ppi, (cardY - cardMarginY / 2) * ppi, cardMarginX * ppi / 2, (cardHeight + cardMarginY) * ppi); | ||||
|                     } else if ((count % cardsX) == cardsX - 1) { | ||||
|                         aidContext.clearRect((cardX + cardWidth) * ppi, (cardY - cardMarginY / 2) * ppi, cardMarginX * ppi / 2, (cardHeight + cardMarginY) * ppi); | ||||
|                     } | ||||
|                 if (useCuttingAids) { | ||||
|                     context.drawImage(cuttingGuides, x, y, w, h); | ||||
|                 } | ||||
|                 count ++; | ||||
|             } catch { | ||||
|                 console.log('image failed.'); | ||||
|             } | ||||
|         } | ||||
|         count ++; | ||||
|     } | ||||
|     if (document.querySelector('#cuttingAids').checked) { | ||||
|         context.globalCompositeOperation = 'destination-over'; | ||||
|         context.drawImage(aidCanvas, 0, 0, aidCanvas.width, aidCanvas.height); | ||||
|         context.globalCompositeOperation = 'source-over'; | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function downloadSheet() { | ||||
| function downloadCanvas() { | ||||
|     var download = document.createElement('a'); | ||||
|     download.download = 'print.png'; | ||||
|     download.href = canvas.toDataURL(); | ||||
|     document.body.appendChild(download); | ||||
|     await download.click(); | ||||
|     download.click(); | ||||
|     download.remove(); | ||||
| } | ||||
|  | ||||
| @@ -89,52 +95,132 @@ function downloadPDF() { | ||||
|         unit: 'in', | ||||
|         format: [page[0], page[1]] | ||||
|     }); | ||||
|     const cardsX = Math.floor(page[0] / cardWidth); | ||||
|     const cardsY = Math.floor(page[1] / cardHeight); | ||||
|     //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; | ||||
|     if (document.querySelector('#cuttingAids').checked) { | ||||
|         doc.addImage(aidCanvas, 'PNG', 0, 0, page[0], page[1]); | ||||
|     } | ||||
|     for (var i = imageList.length - 1; i >= 0 && count < cardsX * cardsY; i --) { | ||||
|     for (var i = imageList.length - 1; i >= 0 && count < cardsX * cardsY; i--) { | ||||
|         if (imageList[i].width > 1) { | ||||
|             const cardX = (page[0] - cardsX * cardWidth) / 2 + (count % cardsX) * (cardWidth + cardMarginX) - cardMarginX; | ||||
|             const cardY = (page[1] - cardsY * cardHeight) / 2 + (Math.floor(count / cardsX) % cardsY) * (cardHeight + cardMarginY) - cardMarginY; | ||||
|             console.log(`image: ${imageList[i].filename}, bounds: ${cardX}, ${cardY}, ${cardWidth}, ${cardHeight}`); | ||||
|             doc.addImage(imageList[i], 'PNG', cardX, cardY, cardWidth, cardHeight); | ||||
|             if (document.querySelector('#cuttingAids').checked) { | ||||
|                 doc.addImage(cuttingGuides, 'PNG', cardX, cardY, cardWidth, cardHeight); | ||||
|             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.'); | ||||
|             } | ||||
|         } | ||||
|         count ++; | ||||
|     } | ||||
|     doc.save('print.pdf'); | ||||
| } | ||||
|  | ||||
| //Manages page | ||||
| function setPageSize(size = [8.5, 11]) { | ||||
|     page[0] = parseFloat(size[0]); | ||||
|     page[1] = parseFloat(size[1]); | ||||
|     drawSheet(); | ||||
| } | ||||
|  | ||||
| function setCardSize(size = [2.5, 3.5]) { | ||||
|     cardWidth = parseFloat(size[0]); | ||||
|     cardHeight = parseFloat(size[1]); | ||||
|     drawSheet(); | ||||
| } | ||||
|  | ||||
| function setCardDistance(distance) { | ||||
|     cardMarginX = parseInt(distance) / ppi; | ||||
|     cardMarginY = parseInt(distance) / ppi; | ||||
|     drawSheet(); | ||||
| } | ||||
|  | ||||
| function changeOrientation() { | ||||
|     page = page.reverse(); | ||||
|     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; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function setPPI(inputPPI) { | ||||
|     ppi = parseInt(inputPPI); | ||||
|     setPageSize([page[0], page[1]]); | ||||
|     setCardSize([cardWidth, cardHeight]); | ||||
| } | ||||
| loadDefaults(); | ||||
		Reference in New Issue
	
	Block a user
	 Kyle
					Kyle