1
0
Fork 0
freesewing/sites/shared/components/workbench/exporting/exporter.js

185 lines
4.9 KiB
JavaScript
Raw Normal View History

import {sizes} from '../layout/print/plugin'
import PDFDocument from 'pdfkit/js/pdfkit.standalone'
import SVGtoPDF from 'svg-to-pdfkit'
import fileSaver from 'file-saver'
const pointsPerPx = (72/96);
const pxPerMm = 3.77953
const pointsPerMm = pxPerMm * pointsPerPx
export default class Exporter {
designName
svg
settings
2022-08-17 00:34:25 -05:00
pattern
pdf
pageWidth
pageHeight
margin
wPages
hPages
svgWidth
svgHeight
2022-08-17 00:34:25 -05:00
pagesWithContent = {}
constructor(designName, pattern, svg, settings) {
this.designName = designName || 'freesewing'
this.settings = settings
2022-08-17 00:34:25 -05:00
this.pattern = pattern
this.createPdf()
this.pageHeight = this.pdf.page.height
this.pageWidth = this.pdf.page.width
this.margin = this.settings.margin * pointsPerMm
let marginInMm = this.settings.margin
2022-08-17 00:34:25 -05:00
// let pageWidthInPx = this.pageWidth / pointsPerMm - marginInMm
// let pageHeightInPx = this.pageHeight / pointsPerMm - marginInMm
const divElem = document.createElement('div');
divElem.innerHTML = svg;
this.svg = divElem.firstElementChild;
2022-08-17 00:34:25 -05:00
const viewBox = this.svg.viewBox.baseVal
this.svgWidth = viewBox.width + viewBox.x
this.svgHeight = viewBox.height + viewBox.y
2022-08-17 00:34:25 -05:00
this.wPages = Math.ceil(this.svgWidth/this.pageWidthInPx)
this.hPages = Math.ceil(this.svgHeight/this.pageHeightInPx)
this.svgWidth = this.wPages * (this.pageWidth - this.margin)
this.svgHeight = this.hPages * (this.pageHeight - this.margin)
this.svg.setAttribute('height', this.svgWidth + 'pt')
this.svg.setAttribute('width', this.svgHeight + 'pt')
2022-08-17 00:34:25 -05:00
this.svg.setAttribute('viewBox', `0 0 ${this.wPages * this.pageWidthInPx} ${this.hPages * this.pageHeightInPx}`)
}
2022-08-17 00:34:25 -05:00
get pageWidthInPx() { return this.pageWidth / pointsPerMm - this.settings.margin}
get pageHeightInPx() { return this.pageHeight / pointsPerMm - this.settings.margin}
createPdf() {
this.pdf = new PDFDocument({
2022-08-17 00:34:25 -05:00
size: this.settings.size.toUpperCase(),
layout: this.settings.orientation
})
const buffers = [];
this.pdf.on('data', buffers.push.bind(buffers));
this.pdf.on('end', () => {
const blob = new Blob(buffers, {
type: 'application/pdf'
})
fileSaver.saveAs(blob, `freesewing-${this.designName}.pdf`)
});
}
2022-08-17 00:34:25 -05:00
scanPages() {
const layout = typeof this.pattern.settings.layout === 'object' ? this.pattern.settings.layout : this.pattern.autoLayout;
// const usableWidth = this.pageWidth - this.margin
// const usableHeight = this.pageHeight - this.margin
for (var h = 0; h < this.hPages; h++) {
this.pagesWithContent[h] = {}
for (var w = 0; w < this.wPages; w++) {
let x = w * this.pageWidthInPx
let y = h * this.pageHeightInPx
let hasContent = false
for (var p in layout.parts) {
let part = this.pattern.parts[p]
if (p === 'pages' || part.render === false) continue
let partLayout = layout.parts[p]
let partX = partLayout.move.x + part.topLeft.x
let partY = partLayout.move.y + part.topLeft.y
if (
partX < x + this.pageWidthInPx &&
partX + part.width > x &&
partY < y + this.pageHeightInPx &&
partY + part.height > y
) {
hasContent = true;
break;
}
}
this.pagesWithContent[h][w] = hasContent
if (!hasContent) {
let pageName = `_pages__row${h}-col${w}`
this.removeElem(pageName, 'circle', 'text')
this.removeElem(pageName + '-row-marker', 'text')
this.removeElem(pageName + '-col-marker', 'text')
this.removeElem(pageName + '-x-ruler', 'text')
this.removeElem(pageName + '-y-ruler', 'text')
}
}
}
}
removeElem(pathId, ...suffixes) {
const that = this;
const elem = that.svg.getElementById(pathId)
if (elem) elem.setAttribute('class', 'hidden')
suffixes.forEach((s) => that.removeElem(`${pathId}-${s}`))
}
async export() {
2022-08-17 00:34:25 -05:00
this.scanPages()
await this.generateCoverPage()
await this.generatePages();
this.save()
}
async generateCoverPage() {
if (!this.settings.coverPage) {
return
}
let coverMargin = 100
let coverHeight = this.pageHeight - coverMargin * 2
let coverWidth = this.pageWidth - coverMargin * 2
await SVGtoPDF(this.pdf, this.svg.outerHTML, coverMargin, coverMargin, {
width: coverWidth,
height: coverHeight,
assumePt: true,
preserveAspectRatio: 'xMidYMid meet'
});
}
async generatePages() {
const options = {
assumePt: true,
width: this.svgWidth,
height: this.svgHeight,
preserveAspectRatio: 'xMinYMin slice'
}
for (var h = 0; h < this.hPages; h++) {
for (var w = 0; w < this.wPages; w++) {
2022-08-17 00:34:25 -05:00
let x = -w * this.pageWidth + (0.5 + w) * this.margin
let y = -h * this.pageHeight + (0.5 + h) * this.margin
if (!this.pagesWithContent[h][w]) continue;
// if there was no cover page, the first page already exists
if (this.settings.coverPage || h+w > 0) {
this.pdf.addPage()
}
await SVGtoPDF(this.pdf, this.svg.outerHTML, x, y, options)
}
}
}
save() {
this.pdf.end();
}
}