Files
2026-08-21 15:49:37 +02:00

197 lines
7.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
class ScientificCalculator {
constructor(containerId) {
this.container = document.getElementById(containerId);
if (!this.container) return;
this.currentInput = "0";
this.previousInput = "";
this.operation = null;
this.init();
}
init() {
this.container.innerHTML = `
<div class="w-80 bg-slate-800 p-4 rounded-2xl shadow-xl select-none text-slate-100">
<!-- Écran -->
<div id="calc-screen" class="bg-slate-900 text-right p-4 rounded-xl mb-4 text-2xl font-mono tracking-wider overflow-hidden min-h-[4rem] flex flex-col justify-center">
<div id="calc-prev" class="text-xs text-slate-400 h-4"></div>
<div id="calc-current" class="truncate">0</div>
</div>
<!-- Clavier scientifique -->
<div class="grid grid-cols-4 gap-2 text-sm">
<!-- Ligne 0 : Fonctions avancées -->
<button data-action="scientific" data-value="sqrt" class="bg-indigo-700 hover:bg-indigo-600 p-2.5 rounded-xl font-bold transition">√</button>
<button data-action="scientific" data-value="sqr" class="bg-indigo-700 hover:bg-indigo-600 p-2.5 rounded-xl font-bold transition">x²</button>
<button data-action="scientific" data-value="inv" class="bg-indigo-700 hover:bg-indigo-600 p-2.5 rounded-xl font-bold transition">1/x</button>
<button data-action="clear" class="bg-red-600 hover:bg-red-500 p-2.5 rounded-xl font-bold transition">AC</button>
<!-- Ligne 1 : Trigo & Suppression -->
<button data-action="scientific" data-value="sin" class="bg-indigo-800 hover:bg-indigo-700 p-2.5 rounded-xl font-semibold transition">sin</button>
<button data-action="scientific" data-value="cos" class="bg-indigo-800 hover:bg-indigo-700 p-2.5 rounded-xl font-semibold transition">cos</button>
<button data-action="scientific" data-value="tan" class="bg-indigo-800 hover:bg-indigo-700 p-2.5 rounded-xl font-semibold transition">tan</button>
<button data-action="delete" class="bg-slate-700 hover:bg-slate-600 p-2.5 rounded-xl font-bold transition">⌫</button>
<!-- Ligne 2 -->
<button data-action="number" data-value="7" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">7</button>
<button data-action="number" data-value="8" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">8</button>
<button data-action="number" data-value="9" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">9</button>
<button data-action="operator" data-value="/" class="bg-amber-600 hover:bg-amber-500 p-3 rounded-xl font-bold transition">÷</button>
<!-- Ligne 3 -->
<button data-action="number" data-value="4" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">4</button>
<button data-action="number" data-value="5" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">5</button>
<button data-action="number" data-value="6" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">6</button>
<button data-action="operator" data-value="*" class="bg-amber-600 hover:bg-amber-500 p-3 rounded-xl font-bold transition">×</button>
<!-- Ligne 4 -->
<button data-action="number" data-value="1" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">1</button>
<button data-action="number" data-value="2" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">2</button>
<button data-action="number" data-value="3" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">3</button>
<button data-action="operator" data-value="-" class="bg-amber-600 hover:bg-amber-500 p-3 rounded-xl font-bold transition">-</button>
<!-- Ligne 5 -->
<button data-action="number" data-value="0" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">0</button>
<button data-action="number" data-value="." class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">.</button>
<button data-action="calculate" class="bg-emerald-600 hover:bg-emerald-500 p-3 rounded-xl font-bold transition">=</button>
<button data-action="operator" data-value="+" class="bg-amber-600 hover:bg-amber-500 p-3 rounded-xl font-bold transition">+</button>
</div>
</div>
`;
this.prevScreen = this.container.querySelector("#calc-prev");
this.currentScreen = this.container.querySelector("#calc-current");
this.addListeners();
}
addListeners() {
this.container.addEventListener("click", (e) => {
const button = e.target.closest("button");
if (!button) return;
const action = button.getAttribute("data-action");
const value = button.getAttribute("data-value");
if (action === "number") {
this.appendNumber(value);
} else if (action === "operator") {
this.chooseOperation(value);
} else if (action === "scientific") {
this.scientificOperation(value);
} else if (action === "calculate") {
this.compute();
} else if (action === "clear") {
this.clear();
} else if (action === "delete") {
this.deleteDigit();
}
this.updateScreen();
});
}
appendNumber(number) {
if (number === "." && this.currentInput.includes(".")) return;
if (this.currentInput === "0" && number !== ".") {
this.currentInput = number;
} else {
this.currentInput += number;
}
}
chooseOperation(op) {
if (this.currentInput === "") return;
if (this.previousInput !== "") {
this.compute();
}
this.operation = op;
this.previousInput = this.currentInput;
this.currentInput = "";
}
scientificOperation(func) {
const current = parseFloat(this.currentInput);
if (isNaN(current)) return;
let result;
switch (func) {
case "sqrt":
result = current < 0 ? "Erreur" : Math.sqrt(current);
break;
case "sqr":
result = Math.pow(current, 2);
break;
case "inv":
result = current === 0 ? "Erreur" : 1 / current;
break;
case "sin":
// Conversion en radians pour le calcul trigonométrique standard
result = Math.sin(current * (Math.PI / 180));
break;
case "cos":
result = Math.cos(current * (Math.PI / 180));
break;
case "tan":
result = Math.tan(current * (Math.PI / 180));
break;
default:
return;
}
this.currentInput =
typeof result === "number"
? parseFloat(result.toFixed(8)).toString()
: result;
}
compute() {
let computation;
const prev = parseFloat(this.previousInput);
const current = parseFloat(this.currentInput);
if (isNaN(prev) || isNaN(current)) return;
switch (this.operation) {
case "+":
computation = prev + current;
break;
case "-":
computation = prev - current;
break;
case "*":
computation = prev * current;
break;
case "/":
computation = current === 0 ? "Erreur" : prev / current;
break;
default:
return;
}
this.currentInput = parseFloat(computation.toFixed(8)).toString();
this.operation = null;
this.previousInput = "";
}
clear() {
this.currentInput = "0";
this.previousInput = "";
this.operation = null;
}
deleteDigit() {
if (this.currentInput.length === 1 || this.currentInput === "Erreur") {
this.currentInput = "0";
} else {
this.currentInput = this.currentInput.slice(0, -1);
}
}
updateScreen() {
this.currentScreen.innerText =
this.currentInput === "" ? "0" : this.currentInput;
if (this.operation != null) {
this.prevScreen.innerText = `${this.previousInput} ${this.operation}`;
} else {
this.prevScreen.innerText = "";
}
}
}