Partiamo subito con il definire la struttura del codice, per semplicità di condivisione ho preferito raccogliere tutto nell'HTML ma farei una breve distinzione del contenuto rappresentato in HTML, CSS e Javascript.
HTML: dopo la struttura base di una pagina è presente tutta la parte grafica della leva è contenuta in un div chiamato "lever-container" e la leva stessa è all'interno di un altro div chiamato "lever". Sono presenti anche campi di testo per inserire i valori di posizione del fulcro, posizione del carico, peso e lunghezza della leva (che verrà aggiornata in real-time).
Inutile specificare che nel CSS è presente tutta la parte grafica anche se di design c'è ben poco.😅
Iniziamo a parlare della parte Javascript che in questo caso è il succo del codice. Event listeners davvero importanti negli input dei campi di testo e agli slider per garantire un risultato nella leva in tempo reale.
Funzione updateLoadPosition(): viene chiamata quando l'utente cambia la posizione del fulcro o del carico. In pratica prende i valori dalle caselle di testo e aggiorna in live la posizione del fulcro e carico chiamando anche updateLeverAngle() per aggiornare l'angolo.
Approfondiamo meglio questa funzione updateLeverAngle() che calcola l'angolo di inclinazione della leva in base ai valori di posizione del fulcro, posizione del carico, peso e lunghezza della leva. Non funziona a caso o per proporzioni, funziona secondo delle formule.
- Momento Torcente: forza x braccio leva
- Braccio della Leva = (posizione carico - posizione fulcro) x lunghezza leva
- Angolo inclinazione = atan(Mom. Torc. / (Peso x 9.81))
Atan è una funzione per calcolare l'angolo in radianti.
Ovviamente come si può vedere i valori sono inseriti secondo unità di misura non modificabili.
Il sito web relativo è leva.samueleex.repl.co e il codice è il seguente:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Leva Simulator</title>
<style>
#lever-container {
width: 300px;
margin: 0 auto;
}
#lever {
width: 200px;
height: 20px;
background-color: gray;
position: relative;
}
#fulcrum {
width: 10px;
height: 40px;
background-color: black;
position: absolute;
top: -20px;
left: 50%;
transform: translateX(-50%);
}
#load {
width: 40px;
height: 40px;
background-color: blue;
position: absolute;
top: -20px;
left: 50%;
transform: translateX(-50%);
}
</style>
</head>
<body>
<h1>Leva Simulator</h1>
<div id="lever-container">
<div id="lever">
<div id="fulcrum"></div>
<div id="load"></div>
</div>
</div>
<p>Posizione del fulcro: <span id="fulcrumPosition">50%</span></p>
<p>Posizione del carico: <span id="loadPosition">50%</span></p>
<label for="fulcrumPositionInput">Posizione del fulcro (m):</label>
<input type="text" id="fulcrumPositionInput" value="0.5">
<label for="loadPositionInput">Posizione del carico (m):</label>
<input type="text" id="loadPositionInput" value="0.5">
<label for="weightInput">Peso (N):</label>
<input type="text" id="weightInput" value="10">
<label for="leverLengthInput">Lunghezza della leva (m):</label>
<input type="text" id="leverLengthInput" value="1">
<script>
const fulcrum = document.getElementById('fulcrum');
const load = document.getElementById('load');
const fulcrumPositionSpan = document.getElementById('fulcrumPosition');
const loadPositionSpan = document.getElementById('loadPosition');
const fulcrumPositionInput = document.getElementById('fulcrumPositionInput');
const loadPositionInput = document.getElementById('loadPositionInput');
const weightInput = document.getElementById('weightInput');
const leverLengthInput = document.getElementById('leverLengthInput');
const lever = document.getElementById('lever');
fulcrumPositionInput.addEventListener('input', () => {
fulcrumPositionSpan.textContent = `${fulcrumPositionInput.value} m`;
updateLoadPosition();
});
loadPositionInput.addEventListener('input', () => {
loadPositionSpan.textContent = `${loadPositionInput.value} m`;
updateLoadPosition();
});
weightInput.addEventListener('input', () => {
updateLeverAngle();
});
leverLengthInput.addEventListener('input', () => {
updateLeverAngle();
});
function updateLoadPosition() {
const fulcrumPosition = parseFloat(fulcrumPositionInput.value);
const loadPosition = parseFloat(loadPositionInput.value);
fulcrum.style.left = `${fulcrumPosition * 100}%`;
load.style.left = `${loadPosition * 100}%`;
updateLeverAngle();
}
function updateLeverAngle() {
const fulcrumPosition = parseFloat(fulcrumPositionInput.value);
const loadPosition = parseFloat(loadPositionInput.value);
const leverLength = parseFloat(leverLengthInput.value);
const weight = parseFloat(weightInput.value);
const leverArm = Math.abs(loadPosition - fulcrumPosition) * leverLength;
const torque = weight * leverArm;
const angle = Math.atan(torque);
lever.style.transform = `rotate(${angle}rad)`;
}
</script>
</body>
</html>