Kalkulator w przeglądarce z JavaScript

Pokażę jak to dzięki pomocy jednej funkcji JavaScript – eval() i podstawowej znajomości HTML, CSS i JavaScript można zbudować kalkulator w przeglądarce internetowej.

Od prostej wersji z obliczeniami w konsoli:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Calculator</title>
</head>

<body>
  <p>
    <button onclick="
      calculation +='1';
      console.log(calculation);
      ">
      1
    </button>
    <button onclick="
    calculation +='2';
    console.log(calculation);
    ">
      2
    </button>
    <button onclick="
    calculation +='3';
    console.log(calculation);
    ">
      3
    </button>
    <button onclick="
    calculation += ' + ';
    ">
      +
    </button>
  </p>
  <p>
    <button onclick="
      calculation +='4';
      console.log(calculation);
      ">
      4
    </button>
    <button onclick="
      calculation +='5';
      console.log(calculation);
      ">
      5
    </button>
    <button onclick="
      calculation +='6';
      console.log(calculation);
      ">
      6
    </button>
    <button onclick="
      calculation += ' - ';
      ">
      -
    </button>
  </p>
  <p>
    <button onclick="
      calculation +='7';
      console.log(calculation);
      ">
      7
    </button>
    <button onclick="
      calculation +='8';
      console.log(calculation);
      ">
      8
    </button>
    <button onclick="
      calculation +='9';
      console.log(calculation);
      ">
      9
    </button>
    <button onclick="
      calculation += ' * ';
      ">
      *
    </button>
  </p>
  <p>
    <button onclick="
    calculation +='0';
    console.log(calculation);
    ">
      0
    </button>
    <button onclick="
calculation += '.';
">
      .
    </button>

    <button onclick="
    calculation = eval(calculation);
    console.log(calculation);
    ">
      =
    </button>

    <button onclick="
      calculation += ' / ';
      ">
      /
    </button>
  </p>
  <p>
    <button onclick="
    calculation = '';
    console.log(0);
    ">
      Clear
    </button>
  </p>

  <script>
    let calculation = "";
  </script>
</body>

</html>

 

 

Z dodaniem domyślnych stylów i animacji z Bootstrap-a:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Calculator</title>
  <!-- Add Bootstrap CSS -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    .calc-button {
      width: 60px;
      height: 60px;
      margin: 5px;
    }

    .display {
      font-size: 2rem;
      margin-bottom: 20px;
      text-align: right;
      padding: 10px;
    }
  </style>
</head>

<body class="bg-light">

  <div class="container mt-5">
    <div class="row justify-content-center">
      <div class="col-md-4">
        <div class="card p-3 shadow">
          <div class="display bg-white border rounded" id="display">0</div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('1')">1</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('2')">2</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('3')">3</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' + ')">+</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('4')">4</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('5')">5</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('6')">6</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' - ')">-</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('7')">7</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('8')">8</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('9')">9</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' * ')">*</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('0')">0</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('.')">.</button>
            <button class="btn btn-success calc-button" onclick="calculate()">=</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' / ')">/</button>
          </div>

          <div class="d-flex justify-content-center">
            <button class="btn btn-danger calc-button" onclick="clearCalculation()">Clear</button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Add Bootstrap JS -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>

  <script>
    let calculation = '';

    function updateCalculation(value) {
      calculation += value;
      document.getElementById('display').innerText = calculation;
    }

    function calculate() {
      try {
        calculation = eval(calculation);
        document.getElementById('display').innerText = calculation;
      } catch (e) {
        document.getElementById('display').innerText = 'Error';
      }
    }

    function clearCalculation() {
      calculation = '';
      document.getElementById('display').innerText = '0';
    }
  </script>
</body>

</html>

 

Później dodaniem więcej animacji korzystając z biblioteki jQuery:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Calculator</title>

  <!-- Add Bootstrap CSS -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
  <!-- Add jQuery -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <!-- Add jQuery UI for animations -->
  <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

  <style>
    .calc-button {
      width: 70px;
      height: 70px;
      margin: 8px;
      font-size: 1.5rem;
    }

    .display {
      font-size: 2.5rem;
      margin-bottom: 20px;
      text-align: right;
      padding: 15px;
      background-color: #f8f9fa;
    }

    .container {
      margin-top: 50px;
    }

    .btn-primary,
    .btn-warning,
    .btn-danger,
    .btn-success {
      transition: transform 0.1s ease;
    }
  </style>
