master
Dirk Heilig 2024-09-26 13:49:39 +02:00
commit f99c568576
7 changed files with 324 additions and 0 deletions

2
.gitignore vendored 100644
View File

@ -0,0 +1,2 @@
dist
node_modules/

32
Makefile 100644
View File

@ -0,0 +1,32 @@
.PHONY: dev-deploy pretty build build-src build-png build-assets default-target clean
default-target: build
clean:
rm -rf dist node_modules
dev-deploy: build
rsync -rv dist/* shnbk.de:domains/3dcalc.shnbk.de/htdocs/
pretty:
prettier -w src/**/*.html **/*.md
dist:
mkdir dist
build: build-assets build-png build-src
build-src: dist
minify -ar src/ -o dist
build-png: dist
pngcrush -q -d dist src/*.png
build-assets: dist node_modules
minify node_modules/bulma/css/bulma.min.css -o dist/bulma.min.css
node_modules: package.json
npm i
touch node_modules

29
Readme.md 100644
View File

@ -0,0 +1,29 @@
# Filament 3D Coast Calculator
Hiermit werden Druckkosten beim C3re berechnet.
Die Berechnung Basiert auf 4 Festen werten und 2-3 Userwerten.
Der user gibt ein (Werte aus dem Slicer):
- Druckdauer
- Ob er Pool-Filament nutzen will und wenn ja:
- Wie viel in g
Mit diesen Angaben werden die Kosten berechnet.
Die Fixwerte sind in der index.html relativ weit oben angegeben.
Berechnet wird, wenn kein Filament genutzt wird
```
Druckdauer * `pricePerPrintingHourInEuro`
```
Mit Pool-Filament wird berechnet:
```
Druckdauer * `pricePerPrintingHourInEuro` + `pricePerGrammPoolFilamentInEuro` * `poolFilamentInGramm`
```
In beiden Fällen wird dann auf die nächsten vollen wert von `roundUpStep` aufgerundet und dann wird noch identifierAddition dazu addiert.

27
package-lock.json generated 100644
View File

@ -0,0 +1,27 @@
{
"name": "filament_3d_coast_calculater",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "filament_3d_coast_calculater",
"version": "1.0.0",
"dependencies": {
"bulma": "^1.0.2"
}
},
"node_modules/bulma": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bulma/-/bulma-1.0.2.tgz",
"integrity": "sha512-D7GnDuF6seb6HkcnRMM9E739QpEY9chDzzeFrHMyEns/EXyDJuQ0XA0KxbBl/B2NTsKSoDomW61jFGFaAxhK5A=="
}
},
"dependencies": {
"bulma": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bulma/-/bulma-1.0.2.tgz",
"integrity": "sha512-D7GnDuF6seb6HkcnRMM9E739QpEY9chDzzeFrHMyEns/EXyDJuQ0XA0KxbBl/B2NTsKSoDomW61jFGFaAxhK5A=="
}
}
}

7
package.json 100644
View File

@ -0,0 +1,7 @@
{
"name": "filament_3d_coast_calculater",
"version": "1.0.0",
"dependencies": {
"bulma": "^1.0.2"
}
}

227
src/index.html 100644
View File

@ -0,0 +1,227 @@
<html class="theme-light">
<head>
<meta charset="UTF-8" />
<title>3D-Druck Kostenrechner</title>
<script>
// THIS IS CONFIGURATION
const pricePerPrintingHourInEuro = 0.3;
const pricePerMaterialGrammInEuro = 0.025;
const roundUpStep = 0.5;
const identifierAddition = 0.03;
</script>
<link rel="stylesheet" href="./bulma.min.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<div class="block" id="filamentcalc">
<style>
body {
padding: 2em;
background-color: #f5f5f5;
}
.box {
border: 0.125em solid #dbdbdb;
}
#logo {
float: right;
position: absolute;
top: 0;
right: 0;
}
.selected {
filter: brightness(90%);
text-decoration: underline;
}
.box {
margin: 2em auto 0;
max-width: 50em;
}
.b button {
float: right;
margin-right: 1em;
}
input {
margin-left: 1em;
width: 5em;
}
h2 {
margin-bottom: 0.5em;
font-weight: bold;
}
li {
list-style: none;
}
</style>
<section class="hero">
<div class="hero-body">
<h1 class="title">3D-Druck Filamentkostenrechner</h1>
<p id="logo" class="image is-128x128">
<img src="logo.png" />
</p>
</div>
</section>
<!--todo: frage und antwortbuttons in eine box packen-->
<div class="columns box">
<div class="column is-full b">
Wo kommt dein Filament her?
<button class="button" id="pool_filament">Pool Filament</button>
<button class="button" id="own_filament">
Eigenes/Spenden- Filament
</button>
</div>
</div>
<div class="columns box step2">
<div class="column">
<label for="printtime_h">Druckzeit</label>
</div>
<div class="column">
<input
id="printtime_h"
class="half"
type="number"
min="0"
max="1000"
step="1"
placeholder="0"
/>
<label for="printtime_h">h</label>
<input
id="printtime_m"
class="half"
type="number"
min="0"
max="5000"
step="1"
placeholder="0"
/>
<label for="printtime_m">m</label>
</div>
</div>
<div class="columns box step2 material">
<div class="column">
<label for="material">Materialmenge</label>
</div>
<div class="column">
<input
id="material"
type="number"
min="0"
max="1000"
step="1"
placeholder="0"
/>
<label for="material">g</label>
</div>
</div>
<div class="columns box step2">
<div class="column"><label for="cost_euro">Kosten in €</label></div>
<div class="column">
<input id="cost_euro" type="text" aria-disabled="true" disabled />
</div>
</div>
<div class="columns box step2">
<div class="column is-two">
<h2>Wie entsteht der Preis?</h2>
<ul>
<li>
Pro Druckstunde fallen <span id="pricePerHour">...</span> € Kosten
für Strom und Verschleiß an.
</li>
<li>
Pool-Filament wird mit <span id="pricePerMaterial">...</span>
pro kg berechnet.
</li>
<li>
Beide Kosten werden addiert und auf die nächsten
<span id="roundUpLimit">...</span> € aufgerundet.<span
id="idtext"
>
(Zusätzlich wird <span id="idval"></span> € addiert damit wir
auf der Abrechnung den Verwendungszweck erkennen können.)</span
>
</li>
</ul>
</div>
</div>
</div>
<script>
const pool_filament = document.getElementById("pool_filament");
const own_filament = document.getElementById("own_filament");
const step1 = document.getElementsByClassName("step1");
const step2 = document.getElementsByClassName("step2");
const printtime_h = document.getElementById("printtime_h");
const printtime_m = document.getElementById("printtime_m");
const material = document.getElementById("material");
const cost_euro = document.getElementById("cost_euro");
let ownFilament;
pool_filament.addEventListener("click", function () {
for (let i = 0; i < step2.length; i++) {
step2[i].style.display = "flex";
}
ownFilament = false;
updateCost();
});
own_filament.addEventListener("click", function () {
for (let i = 0; i < step2.length; i++) {
const el = step2[i];
if (el.classList.contains("material")) {
el.style.display = "none";
} else {
el.style.display = "flex";
}
}
ownFilament = true;
updateCost();
});
printtime_h.addEventListener("input", updateCost);
printtime_m.addEventListener("input", updateCost);
material.addEventListener("input", updateCost);
function updateCost() {
pricePerHour.innerHTML = pricePerPrintingHourInEuro.toFixed(2);
pricePerMaterial.innerHTML = (
pricePerMaterialGrammInEuro * 1000
).toFixed(2);
roundUpLimit.innerHTML = roundUpStep.toFixed(2);
idval.innerHTML = identifierAddition.toFixed(2);
if (identifierAddition === 0) {
idtext.style.display = "none";
} else {
idtext.style.display = "inherit";
}
const printtime =
parseInt("0" + printtime_h.value) * 60 +
parseInt("0" + printtime_m.value);
const materialcost =
parseInt("0" + material.value) * pricePerMaterialGrammInEuro;
let totalcost = (printtime * pricePerPrintingHourInEuro) / 60;
if (!ownFilament) {
totalcost += materialcost;
}
totalcost = Math.ceil(totalcost / roundUpStep) * roundUpStep;
if (totalcost > 0) {
totalcost += identifierAddition;
}
console.log(totalcost);
cost_euro.value = totalcost.toFixed(2) + " €";
if (ownFilament) {
own_filament.classList.add("selected");
pool_filament.classList.remove("selected");
} else {
pool_filament.classList.add("selected");
own_filament.classList.remove("selected");
}
}
updateCost();
</script>
</body>
</html>

BIN
src/logo.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB