Select Git revision
-
Jakob Yanagibashi authoredJakob Yanagibashi authored
main.js 30.38 KiB
import "normalize.css";
import "./css/main.css";
import tailorbirdLogo from "./img/logo-new.jpg";
// Zdog
import * as Zdog from "zdog";
// Font Awesome
import "@fortawesome/fontawesome-free/css/fontawesome.css";
import "@fortawesome/fontawesome-free/css/solid.css";
var aboutText = `
</h1>
<p>Version: ${ import.meta.env.VITE_APP_DATE }
(${ import.meta.env.VITE_APP_HASH })</p>
`;
if (import.meta.env.VITE_APP_BRANCH == "dev") {
aboutText = `
<i class="fa-solid fa-kiwi-bird fa-bounce"></i> TESTING</h1>
<p>Version: ${ import.meta.env.VITE_APP_DATE }
(${ import.meta.env.VITE_APP_BRANCH }
${ import.meta.env.VITE_APP_HASH })</p>
`;
}
document.querySelector("#app").innerHTML = `
<main>
<section id="viewer">
<article id="viewer-main">
<canvas class="zdog-canvas"></canvas>
</article>
<article id="viewer-settings">
<menu>
<li>
<button id="zoomIntoViewButton">
<i class="fa-solid fa-magnifying-glass-plus"></i>
</button>
</li>
<li>
<button id="zoomOutViewButton">
<i class="fa-solid fa-magnifying-glass-minus"></i>
</button>
</li>
<li>
<button id="playViewButton">
<i class="fa-solid fa-play"></i> Simulate
</button>
</li>
</menu>
<menu class="menu-impressum">
<li>
<a href="#" id="helpLink">About</a>
</li>
<li>
<a href="mailto:yanagibashi@kg.rwth-aachen.de">Feedback</a>
</li>
<li>
<a href="https://www.kg.rwth-aachen.de/cms/KG/Footer/Service/~vcyq/Impressum/">Impressum</a>
</li>
</menu>
<menu class="menu-right">
<li>
<button id="saveProjectMenuButton">
<i class="fa-solid fa-floppy-disk"></i> Save
</button>
</li>
<li>
<button id="loadProjectMenuButton">
<i class="fa-solid fa-folder-open"></i> Load
</button>
</li>
<li>
<button id="exportProjectMenuButton">
<i class="fa-solid fa-file-export"></i> Export
</button>
</li>
<li>
<button id="openSettingsButton">
<i class="fa-solid fa-gear"></i> Settings
</button>
</li>
</menu>
</article>
</section>
<section id="tools">
<img id="tailorbirdLogo" src="${tailorbirdLogo}" />
<article id="tools-edit">
<menu>
<li>
<button id="addLineEditButton">
<i class="fa-solid fa-lines-leaning"></i> Add line
</button>
</li>
<li>
<button id="addArcEditButton">
<i class="fa-solid fa-bezier-curve"></i> Add arc
</button>
</li>
</menu>
</article>
<article id="tools-list">
<ul id="list-commands"></ul>
</article>
<article id="tools-list-buttons">
<menu>
<!-- <li>
<button id="editCommandButton" disabled>
<i class="fa-solid fa-pen-to-square"></i> Edit
</button>
</li> -->
<li>
<button id="removeCommandButton">
<i class="fa-solid fa-trash"></i> Remove
</button>
</li>
</menu>
</article>
</section>
</main>
<!-- Dialogs -->
<dialog id="helpDialog">
<h1>Tailorbird 3D ${ aboutText }
<h2><i class="fa-solid fa-keyboard"></i> Controls</h2>
<p>
<ul>
<li><i class="fa-solid fa-magnifying-glass"></i> <span class="helpControlText">Zoom: Scroll wheel</span></li>
<li><i class="fa-solid fa-left-right"></i> <span class="helpControlText">Rotate horizontally: Drag</span></li>
<li><i class="fa-solid fa-up-down"></i> <span class="helpControlText">Rotate vertically: Shift+Drag</span></li>
<li><i class="fa-solid fa-up-down-left-right"></i> <span class="helpControlText">Move: Opt/Alt+Drag</span></li>
<li><i class="fa-solid fa-share fa-rotate-90"></i> <span class="helpControlText">Jump to: O</span></li>
</ul>
</p>
<form method="dialog">
<menu>
<button value="example1">Load example 1</button>
<button value="example2">Load example 2</button>
<button value="cancel">Close</button>
</menu>
</form>
</dialog>
<!-- Dialogs Main menu -->
<dialog id="saveDialog">
<form method="dialog">
<input type="text" id="saveDialogInput" />
<menu>
<button value="save">Save</button>
<button value="cancel">Cancel</button>
</menu>
</form>
</dialog>
<dialog id="loadDialog">
<form method="dialog">
<input type="text" id="loadDialogInput" />
<br />
<ul id="loadDialogList">
</ul>
<menu>
<button value="load">Load</button>
<button value="cancel">Cancel</button>
</menu>
</form>
</dialog>
<dialog id="exportDialog">
<form method="dialog">
<menu>
<button value="export">Save as G-code</button>
<button value="close">Close</button>
</menu>
</form>
</dialog>
<!-- Dialogs Edit menu -->
<dialog id="addLineDialog">
<form method="dialog" id="addLineForm">
<h3>Add line</h3>
<fieldset>
<legend>Position</legend>
<input
type="radio"
id="addLineInputAbsRel2"
name="addLineInputAbsRel"
value="rel"
checked
/>
<label for="addLineInputAbsRel2">Relative</label>
<input
type="radio"
id="addLineInputAbsRel1"
name="addLineInputAbsRel"
value="abs"
/>
<label for="addLineInputAbsRel1">Absolute</label>
<br />
X: <input type="text" id="addLineInputX" value="0" /><br />
Y: <input type="text" id="addLineInputY" value="0" /><br />
Z: <input type="text" id="addLineInputZ" value="0" /><br />
</fieldset>
<fieldset>
<legend>Behavior</legend>
<input
type="radio"
id="addLineInputExtPmmAbs1"
name="addLineInputExtPmmAbs"
value="pmm"
checked
/>
<label for="addLineInputExtPmmAbs1">per mm</label>
<input
type="radio"
id="addLineInputExtPmmAbs2"
name="addLineInputExtPmmAbs"
value="abs"
/>
<label for="addLineInputExtPmmAbs2">Absolute</label>
<br />
Flow (<strong>E</strong>xtrusion):
<input
type="text"
id="addLineInputE"
value="1"
/><br />
Speed (<strong>F</strong>eed):
<input
type="text"
id="addLineInputF"
value="1500"
/><br />
</fieldset>
<menu>
<button value="add">Add</button>
<button value="cancel">Cancel</button>
</menu>
</form>
</dialog>
<dialog id="addArcDialog">
<form method="dialog" id="addArcForm">
<h3>Add arc</h3>
<fieldset>
<legend>Properties</legend>
Size: <input type="text" id="addArcInputSize" /><br />
Curvature:
<br />
<input
type="radio"
id="addArcInputCurvature1"
name="addArcInputCurvature"
value="1"
checked
/>
<label for="addArcInputCurvature1">Curved upwards</label>
<input
type="radio"
id="addArcInputCurvature2"
name="addArcInputCurvature"
value="2"
/>
<label for="addArcInputCurvature2">Curved downwards</label>
<br />
Direction:
<br />
<input
type="radio"
id="addArcInputDirection1"
name="addArcInputDirection"
value="1"
checked
/>
<label for="addArcInputDirection1">X pos</label>
<input
type="radio"
id="addArcInputDirection2"
name="addArcInputDirection"
value="2"
/>
<label for="addArcInputDirection2">Y pos</label>
<input
type="radio"
id="addArcInputDirection3"
name="addArcInputDirection"
value="3"
/>
<label for="addArcInputDirection3">X neg</label>
<input
type="radio"
id="addArcInputDirection4"
name="addArcInputDirection"
value="4"
/>
<label for="addArcInputDirection4">Y neg</label>
<br />
<input
type="radio"
id="addArcInputDirectionZ1"
name="addArcInputDirectionZ"
value="1"
checked
/>
<label for="addArcInputDirectionZ1">Up</label>
<input
type="radio"
id="addArcInputDirectionZ2"
name="addArcInputDirectionZ"
value="2"
/>
<label for="addArcInputDirectionZ2">Down</label>
<input
type="radio"
id="addArcInputDirectionZ3"
name="addArcInputDirectionZ"
value="3"
/>
<label for="addArcInputDirectionZ2">Flat</label>
</fieldset>
<fieldset>
<legend>Behavior</legend>
Flow:
<input
type="text"
id="addArcInputE"
placeholder="Extrusion rate"
value="0"
/><br />
Speed:
<input
type="text"
id="addArcInputF"
placeholder="Feed rate"
value="1500"
/><br />
</fieldset>
<menu>
<button value="add">Add</button>
<button value="cancel">Cancel</button>
</menu>
</form>
</dialog>
<!-- Dialogs View menu -->
<dialog id="settingsDialog">
<form method="dialog" id="settingsForm">
<fieldset>
<legend>Grid</legend>
<input
type="checkbox"
id="settingsGridDisplay"
name="settingsGridDisplay"
checked=""
/>
<label for="settingsGridDisplay"> Display grid</label><br />
<br />
<label for="settingsGridSizeInput">Size: </label>
<input
type="text"
id="settingsGridSizeInput"
placeholder="Default: 10"
/>
mm
</fieldset>
<fieldset>
<legend>Rendering</legend>
<input
type="checkbox"
id="settingsRenderNoExtrusionDisplay"
name="settingsRenderNoExtrusionDisplay"
checked=""
/>
<label for="settingsRenderNoExtrusionDisplay">
Display moves without extrusion</label
>
</fieldset>
<fieldset>
<legend>G-code Export</legend>
<label for="settingsGcodeStartCode">Start Code</label><br />
<textarea id="settingsGcodeStartCode" name="settingsGcodeStartCode">
; -- START GCODE --
G90
M82
G28
G92 E0.0000
G1 E-4.0000 F60000
; -- end of START GCODE --</textarea
>
<br /><br />
<label for="settingsGcodeEndCode">End Code</label><br />
<textarea id="settingsGcodeEndCode" name="settingsGcodeEndCode">
; -- END GCODE --
G92 E0.0000
G1 E-4.0000 F60000
G28
; -- end of END GCODE --</textarea
>
</fieldset>
<menu>
<button value="apply">Apply</button>
</menu>
</form>
</dialog>
`;
// Old main.js
import { Project } from "./js/project.js";
import { Move } from "./js/command.js";
function getPresetModelVase() {
var presetProject = new Project();
var precision = 10;
var zoom = 30;
const levels = 20;
const extMultiplier = 1;
const levelHeight = 3;
var previousGoal = {
x: 0,
y: 0,
e: -zoom,
};
var currentGoal = {
x: 0,
y: 0,
e: 0,
};
for (var e = 0; e < levels; e++) {
for (var i = 0; i < precision; i++) {
currentGoal.x = Math.sin((1 / precision) * 2 * Math.PI * i) * zoom;
currentGoal.y = Math.cos((1 / precision) * 2 * Math.PI * i) * zoom;
currentGoal.e =
previousGoal.e +
Math.hypot(
currentGoal.x - previousGoal.x,
currentGoal.y - previousGoal.y
);
var newCommand = new Move(
currentGoal.e * extMultiplier,
1250,
currentGoal.x,
currentGoal.y,
e * levelHeight + levelHeight / precision
);
presetProject.model.append(newCommand);
previousGoal.x = currentGoal.x;
previousGoal.y = currentGoal.y;
previousGoal.e = currentGoal.e;
}
if (e < levels / 2) {
zoom += 0.5 + (e % 10) / 10;
precision += 1;
} else {
zoom -= 0.5 + (e % 10) / 10;
precision -= 1;
}
}
return presetProject;
}
function getPresetModelVertical() {
var presetProject = new Project();
var extMult = 4;
var ext = 0;
const startX = 35;
var currPoint;
presetProject.addLine(ext, 2500, 0, 0, 0);
presetProject.addLine(ext, 1500, startX - extMult, 0, 0);
presetProject.addLine(ext += 4, 1500, startX, 0, 0);
presetProject.addLine(ext, 1500, startX + 15, 0, 0);
presetProject.addLine(ext, 1500, startX - extMult, 0, 10);
for (var i = 1; i < 10; i++) {
currPoint = i * extMult;
// Go to starting point
presetProject.addLine(ext, 2000, startX - currPoint, 0, 0);
presetProject.addLine(ext += extMult, 1500, startX - currPoint, 0, 0);
// Draw arc
presetProject.addArc(ext += currPoint * 1.8, 1500, currPoint, "1", "1", "1");
presetProject.addLine(ext, 2000, startX + currPoint / 2, 0, Math.max(currPoint - 25, 0));
presetProject.addLine(ext, 2000, startX + currPoint / 2 + 10, 0, 0);
presetProject.addLine(ext, 1500, startX, 0, currPoint + 10);
presetProject.addLine(ext, 1500, startX - currPoint - 10, 0, currPoint);
}
return presetProject;
}
/* Model modification */
function editSelectedCommand() {}
function removeSelectedCommand() {
// Remove item from list in DOM
window.selectedListEntries.forEach((entry) => {
entry.listElement.parentNode.removeChild(entry.listElement);
window.currentProject.model.remove(entry);
});
window.selectedListEntries = [];
//window.currentProject.draw();
/*
document
.getElementById("list-commands")
.removeChild(window.selectedListEntry);
// Remove reference from Model to Command
window.currentProject.removeCommand(window.selectedListEntry.parentCommand);*/
}
/* 3D & UI */
function initIllo() {
window.illo = new Zdog.Illustration({
element: ".zdog-canvas",
scale: 10,
resize: true,
rotate: { x: Zdog.TAU * 0.2 },
});
// Wheel (zoom)
window.illo.element.addEventListener("wheel", (e) => {
e.preventDefault();
// Zoom into: positive, Zoom out: negative, e.deltaY
if (
(window.illo.scale.x < 2 && e.deltaY > 0) ||
(window.illo.scale.x > 80 && e.deltaY < 0)
) {
return;
}
window.illo.scale.multiply(
1 - Math.max(Math.min(e.deltaY / 40, 0.9), -0.9)
);
});
// Drag (move)
window.viewRotation = new Zdog.Vector();
new Zdog.Dragger({
startElement: window.illo.element,
onDragStart: function (pointer) {
if (pointer.buttons == 4 || pointer.altKey) {
// Move object with middle mouse key or Meta key
window.dragStartRX = window.illo.translate.x;
window.dragStartRY = window.illo.translate.y;
} else if (pointer.shiftKey) {
// Rotate vertically with Shift key
window.dragStartRX = window.illo.rotate.x;
} else {
// Rotate horizontally
window.dragStartRX = window.illo.rotate.z;
}
},
onDragMove: function (pointer, moveX, moveY) {
if (pointer.buttons == 4 || pointer.altKey) {
// Move object with middle mouse key or Meta key
window.illo.translate.x = window.dragStartRX + moveX;
window.illo.translate.y = window.dragStartRY + moveY;
} else if (pointer.shiftKey) {
// Rotate vertically with Shift key
let moveRX = (moveY / illo.width) * Zdog.TAU * -1;
window.illo.rotate.x = window.dragStartRX + moveRX;
} else {
// Rotate horizontally
let moveRX = (moveX / illo.width) * Zdog.TAU * -1;
window.illo.rotate.z = window.dragStartRX + moveRX;
}
},
});
// O button (jump to)
window.addEventListener("keydown", (event) => {
if (event.isComposing || event.key !== "o" || !window.selectedListEntries[0]) {
return;
}
const jumpCmd = window.selectedListEntries[0];
if (!"goalx" in jumpCmd || !"goaly" in jumpCmd) {
return;
}
var illoTrans = new Zdog.Vector({
x: -jumpCmd.goaly.value * window.illo.scale.x,
y: -jumpCmd.goalx.value * window.illo.scale.y,
z: -jumpCmd.goalz.value * window.illo.scale.z,
});
illoTrans.rotate(window.illo.rotate);
console.log("jump to X: " + illoTrans.x + ", Y: " + illoTrans.y);
window.illo.translate = illoTrans;
});
window.currentProject.renderAll();
animateIllo();
}
function animateIllo() {
window.illo.updateRenderGraph();
window.animationReq = requestAnimationFrame(animateIllo);
}
/* Saving & loading */
function saveProject(projectToSave) {
console.log("Save project to: " + projectToSave);
saveToStorage(window.currentProject, projectToSave);
}
function loadProject(projectToLoad) {
console.log("Load project from: " + projectToLoad);
const loadedProject = loadFromStorage(projectToLoad);
//window.currentProject.unload();
window.currentProject = loadedProject;
//window.currentProject.load();
}
/*function loadProject() {
const projectToLoad = document.getElementById("project-input").value;
if (!Number.isInteger(parseInt(projectToLoad))) return;
if (projectToLoad.length != 4) return;
const functionName = "loadProject" + projectToLoad;
//runFunctionByName(functionName)();
eval(functionName + "()");
animateIllo();
}*/
/** LocalStorage **/
function loadFromStorage(modelName) {
const loadedJson = localStorage.getItem("model" + modelName);
if (!loadedJson) return;
const loadedObject = JSON.parse(loadedJson);
var loadedProject = new Project();
loadedObject.moves.forEach((command) => {
loadedProject.model.append(
new Move(
command[0].value,
command[1].value,
command[2].value,
command[3].value,
command[4].value
)
);
});
return loadedProject;
}
function saveToStorage(modelToSave, modelName) {
var jsonObject = { moves: [] };
currentProject.model.commands.forEach((command) => {
jsonObject.moves.push([
command.flow,
command.speed,
command.goalx,
command.goaly,
command.goalz,
]);
});
const jsonToSave = JSON.stringify(jsonObject);
console.log(jsonToSave);
localStorage.setItem("model" + modelName, jsonToSave);
}
/** Files **/
function saveToFile() {
const a = document.createElement("a");
const file = new Blob([document.getElementById("textarea-output").value], {
type: "text/plain",
});
a.href = URL.createObjectURL(file);
a.download = "output.gcode";
a.click();
URL.revokeObjectURL(a.href);
}
/* Event listeners */
function initEventListeners() {
initMainEventListeners(); /* Top bar menu */
initEditEventListeners(); /* Edit menu */
initViewEventListeners(); /* View menu */
initModalEventListeners(); /* All modals */
}
function initMainEventListeners() {
document
.getElementById("exportProjectMenuButton")
.addEventListener("click", function onOpen() {
document.getElementById("exportDialog").showModal();
});
document
.getElementById("saveProjectMenuButton")
.addEventListener("click", function onOpen() {
document.getElementById("saveDialog").showModal();
});
document
.getElementById("loadProjectMenuButton")
.addEventListener("click", function onOpen() {
const saveList = document.getElementById("loadDialogList");
saveList.replaceChildren();
for (let i = 0; i < localStorage.length; i++) {
if (!localStorage.key(i).startsWith("model")) {
continue;
}
var saveItem = document.createElement("li");
saveItem.appendChild(
document.createTextNode(localStorage.key(i).substring(5))
);
saveList.appendChild(saveItem);
}
document.getElementById("loadDialog").showModal();
});
document
.getElementById("helpLink")
.addEventListener("click", function onOpen() {
document.getElementById("helpDialog").showModal();
});
}
function initEditEventListeners() {
// Add line / arc
document
.getElementById("addLineEditButton")
.addEventListener("click", function onOpen() {
document.getElementById("addLineDialog").showModal();
});
document
.getElementById("addArcEditButton")
.addEventListener("click", function onOpen() {
document.getElementById("addArcDialog").showModal();
});
// Remove / Edit
document
.getElementById("removeCommandButton")
.addEventListener("click", removeSelectedCommand);
/*
document
.getElementById("editCommandButton")
.addEventListener("click", editSelectedCommand);*/
// Select Command in List
document
.getElementById("list-commands")
.addEventListener("click", function (e) {
e.preventDefault();
if (!e.shiftKey) {
// Remove old selection
window.selectedListEntries.forEach((entry) => entry.removeSelection());
window.selectedListEntries = [];
}
// Add selection
if (e.target && e.target.matches("li")) {
//window.selectedListEntry = e.target; TEST for removal
e.target.command.addSelection();
window.selectedListEntries.push(e.target.command);
}
});
}
function initViewEventListeners() {
document
.getElementById("zoomIntoViewButton")
.addEventListener("click", function (e) {
// Zoom into
window.illo.scale.multiply(1.1);
});
document
.getElementById("zoomOutViewButton")
.addEventListener("click", function (e) {
// Zoom out
window.illo.scale.multiply(1 / 1.1);
});
document
.getElementById("playViewButton")
.addEventListener("click", function (e) {
if (e.target.lastChild.nodeValue.includes("Simulate")) {
window.currentProject.drawPlaybackStart();
} else {
window.currentProject.drawPlaybackStop();
}
});
document
.getElementById("openSettingsButton")
.addEventListener("click", function (e) {
document.getElementById("settingsDialog").showModal();
});
}
function saveAs(blob, name) {
const a = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
a.download = name;
a.rel = "noopener";
a.href = URL.createObjectURL(blob);
a.target = "_blank";
setTimeout(() => {
URL.revokeObjectURL(a.href);
document.body.removeChild(a);
}, 30000);
setTimeout(() => {
document.body.appendChild(a);
a.click();
}, 0);
}
function initModalEventListeners() {
document
.getElementById("exportDialog")
.addEventListener("close", function onClose() {
// Check if Export button was pressed
if (event.target.returnValue != "export") return;
console.log("Exporting to G-code...");
var gcode = "";
/*var maxVals = { x: 0, y: 0, z: 0, e: 0 };
var minVals = { x: 0, y: 0, z: 0 };*/
let initCode = {
start: null,
end: null,
};
if (
!(
(initCode.start = localStorage.getItem("settingsGcodeStartCode")) &&
(initCode.end = localStorage.getItem("settingsGcodeEndCode"))
)
) {
initCode = {
start: `; -- START GCODE --
G90
M82
G28
G92 E0.0000
G1 E-4.0000 F60000
; -- end of START GCODE --
`,
end: `; -- END GCODE --
G92 E0.0000
G1 E-4.0000 F60000
G28
; -- end of END GCODE --
`,
};
}
gcode += initCode.start;
currentProject.model.commands.forEach((command) => {
gcode += command + "\n";
/*
if (command instanceof Move) {
const parameters = command.getParameters();
const vals = {
x: parameters[0].getValue(),
y: parameters[1].getValue(),
z: parameters[2].getValue(),
e: parameters[4].getValue(),
};
if (vals.z < 0.0) {
this.addStatOutput("CAUTION: Z-Axis below ground: " + command);
}
if (vals.e > maxVals.e) {
if (vals.x > maxVals.x) maxVals.x = vals.x;
if (vals.y > maxVals.y) maxVals.y = vals.y;
if (vals.z > maxVals.z) maxVals.z = vals.z;
if (vals.x < minVals.x) minVals.x = vals.x;
if (vals.y < minVals.y) minVals.y = vals.y;
if (vals.z < minVals.z) minVals.z = vals.z;
}
maxVals.e = vals.e;
}*/
});
/*
this.addStatOutput(
"Max X: " +
maxVals.x +
", Max Y: " +
maxVals.y +
", Max Z: " +
maxVals.z +
", Max E: " +
maxVals.e
);
this.addStatOutput(
"Min X: " + minVals.x + ", Min Y: " + minVals.y + ", Min Z: " + minVals.z
);
this.addStatOutput("G-Code generation successful.");*/
gcode += initCode.end;
// DEBUG!!
//console.log(gcode);
//return;
var blob = new Blob([gcode], { type: "text/plain;charset=utf-8" });
saveAs(blob, "tailorbird.gcode");
});
document
.getElementById("settingsDialog")
.addEventListener("close", function onClose(e) {
// Check if Apply button was pressed
if (e.target.returnValue != "apply") return;
const data = new FormData(document.querySelector("#settingsForm"));
// Grid display
if (data.has("settingsGridDisplay")) {
localStorage.setItem("settingsGridDisplay", "on");
} else {
localStorage.setItem("settingsGridDisplay", "off");
}
// Grid size
const gridSizeInput = document.getElementById("settingsGridSizeInput");
if (Number.isInteger(parseInt(gridSizeInput.value, 10))) {
localStorage.setItem("settingsGridSize", gridSizeInput.value);
} else {
localStorage.setItem("settingsGridSize", "10");
}
gridSizeInput.value = localStorage.getItem("settingsGridSize");
// Non-extruding move display
if (data.has("settingsRenderNoExtrusionDisplay")) {
localStorage.setItem("settingsRenderNoExtrusionDisplay", "on");
} else {
localStorage.setItem("settingsRenderNoExtrusionDisplay", "off");
}
// G-code start / end code
localStorage.setItem(
"settingsGcodeStartCode",
data.get("settingsGcodeStartCode")
);
localStorage.setItem(
"settingsGcodeEndCode",
data.get("settingsGcodeEndCode")
);
// Re-render everything
window.currentProject.renderAll();
});
document
.getElementById("saveDialog")
.addEventListener("close", function onClose(e) {
// Check if Load button was pressed
if (e.target.returnValue != "save") return;
const inputEl = document.getElementById("saveDialogInput");
saveProject(inputEl.value);
});
document
.getElementById("loadDialog")
.addEventListener("close", function onClose(e) {
// Check if Load button was pressed
if (e.target.returnValue != "load") return;
const inputEl = document.getElementById("loadDialogInput");
const saveInputEl = document.getElementById("saveDialogInput");
loadProject(inputEl.value);
saveInputEl.value = inputEl.value;
inputEl.value = "";
});
document
.getElementById("helpDialog")
.addEventListener("close", function onClose(e) {
// Check if Load button was pressed
switch (e.target.returnValue) {
case "example1":
window.currentProject = getPresetModelVase();
break;
case "example2":
window.currentProject = getPresetModelVertical();
break;
default:
return;
}
});
document
.getElementById("addLineDialog")
.addEventListener("close", function onClose(e) {
// Check if Add button was pressed
if (e.target.returnValue != "add") return;
let inputX = document.getElementById("addLineInputX");
let inputY = document.getElementById("addLineInputY");
let inputZ = document.getElementById("addLineInputZ");
let inputE = document.getElementById("addLineInputE"); // Extrusion (E) - Flow
let inputF = document.getElementById("addLineInputF"); // Feed rate (F) - Speed
const data = new FormData(document.querySelector("#addLineForm"));
const currCoords = currentProject.model.currentCoordinates();
// TODO: Make this nicer
if (data.get("addLineInputAbsRel") == "rel") {
if (data.get("addLineInputExtPmmAbs") == "pmm") {
window.currentProject.addLine(
Number.parseFloat(inputE.value) *
Math.hypot(
Number.parseFloat(inputX.value),
Number.parseFloat(inputY.value),
Number.parseFloat(inputZ.value)
) +
currCoords.e,
Number.parseFloat(inputF.value),
Number.parseFloat(inputX.value) + currCoords.x,
Number.parseFloat(inputY.value) + currCoords.y,
Number.parseFloat(inputZ.value) + currCoords.z
);
} else {
window.currentProject.addLine(
Number.parseFloat(inputE.value) + currCoords.e,
Number.parseFloat(inputF.value),
Number.parseFloat(inputX.value) + currCoords.x,
Number.parseFloat(inputY.value) + currCoords.y,
Number.parseFloat(inputZ.value) + currCoords.z
);
}
} else {
if (data.get("addLineInputExtPmmAbs") == "pmm") {
window.currentProject.addLine(
Number.parseFloat(inputE.value) *
Math.hypot(
Number.parseFloat(inputX.value) - currCoords.x,
Number.parseFloat(inputY.value) - currCoords.y,
Number.parseFloat(inputZ.value) - currCoords.z
) +
currCoords.e,
Number.parseFloat(inputF.value),
Number.parseFloat(inputX.value),
Number.parseFloat(inputY.value),
Number.parseFloat(inputZ.value)
);
} else {
window.currentProject.addLine(
Number.parseFloat(inputE.value) + currCoords.e,
Number.parseFloat(inputF.value),
Number.parseFloat(inputX.value),
Number.parseFloat(inputY.value),
Number.parseFloat(inputZ.value)
);
}
}
inputX.value = "";
inputY.value = "";
inputZ.value = "";
});
document
.getElementById("addArcDialog")
.addEventListener("close", function onClose(e) {
// Check if Add button was pressed
if (e.target.returnValue != "add") return;
const size = document.getElementById("addArcInputSize");
const data = new FormData(document.querySelector("#addArcForm"));
window.currentProject.addArc(
data.get("addArcInputE"),
data.get("addArcInputF"),
size.value,
data.get("addArcInputDirection"),
data.get("addArcInputDirectionZ"),
data.get("addArcInputCurvature")
);
size.value = "";
});
}
/* Load application */
window.onload = function () {
window.currentProject = new Project();
window.selectedListEntries = [];
initIllo();
initEventListeners();
if (localStorage.getItem("splashSeen") !== "1") {
localStorage.setItem("splashSeen", "1");
document.getElementById("helpDialog").showModal();
}
};