From 17678800af68acd315574e0b96f73767038fcd49 Mon Sep 17 00:00:00 2001
From: whatwareweb <59752545+whatwareweb@users.noreply.github.com>
Date: Thu, 25 Jul 2024 19:39:07 -0500
Subject: [PATCH 1/5] Update toolkit and DropBox to prepare for SVG auto scaler
---
src/components/DropBox.tsx | 152 ++++++++++++++++++++++------------
src/drawingToolkit/toolkit.js | 4 +
2 files changed, 105 insertions(+), 51 deletions(-)
diff --git a/src/components/DropBox.tsx b/src/components/DropBox.tsx
index f1c39df8a..72477c8be 100644
--- a/src/components/DropBox.tsx
+++ b/src/components/DropBox.tsx
@@ -8,10 +8,10 @@ export default function DropBox() {
// Make sure the ref is defined
addDragDrop();
}, []); // Empty dependency array means this effect runs once after initial render
-
+
return (
- Drop an SVG or JS file.
+ Drop an SVG or JS file.
);
}
function addDragDrop() {
const droparea: HTMLElement | null = document.querySelector(".droparea");
-
+
window.addEventListener("drop", function (evt) {
const { view } = getStore();
-
+
let dt = evt.dataTransfer;
-
+
if (dt === null || droparea === null) return;
-
+
let files = dt.files;
-
+
droparea.classList.add("hidden");
-
+
const file = files[0];
const fileName = file.name.split(".");
const name = fileName[0];
const extension = fileName[fileName.length - 1];
-
+
var reader = new FileReader();
reader.readAsText(file);
-
+
reader.onloadend = (event) => {
let text = reader.result;
-
+
if (extension === "js") {
loadCodeFromString(text);
} else if (extension === "svg") {
text = text.replaceAll("\n", "");
-
+
const polylines = JSON.stringify(tk.svgToPolylines(text));
-
+
customAlert(polylines);
-
+
// const newLines = `const importedSVG = ${polylines};\n`;
-
+
// view.dispatch({
// changes: { from: 0, insert: newLines },
// });
@@ -79,19 +79,19 @@ function addDragDrop() {
throw Error("Unknown extension:" + extension);
}
};
-
+
pauseEvent(evt);
});
-
+
window.addEventListener("dragover", function (evt) {
droparea.classList.remove("hidden");
pauseEvent(evt);
});
["mouseout"].forEach((trigger) =>
window.addEventListener(trigger, function (evt) {
- droparea.classList.add("hidden");
- }),
- );
+ droparea.classList.add("hidden");
+ }),
+);
}
function pauseEvent(e) {
@@ -102,51 +102,101 @@ function pauseEvent(e) {
return false;
}
-function customAlert(polylines) {
+const dialogstyle = `
+z-index: 999999999999;
+width: 550px;
+min-height: 100px;
+position: absolute;
+left: 50%;
+top: 100px;
+transform: translate(-50%, 0%);
+background: #f4f4f4;
+border-radius: 10px;
+border: 1px solid black;
+padding: 8px;
+`
+
+const polylinesStyle = `
+overflow-x: auto;
+background: #e2e2e2;
+border-radius: 5px;
+margin: auto;
+margin-top: 1em;
+margin-bottom: 1em;
+padding: .25rem;
+`
+
+const buttonClasses = `class="mx-auto my-1 text-white p-2 rounded cursor-pointer bg-gray-700 hover:bg-gray-500"`
+function customAlert(polylines) {
const el = document.createElement("div");
- const style = `
- z-index: 999999999999;
- width: 550px;
- min-height: 100px;
- position: absolute;
- left: 50%;
- top: 100px;
- transform: translate(-50%, 0%);
- background: #f4f4f4;
- border-radius: 10px;
- border: 1px solid black;
- padding: 8px;
- `
-
- const polylinesStyle = `
- overflow-x: auto;
- background: #e2e2e2;
- border-radius: 5px;
- margin: auto;
- margin-top: 1em;
- margin-bottom: 1em;
- padding: .25rem;
+
+ el.innerHTML = `
+
+
+
Here are the polylines of your SVG. Copy and paste it into the editor.
+
${polylines}
+
+
+
+
+
+
+
`
+
+ el.querySelector("#closeButton").addEventListener("click", () => {
+ el.remove();
+ })
+
+ el.querySelector("#scaleButton").addEventListener("click", () => {
+ el.remove();
+ scaleAlert(polylines);
+ })
+
+ document.body.append(el);
+}
+function scaleAlert(polylines) {
+ const el = document.createElement("div");
+
el.innerHTML = `
-
+
-
Here are the polylines of your SVG. Copy and paste it into the editor.
+
Scale your polylines to specific dimensions.
${polylines}
+
+
+
+
+
-
`
- el.querySelector("button").addEventListener("click", () => {
+ el.querySelector("#scaleButton").addEventListener("click", () => {
+ const newPolyLines = tk.scalePolylinesToDimension(polylines, el.querySelector("#newWidth").value, el.querySelector("#newHeight").value);
el.remove();
+ customAlert(newPolyLines);
})
-
+
+ el.querySelector("#cancelButton").addEventListener("click", () => {
+ el.remove();
+ customAlert(polylines);
+ })
+
document.body.append(el);
-}
+}
\ No newline at end of file
diff --git a/src/drawingToolkit/toolkit.js b/src/drawingToolkit/toolkit.js
index f51c0472f..7d4aaf73f 100644
--- a/src/drawingToolkit/toolkit.js
+++ b/src/drawingToolkit/toolkit.js
@@ -132,6 +132,10 @@ export const toolkit = {
}
},
+ scalePolylinesToDimension(polylines, width, height){
+ console.log("it works", polylines, width, height);
+ return polylines;
+ },
join() {
const [first, ...rest] = arguments;
if (!first) return [];
From 11d082fbbfaa625442552dd64d8cf542c47ec38b Mon Sep 17 00:00:00 2001
From: whatwareweb <59752545+whatwareweb@users.noreply.github.com>
Date: Thu, 25 Jul 2024 20:49:03 -0500
Subject: [PATCH 2/5] Finish scaling algorithm
---
src/components/DropBox.tsx | 17 ++++++---
src/drawingToolkit/toolkit.js | 72 ++++++++++++++++++++++++++++++++++-
2 files changed, 82 insertions(+), 7 deletions(-)
diff --git a/src/components/DropBox.tsx b/src/components/DropBox.tsx
index 72477c8be..1a958ce07 100644
--- a/src/components/DropBox.tsx
+++ b/src/components/DropBox.tsx
@@ -170,7 +170,7 @@ function scaleAlert(polylines) {
Scale your polylines to specific dimensions.
${polylines}
-
+
@@ -186,11 +186,18 @@ function scaleAlert(polylines) {
`
-
+
el.querySelector("#scaleButton").addEventListener("click", () => {
- const newPolyLines = tk.scalePolylinesToDimension(polylines, el.querySelector("#newWidth").value, el.querySelector("#newHeight").value);
- el.remove();
- customAlert(newPolyLines);
+ const newWidth = el.querySelector("#newWidth").value;
+ const newHeight = el.querySelector("#newHeight").value;
+
+ if (Number.isNaN(newWidth) || Number.isNaN(newHeight)|| newWidth == "" || newHeight == "") {
+ alert("Invalid width/height provided ");
+ } else {
+ const newPolyLines = tk.scalePolylinesToDimension(polylines, newWidth, newHeight);
+ el.remove();
+ customAlert(newPolyLines);
+ }
})
el.querySelector("#cancelButton").addEventListener("click", () => {
diff --git a/src/drawingToolkit/toolkit.js b/src/drawingToolkit/toolkit.js
index 7d4aaf73f..5e67ace7c 100644
--- a/src/drawingToolkit/toolkit.js
+++ b/src/drawingToolkit/toolkit.js
@@ -133,8 +133,76 @@ export const toolkit = {
},
scalePolylinesToDimension(polylines, width, height){
- console.log("it works", polylines, width, height);
- return polylines;
+ polylines = JSON.parse(polylines);
+
+ let minXVal = Number.POSITIVE_INFINITY;
+ polylines.forEach((obj) => {
+ obj.forEach((coord) => {
+ if (coord[0] < minXVal) {
+ minXVal = coord[0];
+ }
+ })
+ })
+
+ let minYVal = Number.POSITIVE_INFINITY;
+ polylines.forEach((obj) => {
+ obj.forEach((coord) => {
+ if (coord[1] < minYVal) {
+ minYVal = coord[1];
+ }
+ })
+ })
+
+ if (minXVal != 0) {
+ polylines.forEach((obj) => {
+ obj.forEach((coord) => {
+ coord[0] -= minXVal;
+ })
+ })
+ }
+
+ if (minYVal != 0) {
+ polylines.forEach((obj) => {
+ obj.forEach((coord) => {
+ coord[1] -= minYVal;
+ })
+ })
+ }
+
+ let maxXVal = Number.NEGATIVE_INFINITY;
+ polylines.forEach((obj) => {
+ obj.forEach((coord) => {
+ if (coord[0] > maxXVal) {
+ maxXVal = coord[0];
+ }
+ })
+ })
+
+ let maxYVal = Number.NEGATIVE_INFINITY;
+ polylines.forEach((obj) => {
+ obj.forEach((coord) => {
+ if (coord[1] > maxYVal) {
+ maxYVal = coord[1];
+ }
+ })
+ })
+
+ const xFactor = width/maxXVal;
+ const yFactor = height/maxYVal;
+
+ polylines.forEach((obj) => {
+ obj.forEach((coord) => {
+ coord[0] *= xFactor;
+ })
+ })
+
+ polylines.forEach((obj) => {
+ obj.forEach((coord) => {
+ coord[1] *= yFactor;
+ })
+ })
+
+ return JSON.stringify(polylines);
},
join() {
const [first, ...rest] = arguments;
From db71302c7b691a35b4d0a7e0e3703113a9d432a4 Mon Sep 17 00:00:00 2001
From: whatwareweb <59752545+whatwareweb@users.noreply.github.com>
Date: Thu, 25 Jul 2024 23:34:04 -0500
Subject: [PATCH 3/5] Finish SVG import scaling settings
---
src/components/DropBox.tsx | 10 +++-
src/drawingToolkit/toolkit.js | 87 +++++++++++++----------------------
2 files changed, 41 insertions(+), 56 deletions(-)
diff --git a/src/components/DropBox.tsx b/src/components/DropBox.tsx
index 1a958ce07..5881a4d4b 100644
--- a/src/components/DropBox.tsx
+++ b/src/components/DropBox.tsx
@@ -175,10 +175,15 @@ function scaleAlert(polylines) {
+
+
+
+
+
- scale
+ scale (keep aspect ratio)
cancel
@@ -190,11 +195,12 @@ function scaleAlert(polylines) {
el.querySelector("#scaleButton").addEventListener("click", () => {
const newWidth = el.querySelector("#newWidth").value;
const newHeight = el.querySelector("#newHeight").value;
+ const addPadding = el.querySelector("#paddingCheckbox").checked;
if (Number.isNaN(newWidth) || Number.isNaN(newHeight)|| newWidth == "" || newHeight == "") {
alert("Invalid width/height provided ");
} else {
- const newPolyLines = tk.scalePolylinesToDimension(polylines, newWidth, newHeight);
+ const newPolyLines = tk.scalePolylinesToDimension(polylines, newWidth, newHeight, addPadding);
el.remove();
customAlert(newPolyLines);
}
diff --git a/src/drawingToolkit/toolkit.js b/src/drawingToolkit/toolkit.js
index 5e67ace7c..34e1a5a44 100644
--- a/src/drawingToolkit/toolkit.js
+++ b/src/drawingToolkit/toolkit.js
@@ -54,34 +54,34 @@ export const toolkit = {
if (boundary === "closed" && points.length > 3) {
points.pop();
};
-
+
var curve = nurbs({
points,
degree,
boundary
});
-
+
const pl = [];
const domain = curve.domain[0];
const range = domain[1] - domain[0];
const stepSize = range/steps;
-
+
let i = domain[0];
while (i <= domain[1]) {
-
+
const pt = curve.evaluate([], i);
pl.push(pt);
-
+
i += stepSize;
}
-
+
if (i !== domain[1]) {
const pt = curve.evaluate([], domain[1]);
pl.push(pt);
}
-
+
return pl;
-
+
function isClosed(polyline, epsilon = 1e-3) {
let start = polyline[0]
let end = polyline[polyline.length - 1]
@@ -109,12 +109,12 @@ export const toolkit = {
polylines.forEach(pl => {
const newPl = simplifyPolyline(pl, tolerance, hq)
while (pl.length > 0) pl.pop()
-
+
while (newPl.length > 0) {
pl.push(newPl.shift())
}
})
-
+
return polylines;
},
trim: trimPolylines,
@@ -125,96 +125,75 @@ export const toolkit = {
const doc = parser.parseFromString(svgString, 'image/svg+xml');
const svg = doc.querySelector('svg');
const polylines = flattenSVG(svg, { maxError: 0.001 }).map(pl => pl.points);
-
+
return polylines;
} catch (err) {
throw new Error("SVGs can not be parsed in web workers.");
}
},
- scalePolylinesToDimension(polylines, width, height){
+ scalePolylinesToDimension(polylines, width, height, addPadding){
polylines = JSON.parse(polylines);
-
+
let minXVal = Number.POSITIVE_INFINITY;
+ let minYVal = Number.POSITIVE_INFINITY;
polylines.forEach((obj) => {
obj.forEach((coord) => {
if (coord[0] < minXVal) {
minXVal = coord[0];
}
- })
- })
-
- let minYVal = Number.POSITIVE_INFINITY;
- polylines.forEach((obj) => {
- obj.forEach((coord) => {
if (coord[1] < minYVal) {
minYVal = coord[1];
}
})
})
-
- if (minXVal != 0) {
- polylines.forEach((obj) => {
- obj.forEach((coord) => {
- coord[0] -= minXVal;
- })
- })
- }
-
- if (minYVal != 0) {
- polylines.forEach((obj) => {
- obj.forEach((coord) => {
- coord[1] -= minYVal;
- })
- })
- }
+
+ translate(polylines, [-minXVal, -minYVal]);
let maxXVal = Number.NEGATIVE_INFINITY;
+ let maxYVal = Number.NEGATIVE_INFINITY;
polylines.forEach((obj) => {
obj.forEach((coord) => {
if (coord[0] > maxXVal) {
maxXVal = coord[0];
}
- })
- })
-
- let maxYVal = Number.NEGATIVE_INFINITY;
- polylines.forEach((obj) => {
- obj.forEach((coord) => {
if (coord[1] > maxYVal) {
maxYVal = coord[1];
}
})
})
-
- const xFactor = width/maxXVal;
- const yFactor = height/maxYVal;
-
- polylines.forEach((obj) => {
- obj.forEach((coord) => {
- coord[0] *= xFactor;
- })
- })
-
+
+ var ratio = Math.min(width / maxXVal, height / maxYVal);
+
polylines.forEach((obj) => {
obj.forEach((coord) => {
- coord[1] *= yFactor;
+ coord[0] *= ratio;
+ coord[1] *= ratio;
})
})
+ if (ratio == height / maxYVal) {
+ translate(polylines, [width/2 - maxXVal * ratio / 2, 0]);
+ } else if (ratio == width / maxXVal) {
+ translate(polylines, [0, height/2 - maxYVal * ratio / 2]);
+ }
+ if (addPadding) {
+ scale(polylines, 0.97);
+ }
+
return JSON.stringify(polylines);
},
join() {
const [first, ...rest] = arguments;
if (!first) return [];
if (!rest) return first;
-
+
rest.forEach(pls => {
pls.forEach(pl => {
first.push(pl);
})
});
-
+
return first;
},
copy: obj => JSON.parse(JSON.stringify(obj))
From 5247851584b98654ae249318990942335ef78852 Mon Sep 17 00:00:00 2001
From: whatwareweb <59752545+whatwareweb@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:38:34 -0500
Subject: [PATCH 4/5] Update toolkit.js
remove extra whitespace
---
src/drawingToolkit/toolkit.js | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/drawingToolkit/toolkit.js b/src/drawingToolkit/toolkit.js
index 0056f8754..30eb3dc14 100644
--- a/src/drawingToolkit/toolkit.js
+++ b/src/drawingToolkit/toolkit.js
@@ -65,34 +65,34 @@ export const toolkit = {
if (boundary === "closed" && points.length > 3) {
points.pop();
};
-
+
var curve = nurbs({
points,
degree,
boundary
});
-
+
const pl = [];
const domain = curve.domain[0];
const range = domain[1] - domain[0];
const stepSize = range/steps;
-
+
let i = domain[0];
while (i <= domain[1]) {
-
+
const pt = curve.evaluate([], i);
pl.push(pt);
-
+
i += stepSize;
}
-
+
if (i !== domain[1]) {
const pt = curve.evaluate([], domain[1]);
pl.push(pt);
}
-
+
return pl;
-
+
function isClosed(polyline, epsilon = 1e-3) {
let start = polyline[0]
let end = polyline[polyline.length - 1]
@@ -124,12 +124,12 @@ export const toolkit = {
polylines.forEach(pl => {
const newPl = simplifyPolyline(pl, tolerance, hq)
while (pl.length > 0) pl.pop()
-
+
while (newPl.length > 0) {
pl.push(newPl.shift())
}
})
-
+
return polylines;
},
trim: trimPolylines,
@@ -221,13 +221,13 @@ export const toolkit = {
const [first, ...rest] = arguments;
if (!first) return [];
if (!rest) return first;
-
+
rest.forEach(pls => {
pls.forEach(pl => {
first.push(pl);
})
});
-
+
return first;
},
copy(obj) {
From 8fa5f70e4029e16a33dd2c1628910b359aac1417 Mon Sep 17 00:00:00 2001
From: whatwareweb <59752545+whatwareweb@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:54:56 -0500
Subject: [PATCH 5/5] Update DropBox.tsx
Remove extra whitespace
---
src/components/DropBox.tsx | 48 +++++++++++++++++++-------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/src/components/DropBox.tsx b/src/components/DropBox.tsx
index 5881a4d4b..741d08744 100644
--- a/src/components/DropBox.tsx
+++ b/src/components/DropBox.tsx
@@ -8,10 +8,10 @@ export default function DropBox() {
// Make sure the ref is defined
addDragDrop();
}, []); // Empty dependency array means this effect runs once after initial render
-
+
return (
- Drop an SVG or JS file.
+ Drop an SVG or JS file.
);
}
function addDragDrop() {
const droparea: HTMLElement | null = document.querySelector(".droparea");
-
+
window.addEventListener("drop", function (evt) {
const { view } = getStore();
-
+
let dt = evt.dataTransfer;
-
+
if (dt === null || droparea === null) return;
-
+
let files = dt.files;
-
+
droparea.classList.add("hidden");
-
+
const file = files[0];
const fileName = file.name.split(".");
const name = fileName[0];
const extension = fileName[fileName.length - 1];
-
+
var reader = new FileReader();
reader.readAsText(file);
-
+
reader.onloadend = (event) => {
let text = reader.result;
-
+
if (extension === "js") {
loadCodeFromString(text);
} else if (extension === "svg") {
text = text.replaceAll("\n", "");
-
+
const polylines = JSON.stringify(tk.svgToPolylines(text));
-
+
customAlert(polylines);
-
+
// const newLines = `const importedSVG = ${polylines};\n`;
-
+
// view.dispatch({
// changes: { from: 0, insert: newLines },
// });
@@ -79,19 +79,19 @@ function addDragDrop() {
throw Error("Unknown extension:" + extension);
}
};
-
+
pauseEvent(evt);
});
-
+
window.addEventListener("dragover", function (evt) {
droparea.classList.remove("hidden");
pauseEvent(evt);
});
["mouseout"].forEach((trigger) =>
window.addEventListener(trigger, function (evt) {
- droparea.classList.add("hidden");
- }),
-);
+ droparea.classList.add("hidden");
+ }),
+ );
}
function pauseEvent(e) {
@@ -137,7 +137,7 @@ function customAlert(polylines) {
Here are the polylines of your SVG. Copy and paste it into the editor.
${polylines}
-
+
close
@@ -148,7 +148,7 @@ function customAlert(polylines) {
`
-
+
el.querySelector("#closeButton").addEventListener("click", () => {
el.remove();
})
@@ -212,4 +212,4 @@ function scaleAlert(polylines) {
})
document.body.append(el);
-}
\ No newline at end of file
+}