Compare commits

...
3 Commits
Author SHA1 Message Date
chopster44 403daca793 added multipage printing 2026-10-03 19:47:31 +01:00
chopster44 90bfd67c71 initial page generation 2026-10-03 17:09:54 +01:00
chopster44 3cb776566f changed svg which is generated to a path rather than lines 2026-10-03 13:00:44 +01:00
3 changed files with 153 additions and 45 deletions

No files matched your search

+7 -1
View File
@@ -14,6 +14,11 @@
<option value="cm">Centimetres</option> <option value="cm">Centimetres</option>
<option value="in">Inches</option> <option value="in">Inches</option>
</select> <br> </select> <br>
<label for="p">Paper size: </label>
<select id="p">
<option value="a3">A3</option>
<option value="a4">A4</option>
</select> <br>
<label for="h">Height of parachute (h):</label> <label for="h">Height of parachute (h):</label>
<input type="number" id="h" min="0"/><br> <input type="number" id="h" min="0"/><br>
<label for="r">Radius of parachute (r):</label> <label for="r">Radius of parachute (r):</label>
@@ -26,7 +31,8 @@
<input type="number" id="steps" min="10" /><br> <input type="number" id="steps" min="10" /><br>
<button id="generate">Generate!</button> <button id="generate">Generate!</button>
<p id="len"></p> <p id="len"></p>
<div id="output"></div> <div id="output" style="display: none;"></div>
<iframe id="pdf" style="width:100%;height:1000px"></iframe>
<script src="src/main.js" lang="js" type="module"></script> <script src="src/main.js" lang="js" type="module"></script>
</body> </body>
</html> </html>
+56 -44
View File
@@ -1,4 +1,5 @@
import * as maths from "./maths.js"; import * as maths from "./maths.js";
import { createPdf } from "./print.js";
let uInput = document.getElementById("u"); let uInput = document.getElementById("u");
let hInput = document.getElementById("h"); let hInput = document.getElementById("h");
@@ -8,6 +9,7 @@ let npInput = document.getElementById("np");
let outputdiv = document.getElementById("output"); let outputdiv = document.getElementById("output");
let stepInput = document.getElementById("steps"); let stepInput = document.getElementById("steps");
let lenOutput = document.getElementById("len"); let lenOutput = document.getElementById("len");
let paperInput = document.getElementById("p");
let height = 0; let height = 0;
let radius = 0; let radius = 0;
@@ -25,14 +27,15 @@ let pointsQ = [];
let distances = []; let distances = [];
let panelPoints = []; let panelPoints = [];
let panelPaths = [];
let svgSize = { width: 0, height: 0 };
let scaleFactor = 1;
let paperSize = "a3";
let n = 0; let n = 0;
let unit = "px"; let unit = "px";
let strokeWidth = 1; let strokeWidth = 1;
// maths
// logic // logic
function getValues() { function getValues() {
pointsP = []; pointsP = [];
@@ -44,6 +47,7 @@ function getValues() {
spillRadius = /* Math.floor */(parseFloat(rsInput.value) * multiplier); spillRadius = /* Math.floor */(parseFloat(rsInput.value) * multiplier);
numberOfPanels = /* Math.floor */(parseFloat(npInput.value) * multiplier); numberOfPanels = /* Math.floor */(parseFloat(npInput.value) * multiplier);
step = radius / parseInt(stepInput.value); step = radius / parseInt(stepInput.value);
paperSize = paperInput.value;
if (isNaN(spillRadius)) { if (isNaN(spillRadius)) {
spillRadius = /* Math.floor */(0.05 * radius); spillRadius = /* Math.floor */(0.05 * radius);
rsInput.value = 0.05 * radius / multiplier; rsInput.value = 0.05 * radius / multiplier;
@@ -90,78 +94,84 @@ function generateCoordinates() {
} }
} }
function createPerimeterPath(maxY) {
let path = `M `;
// first arc
for (let i = 0; i < panelPoints.length; i++) {
let point = panelPoints[i];
path += `${maths.approx(point.x)},${maths.approx((maxY) - point.y)} `;
}
// second arc
for (let i = panelPoints.length-1; i>=0;i--) {
let point = panelPoints[i];
path +=`${maths.approx(point.x)},${maths.approx((point.y + maxY))} `;
}
path += `${maths.approx(panelPoints[0].x)},${maths.approx((maxY) - panelPoints[0].y)}`;
console.log(path);
return path;
}
function createCentrePath(maxY) {
return `M ${maths.approx(panelPoints[0].x)},${(maxY - maths.approx(panelPoints[0].y) + maths.approx((panelPoints[0].y + maxY))) / 2} ${panelPoints[panelPoints.length - 1].x},${(maxY - maths.approx(panelPoints[panelPoints.length - 1].y) + maths.approx((panelPoints[panelPoints.length - 1].y + maxY))) / 2}`;
}
function plotSVG() { function plotSVG() {
let maxY = 0; let maxY = 0;
let minY = 1000;
let maxX = 0; let maxX = 0;
let minX = 1000; let minX = 1000;
panelPoints.forEach((point) => { panelPoints.forEach((point) => {
if (maxY < point.y) { if (maxY < point.y) {
maxY = point.y; maxY = point.y;
} }
if (minY > point.y) {
minY = point.y;
}
if (minX > point.x) { if (minX > point.x) {
minX = point.x; minX = point.x;
} }
if (maxX < point.x) { if (maxX < point.x) {
maxX = point.x; maxX = point.x;
} }
}) });
let pointsA = ""; svgSize.width = panelPoints[panelPoints.length - 1].x - maths.approx(panelPoints[0].x);
let pointsB = ""; svgSize.height = (maxY - maths.approx(panelPoints[0].y) + maths.approx((panelPoints[0].y + maxY)));
for (let i = 0; i < panelPoints.length; i++) { panelPaths[0] = createCentrePath(maxY);
let point = panelPoints[i]; panelPaths[1] = createPerimeterPath(maxY);
pointsA += `${maths.approx(point.x)},${(maxY) - maths.approx(point.y)} `;
pointsB +=`${maths.approx(point.x)},${maths.approx((point.y + maxY))} `;
}
outputdiv.innerHTML = ` outputdiv.innerHTML = `
<svg width="297mm" <svg width="297mm"
height="210mm" height="210mm"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg">
<g id="layer1"> <g id="layer1">
<line <path
x1="${maths.approx(panelPoints[0].x)}${unit}" d="${panelPaths[0]}"
x2="${panelPoints[0].x}${unit}"
y1="${maxY - maths.approx(panelPoints[0].y)}${unit}"
y2="${maths.approx((panelPoints[0].y + maxY))}${unit}"
fill="none" fill="none"
stroke="black" stroke="black"
stroke-width="${strokeWidth}" stroke-width="${strokeWidth}"
/> />
<line <path
x1="${maths.approx(panelPoints[panelPoints.length - 1].x)}${unit}" d="${panelPaths[1]}"
x2="${panelPoints[panelPoints.length - 1].x}${unit}"
y1="${maxY - maths.approx(panelPoints[panelPoints.length - 1].y)}${unit}"
y2="${maths.approx((panelPoints[panelPoints.length - 1].y + maxY))}${unit}"
fill="none"
stroke="black"
stroke-width="${strokeWidth}"
/>
<line
x1="${maths.approx(panelPoints[0].x)}${unit}"
x2="${panelPoints[panelPoints.length - 1].x}${unit}"
y1="${(maxY - maths.approx(panelPoints[0].y) + maths.approx((panelPoints[0].y + maxY))) / 2}${unit}"
y2="${(maxY - maths.approx(panelPoints[panelPoints.length - 1].y) + maths.approx((panelPoints[panelPoints.length - 1].y + maxY))) / 2}${unit}"
fill="none"
stroke="black"
stroke-width="${strokeWidth}"
/>
<polyline
points="${pointsA}"
fill="none"
stroke="black"
stroke-width="${strokeWidth}"
/>
<polyline
points="${pointsB}"
fill="none" fill="none"
stroke="black" stroke="black"
stroke-width="${strokeWidth}" stroke-width="${strokeWidth}"
/> />
</g> </g>
</svg> </svg>`;
`;
lenOutput.innerText = `Recommended length: ${maths.approx(maxX - minX)} ${unit}`; lenOutput.innerText = `Recommended length: ${maths.approx(maxX - minX)} ${unit}`;
} }
function calculateScaleFactor(unit) {
if (unit == "mm") {
scaleFactor = 72/25.4;
} else if (unit == "cm") {
scaleFactor = 72/2.54;
} else if (unit == "in") {
scaleFactor = 72;
} else if (unit == "px") {
scaleFactor = 0.75;
}
}
// main func // main func
function generatePanel() { function generatePanel() {
@@ -172,6 +182,8 @@ function generatePanel() {
getDistancesBetweenIntersections(); getDistancesBetweenIntersections();
generateCoordinates(); generateCoordinates();
plotSVG(); plotSVG();
calculateScaleFactor(unit);
createPdf(panelPaths, svgSize, scaleFactor, paperSize);
} }
document.getElementById("generate").addEventListener("click", () => generatePanel()); document.getElementById("generate").addEventListener("click", () => generatePanel());
+90
View File
@@ -0,0 +1,90 @@
import { PDFDocument, degrees, rgb } from "pdf-lib";
export async function createPdf(paths, svgSize, scaleFactor, paperSize) {
const pdfDocument = await PDFDocument.create();
// calculate number of pages needed
const margins = { x: 15, y: 15 };
console.log(svgSize);
console.log(`Scale factor ${scaleFactor}`);
// paper sizes in pt
let sizes = {
"a3": {
x: 841.89-2*margins.x,
y: 1190.55-2*margins.y,
},
"a4": {
x: 595.28-2*margins.x,
y: 841.89-2*margins.y,
}
}
let nPages = Math.ceil((svgSize.width *scaleFactor) / sizes[paperSize].y);
console.log(`${svgSize.width} * ${scaleFactor} / ${sizes[paperSize].y} = ${((svgSize.width *scaleFactor) / sizes[paperSize].y)}`);
let needsMarkers = false;
if (1 < nPages) {
needsMarkers = true;
}
console.log(nPages);
// make enough pages
for (let i = 0; i < nPages; i++) {
let offset = i*(sizes[paperSize].y - 4 * margins.y);
let page = pdfDocument.addPage();
page.setSize(sizes[paperSize].x, sizes[paperSize].y);
const { width, height } = page.getSize();
console.log(page.getSize());
const svgSettings = {
x: (width + svgSize.height * scaleFactor)/2,
y: height + offset - margins.y,
rotate: degrees(-90),
borderColor: rgb(0,0,0),
borderWidth: 1,
scale: scaleFactor
};
// centre line
// page.drawLine({
// start: { x: width/2, y: height },
// end: { x: width/2, y: 0 },
// });
page.moveTo(5, height - 5);
// panel
page.drawSvgPath(paths[0], svgSettings);
page.drawSvgPath(paths[1], svgSettings);
// margins
page.drawSvgPath(`M ${margins.x/2},${margins.y/2} ${margins.x/2},${height-margins.y/2} ${width-margins.x/2},${height-margins.y/2} ${width-margins.x/2},${margins.y/2} ${margins.x/2},${margins.y/2} Z`, {
x:0,
y:height,
borderColor: rgb(1,1,1),
borderWidth: margins.x
});
// draw top alignmnet marker
if (i != 0 && needsMarkers) {
page.drawLine({
start: { x: 0, y: height - 2 * margins.y },
end: { x: width, y: height - 2 * margins.y },
});
}
// draw bottom alignment marker
if (i != (nPages-1) && needsMarkers) {
page.drawLine({
start: { x: 0, y: 2 * margins.y },
end: { x: width, y: 2 * margins.y },
});
}
}
const pdfDataUri = await pdfDocument.saveAsBase64({ dataUri: true });
document.getElementById("pdf").src = pdfDataUri;
}