Mini-applications et mini-jeux

Calculatrice simple

Calculatrice arithmétique de base prenant en charge la saisie au clavier et les calculs successifs.

HTMLCSSJavaScriptCalculatrice
Après activation de JavaScript, ce cas peut être modifié, exécuté et enregistré. Code source fixe ci-dessous :
<!doctype html>
<html lang="fr" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Calculatrice simple</title>
  <style>
    * { box-sizing: border-box; }
    body { min-height: 100vh; margin: 0; display: grid; place-items: center; padding: 24px; color: #282720; font-family: "Courier New", monospace; background: #cfd5c5; background-image: linear-gradient(135deg, rgba(255,255,255,.25) 25%, transparent 25%), linear-gradient(315deg, rgba(255,255,255,.25) 25%, transparent 25%); background-size: 30px 30px; }
    .calculator { width: min(370px, 100%); padding: 22px; border: 2px solid #45463d; border-radius: 18px 18px 35px 35px; background: #e5dfce; box-shadow: 0 18px 0 #6d6f62, 0 32px 50px rgba(49,50,44,.28), inset 0 2px rgba(255,255,255,.7); }
    .brand { display: flex; justify-content: space-between; align-items: center; margin: 2px 4px 18px; font-size: 10px; font-weight: 800; letter-spacing: .15em; }
    .brand strong { font-size: 15px; letter-spacing: -.04em; }
    .solar { width: 90px; height: 22px; border: 2px solid #555348; border-radius: 3px; background: repeating-linear-gradient(90deg, #5c493b 0 20px, #2f2a25 21px 22px); }
    .display { min-height: 108px; padding: 16px; overflow: hidden; border: 3px inset #777969; border-radius: 8px; color: #24302b; text-align: right; background: #adbea9; box-shadow: inset 0 5px 12px rgba(42,54,48,.23); }
    .expression { height: 22px; color: #596860; font-size: 13px; }
    .value { margin-top: 8px; overflow: hidden; font-size: clamp(34px, 10vw, 48px); line-height: 1; letter-spacing: -.07em; white-space: nowrap; }
    .keys { display: grid; grid-template-columns: repeat(4, 1fr); gap: 11px; margin-top: 20px; }
    button { min-height: 56px; border: 1px solid #3c3b35; border-radius: 9px; color: #f5f1e7; font: 800 19px/1 "Courier New", monospace; background: #46463f; box-shadow: 0 5px 0 #24241f; cursor: pointer; transition: transform .08s ease, box-shadow .08s ease; }
    button:active, button.is-active { transform: translateY(4px); box-shadow: 0 1px 0 #24241f; }
    button:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
    .function { color: #282720; background: #bdb8aa; box-shadow: 0 5px 0 #77746b; }
    .operator { color: #fff8e9; background: #d06d3f; box-shadow: 0 5px 0 #8c3f20; }
    .equals { grid-row: span 2; background: #476e65; box-shadow: 0 5px 0 #29453f; }
    .zero { grid-column: span 2; }
    .note { margin: 18px 0 0; color: #747268; font-size: 10px; text-align: center; }
    @media (prefers-reduced-motion: reduce) { button { transition: none; } }
  </style>
</head>
<body>
  <main class="calculator">
    <div class="brand"><strong>NUMBER / 84</strong><span class="solar" aria-hidden="true"></span></div>
    <div class="display" aria-live="polite"><div id="expression" class="expression"></div><div id="value" class="value">0</div></div>
    <div class="keys">
      <button class="function" type="button" data-action="clear">AC</button><button class="function" type="button" data-action="sign">±</button><button class="function" type="button" data-action="percent">%</button><button class="operator" type="button" data-operator="/">÷</button>
      <button type="button" data-digit="7">7</button><button type="button" data-digit="8">8</button><button type="button" data-digit="9">9</button><button class="operator" type="button" data-operator="*">×</button>
      <button type="button" data-digit="4">4</button><button type="button" data-digit="5">5</button><button type="button" data-digit="6">6</button><button class="operator" type="button" data-operator="-">−</button>
      <button type="button" data-digit="1">1</button><button type="button" data-digit="2">2</button><button type="button" data-digit="3">3</button><button class="operator" type="button" data-operator="+">+</button>
      <button class="zero" type="button" data-digit="0">0</button><button type="button" data-action="decimal">.</button><button class="equals" type="button" data-action="equals">=</button>
    </div>
    <p class="note">Prend en charge les touches numériques, les opérations arithmétiques, Entrée et Échap</p>
  </main>
  <script>
    const valueDisplay = document.querySelector('#value');
    const expressionDisplay = document.querySelector('#expression');
    let current = '0';
    let stored = null;
    let operator = null;
    let replaceCurrent = false;

    const symbols = { '+': '+', '-': '−', '*': '×', '/': '÷' };
    function render() {
      valueDisplay.textContent = current;
      expressionDisplay.textContent = stored === null ? '' : `${stored} ${symbols[operator] || ''}`;
    }
    function inputDigit(digit) {
      if (replaceCurrent || current === '0' || current === 'Erreur') current = digit;
      else if (current.replace('-', '').replace('.', '').length < 10) current += digit;
      replaceCurrent = false;
      render();
    }
    function calculate(a, b, operation) {
      if (operation === '+') return a + b;
      if (operation === '-') return a - b;
      if (operation === '*') return a * b;
      if (operation === '/') return b === 0 ? null : a / b;
      return b;
    }
    function formatResult(number) {
      if (number === null || !Number.isFinite(number)) return 'Erreur';
      return String(Number(number.toPrecision(10)));
    }
    function chooseOperator(nextOperator) {
      if (operator && !replaceCurrent) {
        current = formatResult(calculate(Number(stored), Number(current), operator));
        stored = current === 'Erreur' ? null : Number(current);
      } else stored = Number(current);
      operator = nextOperator;
      replaceCurrent = true;
      render();
    }
    function equals() {
      if (!operator || stored === null) return;
      current = formatResult(calculate(Number(stored), Number(current), operator));
      stored = null; operator = null; replaceCurrent = true; render();
    }
    function runAction(action) {
      if (action === 'clear') { current = '0'; stored = null; operator = null; replaceCurrent = false; }
      if (action === 'sign' && current !== '0' && current !== 'Erreur') current = current.startsWith('-') ? current.slice(1) : `-${current}`;
      if (action === 'percent' && current !== 'Erreur') current = formatResult(Number(current) / 100);
      if (action === 'decimal' && !current.includes('.')) { current = replaceCurrent ? '0.' : `${current}.`; replaceCurrent = false; }
      if (action === 'equals') equals();
      render();
    }
    document.querySelector('.keys').addEventListener('click', event => {
      const button = event.target.closest('button');
      if (!button) return;
      if (button.dataset.digit) inputDigit(button.dataset.digit);
      else if (button.dataset.operator) chooseOperator(button.dataset.operator);
      else runAction(button.dataset.action);
    });
    document.addEventListener('keydown', event => {
      if (/^[0-9]$/.test(event.key)) inputDigit(event.key);
      else if ('+-*/'.includes(event.key)) chooseOperator(event.key);
      else if (event.key === '.' || event.key === ',') runAction('decimal');
      else if (event.key === 'Enter' || event.key === '=') runAction('equals');
      else if (event.key === 'Escape') runAction('clear');
    });
    render();
  </script>
</body>
</html>
Commentaires sur la pageVous avez découvert un problème ou avez une suggestion d’amélioration ?
Les fonctions de retour nécessitent l’utilisation de la version en ligne

Veuillez activer JavaScript dans la version en ligne avant de soumettre ; les fonctionnalités locales de l’outil ou du cas ne sont pas affectées.

Aller vers la version en ligne pour envoyer des commentaires