feat: Initial commit
This commit is contained in:
commit
2b34943a48
89
assets/calculator.js
Normal file
89
assets/calculator.js
Normal file
@ -0,0 +1,89 @@
|
||||
const MINIMUM_BASE_AREA = 0.5;
|
||||
const MINIMUM_AREA_THREE_RATS = 1.8;
|
||||
const AREA_PER_ADDITIONAL_RAT = 0.2;
|
||||
const MAXIMUM_FALL_HEIGHT = 0.5;
|
||||
const MINIMUM_LENGTH = 0.8;
|
||||
|
||||
const FAILED_BASE_AREA = "base_area";
|
||||
const FAILED_OVERALL_AREA = "overall_area";
|
||||
const FAILED_FALL_HEIGHT = "fall_height";
|
||||
const FAILED_NUM_RATS = "num_rats";
|
||||
const FAILED_LENGTH = "length";
|
||||
|
||||
const FAIL_CRITERIA = {
|
||||
[FAILED_BASE_AREA]: `Die Mindestgrundfläche des Käfigs muss ${MINIMUM_BASE_AREA}m² (also z.B. 100x50cm) betragen.`,
|
||||
[FAILED_OVERALL_AREA]: "Die Gesamtfläche im Käfig ist zu klein.",
|
||||
[FAILED_FALL_HEIGHT]: `Die mögliche Fallhöhe darf nicht mehr als ${(MAXIMUM_FALL_HEIGHT * 100).toFixed(3)}cm betragen.`,
|
||||
[FAILED_NUM_RATS]: "Es müssen mindestens 3 Ratten zusammenleben, Paarhaltung ist nicht artgerecht.",
|
||||
[FAILED_LENGTH]: `Eine Seite des Käfig muss mindestens ${(MINIMUM_LENGTH * 100).toFixed(3)}cm lang sein um Rennen zu ermöglichen.`,
|
||||
};
|
||||
|
||||
class Dimensions {
|
||||
constructor(length, width, height) {
|
||||
this.length = length;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `${this.length}x${this.width}x${this.height}`;
|
||||
}
|
||||
|
||||
static fromDict(data) {
|
||||
const { length, width, height } = data;
|
||||
return new Dimensions(length, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
function overallAreaNeeded(numOfRats) {
|
||||
if (numOfRats < 3 || numOfRats > 15) {
|
||||
throw new Error("This formula works only from 3 to 15 rats");
|
||||
}
|
||||
return MINIMUM_AREA_THREE_RATS + (numOfRats - 3) * AREA_PER_ADDITIONAL_RAT;
|
||||
}
|
||||
|
||||
function cageCheck(dimensions, numRats, numFullFloors) {
|
||||
let failedCriteria = {};
|
||||
|
||||
if (numRats < 2 || numRats > 15) {
|
||||
failedCriteria[FAILED_NUM_RATS] = FAIL_CRITERIA[FAILED_NUM_RATS];
|
||||
}
|
||||
|
||||
const baseArea = dimensions.length * dimensions.width;
|
||||
if (baseArea < MINIMUM_BASE_AREA) {
|
||||
failedCriteria[FAILED_BASE_AREA] = FAIL_CRITERIA[FAILED_BASE_AREA];
|
||||
}
|
||||
|
||||
const areaNeeded = overallAreaNeeded(numRats);
|
||||
if (baseArea * numFullFloors < areaNeeded) {
|
||||
failedCriteria[FAILED_OVERALL_AREA] = FAIL_CRITERIA[FAILED_OVERALL_AREA];
|
||||
}
|
||||
|
||||
if (dimensions.height / numFullFloors > MAXIMUM_FALL_HEIGHT) {
|
||||
failedCriteria[FAILED_FALL_HEIGHT] = FAIL_CRITERIA[FAILED_FALL_HEIGHT];
|
||||
}
|
||||
|
||||
if (dimensions.width < MINIMUM_LENGTH && dimensions.length < MINIMUM_LENGTH) {
|
||||
failedCriteria[FAILED_LENGTH] = FAIL_CRITERIA[FAILED_LENGTH];
|
||||
}
|
||||
|
||||
return failedCriteria;
|
||||
}
|
||||
|
||||
const expectedAreaPerNumRats = { 3: 1.8, 4: 2.0 };
|
||||
for (let numRats in expectedAreaPerNumRats) {
|
||||
console.log(`Area needed for ${numRats}: Calculated=${overallAreaNeeded(parseInt(numRats))}`);
|
||||
}
|
||||
|
||||
const exampleCageChecks = [
|
||||
[[], new Dimensions(1, 0.50, 1), 4, 4],
|
||||
[[FAIL_CRITERIA[FAILED_BASE_AREA]], new Dimensions(0.99, 0.50, 1), 3, 4],
|
||||
[[FAIL_CRITERIA[FAILED_OVERALL_AREA]], new Dimensions(0.99, 0.50, 1), 4, 4],
|
||||
[[FAIL_CRITERIA[FAILED_OVERALL_AREA]], new Dimensions(0.79, 0.79, 1), 4, 4],
|
||||
];
|
||||
|
||||
for (let idx in exampleCageChecks) {
|
||||
let check = exampleCageChecks[idx];
|
||||
console.log(`Example ${idx}: ${check[1]} n(rats): ${check[2]}, n(floors): ${check[3]}`);
|
||||
console.log(`Result: ${JSON.stringify(cageCheck(check[1], check[2], check[3]))}\n`);
|
||||
}
|
39
assets/css/style.css
Normal file
39
assets/css/style.css
Normal file
@ -0,0 +1,39 @@
|
||||
.slidecontainer {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.slider {
|
||||
-webkit-appearance: none;
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
border-radius: 5px;
|
||||
background: #d3d3d3;
|
||||
outline: none;
|
||||
opacity: 0.7;
|
||||
-webkit-transition: .2s;
|
||||
transition: opacity .2s;
|
||||
}
|
||||
|
||||
.slider:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 23px;
|
||||
height: 24px;
|
||||
border: 0;
|
||||
background: url('/assets/img/logo_transparent.png');
|
||||
background-size: 100% 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.slider::-moz-range-thumb {
|
||||
width: 23px;
|
||||
height: 24px;
|
||||
border: 0;
|
||||
background: url('/assets/img/logo_transparent.png');
|
||||
background-size: 100% 100%;
|
||||
cursor: pointer;
|
||||
}
|
BIN
assets/img/logo.png
Normal file
BIN
assets/img/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
assets/img/logo_transparent.png
Normal file
BIN
assets/img/logo_transparent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
assets/img/logo_transparent_small.png
Normal file
BIN
assets/img/logo_transparent_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 546 B |
72
index.html
Normal file
72
index.html
Normal file
@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Knastrechner</title>
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
<script src="assets/calculator.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Range Slider Picture</h1>
|
||||
|
||||
<div class="slidecontainer">
|
||||
<input type="range" min="1" max="20" value="4" class="slider" id="numRats">
|
||||
<label for="numRats">Anzahl an Ratten
|
||||
<div id="outputNumRats"></div>
|
||||
</label>
|
||||
|
||||
|
||||
<input type="range" min="1" max="4" value="2" class="slider" id="numFullFloors">
|
||||
<label for="numFullFloors">Vollebenen
|
||||
<div id="outputNumFullFloors"></div>
|
||||
</label>
|
||||
<div class="container" id="resultsDiv">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var outputFailedChecks = document.getElementById("failedChecks");
|
||||
|
||||
var ratSlider = document.getElementById("numRats");
|
||||
var outputNumRats = document.getElementById("outputNumRats");
|
||||
outputNumRats.innerHTML = ratSlider.value;
|
||||
|
||||
ratSlider.oninput = function () {
|
||||
outputNumRats.innerHTML = this.value;
|
||||
update();
|
||||
}
|
||||
|
||||
// Full floor functions
|
||||
var fullFloorSlider = document.getElementById("numFullFloors");
|
||||
var outputNumFullFloors = document.getElementById("outputNumFullFloors");
|
||||
outputNumFullFloors.innerHTML = fullFloorSlider.value;
|
||||
|
||||
fullFloorSlider.oninput = function () {
|
||||
outputNumFullFloors.innerHTML = this.value;
|
||||
update();
|
||||
}
|
||||
|
||||
var savicSuiteRoyaleDim = new Dimensions(1, 0.5, 1);
|
||||
|
||||
function update() {
|
||||
var failed_checks = cageCheck(savicSuiteRoyaleDim, ratSlider.value, fullFloorSlider.value);
|
||||
var resultsDiv = document.getElementById("resultsDiv");
|
||||
resultsDiv.innerHTML = `<strong>Werte</strong>: ${savicSuiteRoyaleDim.toString()} n(rats): ${ratSlider.value}, n(floors): ${fullFloorSlider.value}`;
|
||||
|
||||
const ul = document.createElement('ul');
|
||||
for (const key in failed_checks) {
|
||||
const li = document.createElement('li');
|
||||
li.textContent = failed_checks[key];
|
||||
ul.appendChild(li);
|
||||
}
|
||||
|
||||
resultsDiv.appendChild(ul);
|
||||
outputFailedChecks.innerHTML = failed_checks;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user