Compare commits
3
Commits
4ec8718cef
...
403daca793
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
403daca793
|
||
|
|
90bfd67c71
|
||
|
|
3cb776566f
|
No files matched your search
+7
-1
@@ -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
@@ -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());
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user