</head>

<body class="bg-light">

  <div class="container">
    <div class="row justify-content-center">
      <div class="col-md-4">
        <div class="card p-4 shadow-lg rounded">
          <div class="display border rounded" id="display">0</div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('1')">1</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('2')">2</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('3')">3</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' + ')">+</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('4')">4</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('5')">5</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('6')">6</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' - ')">-</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('7')">7</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('8')">8</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('9')">9</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' * ')">*</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('0')">0</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('.')">.</button>
            <button class="btn btn-success calc-button" onclick="calculate()">=</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' / ')">/</button>
          </div>

          <div class="d-flex justify-content-center">
            <button class="btn btn-danger calc-button" onclick="clearCalculation()">Clear</button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Add Bootstrap JS -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>

  <script>
    let calculation = '';

    function updateCalculation(value) {
      // Add animations for button press
      animateButton(value);

      calculation += value;
      $("#display").text(calculation);
    }

    function calculate() {
      try {
        calculation = eval(calculation);
        $("#display").text(calculation).effect("bounce", { times: 3 }, 500);
      } catch (e) {
        $("#display").text('Error').effect("shake", { times: 3 }, 500);
      }
    }

    function clearCalculation() {
      calculation = '';
      $("#display").text('0').fadeOut(100).fadeIn(100);
    }

    // Add animation for button clicks
    function animateButton(value) {
      $(".btn").each(function () {
        if ($(this).text() === value) {
          $(this).addClass("pressed");
          $(this).css("transform", "scale(0.95)");
          setTimeout(() => {
            $(this).css("transform", "scale(1)");
          }, 100);
        }
      });
    }

    // Animation for button press style
    $(".btn").on("mousedown", function () {
      $(this).css("transform", "scale(0.95)");
    });
    $(".btn").on("mouseup", function () {
      $(this).css("transform", "scale(1)");
    });
  </script>

</body>

</html>

 

Kończąc na kalkulatorze z motywem prosto z Matrix-a:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Matrix Calculator</title>

  <style>
    body,
    html {
      margin: 0;
      padding: 0;
      height: 100%;
      background-color: #000;
      color: #00ff00;
      font-family: 'Courier New', monospace;
      overflow: hidden;
    }

    #matrix-bg {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 1;
      pointer-events: none;
    }

    .matrix-column {
      position: absolute;
      top: -50px;
      font-size: 14px;
      line-height: 1.5;
    }

    .container {
      position: relative;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      z-index: 2;
    }

    .calculator {
      background-color: rgba(0, 20, 0, 0.8);
      border: 2px solid #00ff00;
      border-radius: 10px;
      padding: 20px;
      box-shadow: 0 0 20px #00ff00;
      transition: all 0.5s ease;
    }

    .calculator:hover {
      transform: scale(1.05);
      box-shadow: 0 0 30px #00ff00;
    }

    .display {
      width: 240px;
      height: 60px;
      margin-bottom: 20px;
      text-align: right;
      padding: 15px;
      background-color: #001400;
      color: #00ff00;
      border-radius: 5px;
      border: 1px solid #00ff00;
      text-shadow: 0 0 5px #00ff00;
      transition: all 0.5s ease;
      overflow-x: scroll;
      overflow-y: hidden;
      white-space: nowrap;
      font-size: 2.5rem;
      display: flexbox;
      align-items: center;
      justify-content: flex-end;
      cursor: text;
      user-select: text;
    }

    .display-content {
      transition: all 0.3s ease;
    }

    .display.animate .display-content {
      animation: pulse 0.5s;
    }

    @keyframes pulse {
      0% {
        transform: scale(1);
      }

      50% {
        transform: scale(1.1);
      }

      100% {
        transform: scale(1);
      }
    }

    .btn {
      width: 60px;
      height: 60px;
      margin: 5px;
      font-size: 1.2rem;
      background-color: #001400;
      color: #00ff00;
      border: 1px solid #00ff00;
      border-radius: 5px;
      transition: all 0.3s ease;
      position: relative;
      overflow: hidden;
    }

    .btn::before {
      content: '';
      position: absolute;
      top: 50%;
      left: 50%;
      width: 0;
      height: 0;
      background-color: rgba(0, 255, 0, 0.5);
      border-radius: 50%;
      transform: translate(-50%, -50%);
      transition: width 0.6s ease, height 0.6s ease;
    }

    .btn:hover {
      color: #000;
      box-shadow: 0 0 15px #00ff00;
    }

    .btn:hover::before {
      width: 200%;
      height: 200%;
    }

    .btn:active {
      transform: scale(0.95);
      box-shadow: 0 0 5px #00ff00;
    }

    .btn span {
      position: relative;
      z-index: 1;
    }

    @keyframes glowPulse {
      0% {
        box-shadow: 0 0 5px #00ff00;
      }

      50% {
        box-shadow: 0 0 20px #00ff00;
      }

      100% {
        box-shadow: 0 0 5px #00ff00;
      }
    }

    .btn:focus {
      outline: none;
      animation: glowPulse 1s infinite;
    }

    .display:focus {
      outline: none;
      box-shadow: 0 0 15px #00ff00;
    }
  </style>
</head>

<body>
  <div id="matrix-bg"></div>

  <div class="container">
    <div class="calculator">
      <div class="display" id="display">
        <div class="display-content">0</div>
      </div>
      <div>
        <button class="btn" data-value="7"><span>7</span></button>
        <button class="btn" data-value="8"><span>8</span></button>
        <button class="btn" data-value="9"><span>9</span></button>
        <button class="btn" data-value="+"><span>+</span></button>
      </div>
      <div>
        <button class="btn" data-value="4"><span>4</span></button>
        <button class="btn" data-value="5"><span>5</span></button>
        <button class="btn" data-value="6"><span>6</span></button>
        <button class="btn" data-value="-"><span>-</span></button>
      </div>
      <div>
        <button class="btn" data-value="1"><span>1</span></button>
        <button class="btn" data-value="2"><span>2</span></button>
        <button class="btn" data-value="3"><span>3</span></button>
        <button class="btn" data-value="*"><span>*</span></button>
      </div>
      <div>
        <button class="btn" data-value="0"><span>0</span></button>
        <button class="btn" data-value="."><span>.</span></button>
        <button class="btn" data-value="="><span>=</span></button>
        <button class="btn" data-value="/"><span>/</span></button>
      </div>
      <div>
        <button class="btn" data-value="clear"><span>Clear</span></button>
      </div>
    </div>
  </div>

  <script>
    const matrixBg = document.getElementById('matrix-bg');
    const display = document.getElementById('display');
    const displayContent = display.querySelector('.display-content');
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()_+-=[]{}|;:,.<>?';
    const rows = Math.floor((window.innerHeight + 50) / 20);
    let calculation = '';
    let isDisplayFocused = false;

    function createColumn() {
      const column = document.createElement('div');
      column.className = 'matrix-column';
      column.style.left = `${Math.random() * window.innerWidth}px`;
      let y = -50;
      let output = '';
      for (let j = 0; j < rows; j++) {
        output += characters[Math.floor(Math.random() * characters.length)] + '<br><br>';
      }
      column.innerHTML = output;
      matrixBg.appendChild(column);

      function updateColumn() {
        y += 5;
        if (y > window.innerHeight) {
          matrixBg.removeChild(column);
        } else {
          column.style.transform = `translateY(${y}px)`;
          requestAnimationFrame(updateColumn);
        }
      }
      requestAnimationFrame(updateColumn);
    }

    function startMatrixEffect() {
      createColumn();
      setTimeout(startMatrixEffect, Math.random() * 500);
    }

    for (let i = 0; i < 5; i++) {
      setTimeout(startMatrixEffect, i * 200);
    }

    function updateDisplay() {
      const scrollPosition = display.scrollLeft;
      displayContent.textContent = calculation || '0';
      display.classList.add('animate');
      setTimeout(() => display.classList.remove('animate'), 500);

      if (!isDisplayFocused) {
        display.scrollLeft = display.scrollWidth;
      } else {
        display.scrollLeft = scrollPosition;
      }
    }

    function handleButtonClick(e) {
      const btn = e.target.closest('.btn');
      if (!btn) return;

      btn.classList.add('active');
      setTimeout(() => btn.classList.remove('active'), 200);

      const value = btn.dataset.value;
      if (value === '=') {
        try {
          calculation = eval(calculation).toString();
        } catch (error) {
          calculation = 'Error';
        }
      } else if (value === 'clear') {
        calculation = '';
      } else {
        calculation += value;
      }
      updateDisplay();
    }

    document.querySelector('.calculator').addEventListener('click', handleButtonClick);

    // Make the display focusable
    display.tabIndex = 0;

    // Track focus state
    display.addEventListener('focus', () => {
      isDisplayFocused = true;
    });

    display.addEventListener('blur', () => {
      isDisplayFocused = false;
    });

    // Prevent default calculator behavior when interacting with the display
    display.addEventListener('mousedown', (e) => {
      e.stopPropagation();
    });

    display.addEventListener('touchstart', (e) => {
      e.stopPropagation();
    });

    // Prevent keyboard input on the display
    display.addEventListener('keydown', (e) => {
      e.preventDefault();
    });

    let lastTime = 0;
    function animate(currentTime) {
      if (currentTime - lastTime > 500) {
        createColumn();
        lastTime = currentTime;
      }
      requestAnimationFrame(animate);
    }
    requestAnimationFrame(animate);
  </script>
</body>

</html>

 

Tutaj link do repozytorium z wszystkimi wersjami aplikacji: kalkulator-github

 

Oraz proste demo z działania:

 

Przeglądarka internetowa Mozilla Firefox i ciekawe dodatki

Wszyscy korzystamy z jakiegoś typu przeglądarki internetowej:
-Internet Explorer (Edge od Microsoftu)
Opera
-Google Chrome(Chromium)
-Mozilla Firefox

Lub innej mniej popularnej.
Otóż korzystamy i często nie zdajemy sobie sprawy, że mamy możliwość włączenia jakiejś wtyczki napisanej przez programistów dla przeglądarki lub też zmiany nużącego nas domyślnego systemowego motywu.

Opiszę tutaj dodatki do przeglądarki Mozilla Firefox, ale z pewnością do innych przeglądarek na pewno znajdziemy coś w tym samym stylu tylko jako zamiennik z jakąś inną nazwą.

Bardzo fajny może okazać się motyw animowany matrix-a (oczywiście wiąże się to z drobnym dodatkowym obciążeniem procesora, ale na pewno niewielkim).
Są to przewijające się na czarnym tle ciągi znaków.

Jest to ciekawy dodatek, ale z pewnością większość zaciekawią następujące rozszerzenia:

Dark Reader (Tryb ciemny dla wszystkich stron internetowych. Nasze oczy nie męczą się tak przy pracy w ciemności.)

Ghostery ( Bloker reklam chroniący prywatność – już dość wielokrotnych męczących Nas reklam na stronach i utrudniających przeglądanie internetu.
Dodatkowo można zastosować pomijanie polityki prywatności i ciasteczek, które wielokrotnie informują Nas o swojej obecności na każdym serwisie)

Simple Translate lub Google Translate ( Tu chyba nie trzeba wiele wyjaśniać. Są to translatory tekstu od Google w formie szybko dostępnej. Czyli zamiast za każdym razem otwierać nową zakładkę i kopiować tekst do translatora możemy skorzystać z opcji tłumaczenia całej strony lub też zaznaczonego tekstu)

Aby to oczywiście wszystko ustawić wchodzimy do menu aplikacji (te trzy poziome kreski w prawym górnym rogu przeglądarki) i klikamy “Dodatki i motywy“( lub też skrót klawiszowy Ctrl+Shift+A)