Spaces:
Running
Running
| <html lang="es"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Calculadora Científica Avanzada</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .unit-converter { | |
| transition: all 0.3s ease; | |
| } | |
| .unit-converter:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); | |
| } | |
| .dark-mode { | |
| background-color: #1a202c; | |
| color: #f7fafc; | |
| } | |
| .dark-mode .bg-gray-100 { | |
| background-color: #2d3748; | |
| } | |
| .dark-mode .bg-white { | |
| background-color: #2d3748; | |
| color: #f7fafc; | |
| } | |
| .dark-mode .text-gray-800 { | |
| color: #f7fafc; | |
| } | |
| .dark-mode .border-gray-300 { | |
| border-color: #4a5568; | |
| } | |
| .history-item { | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| } | |
| .history-item:hover { | |
| background-color: rgba(66, 153, 225, 0.1); | |
| } | |
| .rotate-45 { | |
| transform: rotate(45deg); | |
| } | |
| .rotate-90 { | |
| transform: rotate(90deg); | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100 min-h-screen"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- Header --> | |
| <header class="flex justify-between items-center mb-8"> | |
| <div> | |
| <h1 class="text-3xl font-bold text-blue-600">SciCalc Pro</h1> | |
| <p class="text-gray-600">Calculadora de unidades científicas</p> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <button id="darkModeToggle" class="p-2 rounded-full bg-gray-200 hover:bg-gray-300"> | |
| <i class="fas fa-moon text-gray-700"></i> | |
| </button> | |
| <button id="helpBtn" class="p-2 rounded-full bg-blue-100 hover:bg-blue-200 text-blue-600"> | |
| <i class="fas fa-question"></i> | |
| </button> | |
| </div> | |
| </header> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> | |
| <!-- Main Calculator --> | |
| <div class="lg:col-span-2"> | |
| <div class="bg-white rounded-xl shadow-md overflow-hidden"> | |
| <!-- Display --> | |
| <div class="p-4 bg-gray-50 border-b"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <div class="text-sm text-gray-500" id="currentOperation"></div> | |
| <div class="flex space-x-2"> | |
| <button id="clearBtn" class="px-2 py-1 text-xs bg-red-100 text-red-600 rounded hover:bg-red-200">AC</button> | |
| <button id="backspaceBtn" class="px-2 py-1 text-xs bg-gray-100 text-gray-600 rounded hover:bg-gray-200"> | |
| <i class="fas fa-backspace"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <input type="text" id="display" class="w-full text-right text-3xl font-semibold bg-transparent outline-none" value="0" readonly> | |
| </div> | |
| <!-- Keypad --> | |
| <div class="grid grid-cols-5 gap-2 p-4"> | |
| <!-- Scientific functions --> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="sin">sin</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="cos">cos</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="tan">tan</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="log">log</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="ln">ln</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="√">√</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="^">^</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="π">π</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="e">e</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="!">x!</button> | |
| <!-- Numbers and basic operations --> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value="7">7</button> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value="8">8</button> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value="9">9</button> | |
| <button class="btn-op bg-yellow-100 text-yellow-600 hover:bg-yellow-200" data-value="/">/</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="(">(</button> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value="4">4</button> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value="5">5</button> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value="6">6</button> | |
| <button class="btn-op bg-yellow-100 text-yellow-600 hover:bg-yellow-200" data-value="*">×</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value=")">)</button> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value="1">1</button> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value="2">2</button> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value="3">3</button> | |
| <button class="btn-op bg-yellow-100 text-yellow-600 hover:bg-yellow-200" data-value="-">-</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="%">%</button> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value="0">0</button> | |
| <button class="btn-num bg-gray-100 hover:bg-gray-200" data-value=".">.</button> | |
| <button class="btn-equals bg-green-100 text-green-600 hover:bg-green-200" data-value="=">=</button> | |
| <button class="btn-op bg-yellow-100 text-yellow-600 hover:bg-yellow-200" data-value="+">+</button> | |
| <button class="btn-func bg-blue-100 text-blue-600 hover:bg-blue-200" data-value="±">±</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Unit Converter --> | |
| <div class="space-y-6"> | |
| <!-- Unit Converter Tabs --> | |
| <div class="bg-white rounded-xl shadow-md overflow-hidden"> | |
| <div class="flex border-b"> | |
| <button class="unit-tab active px-4 py-2 font-medium text-blue-600 border-b-2 border-blue-500" data-category="length">Longitud</button> | |
| <button class="unit-tab px-4 py-2 font-medium text-gray-600 hover:text-blue-600" data-category="weight">Peso</button> | |
| <button class="unit-tab px-4 py-2 font-medium text-gray-600 hover:text-blue-600" data-category="temperature">Temperatura</button> | |
| </div> | |
| <div id="unitConverters" class="p-4"> | |
| <!-- Length Converter --> | |
| <div class="unit-converter active bg-gray-50 p-4 rounded-lg" data-category="length"> | |
| <div class="flex items-center mb-4"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="lengthValue" value="1"> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="lengthFrom"> | |
| <option value="mm">Milímetros (mm)</option> | |
| <option value="cm">Centímetros (cm)</option> | |
| <option value="m" selected>Metros (m)</option> | |
| <option value="km">Kilómetros (km)</option> | |
| <option value="in">Pulgadas (in)</option> | |
| <option value="ft">Pies (ft)</option> | |
| <option value="yd">Yardas (yd)</option> | |
| <option value="mi">Millas (mi)</option> | |
| </select> | |
| </div> | |
| <div class="flex justify-center mb-4"> | |
| <button id="lengthSwap" class="p-2 bg-gray-200 rounded-full hover:bg-gray-300"> | |
| <i class="fas fa-exchange-alt"></i> | |
| </button> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="lengthResult" readonly> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="lengthTo"> | |
| <option value="mm">Milímetros (mm)</option> | |
| <option value="cm" selected>Centímetros (cm)</option> | |
| <option value="m">Metros (m)</option> | |
| <option value="km">Kilómetros (km)</option> | |
| <option value="in">Pulgadas (in)</option> | |
| <option value="ft">Pies (ft)</option> | |
| <option value="yd">Yardas (yd)</option> | |
| <option value="mi">Millas (mi)</option> | |
| </select> | |
| </div> | |
| </div> | |
| <!-- Weight Converter --> | |
| <div class="unit-converter hidden bg-gray-50 p-4 rounded-lg" data-category="weight"> | |
| <div class="flex items-center mb-4"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="weightValue" value="1"> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="weightFrom"> | |
| <option value="mg">Miligramos (mg)</option> | |
| <option value="g">Gramos (g)</option> | |
| <option value="kg" selected>Kilogramos (kg)</option> | |
| <option value="t">Toneladas (t)</option> | |
| <option value="oz">Onzas (oz)</option> | |
| <option value="lb">Libras (lb)</option> | |
| </select> | |
| </div> | |
| <div class="flex justify-center mb-4"> | |
| <button id="weightSwap" class="p-2 bg-gray-200 rounded-full hover:bg-gray-300"> | |
| <i class="fas fa-exchange-alt"></i> | |
| </button> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="weightResult" readonly> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="weightTo"> | |
| <option value="mg">Miligramos (mg)</option> | |
| <option value="g" selected>Gramos (g)</option> | |
| <option value="kg">Kilogramos (kg)</option> | |
| <option value="t">Toneladas (t)</option> | |
| <option value="oz">Onzas (oz)</option> | |
| <option value="lb">Libras (lb)</option> | |
| </select> | |
| </div> | |
| </div> | |
| <!-- Temperature Converter --> | |
| <div class="unit-converter hidden bg-gray-50 p-4 rounded-lg" data-category="temperature"> | |
| <div class="flex items-center mb-4"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="tempValue" value="0"> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="tempFrom"> | |
| <option value="c" selected>Celsius (°C)</option> | |
| <option value="f">Fahrenheit (°F)</option> | |
| <option value="k">Kelvin (K)</option> | |
| </select> | |
| </div> | |
| <div class="flex justify-center mb-4"> | |
| <button id="tempSwap" class="p-2 bg-gray-200 rounded-full hover:bg-gray-300"> | |
| <i class="fas fa-exchange-alt"></i> | |
| </button> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="tempResult" readonly> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="tempTo"> | |
| <option value="c">Celsius (°C)</option> | |
| <option value="f" selected>Fahrenheit (°F)</option> | |
| <option value="k">Kelvin (K)</option> | |
| </select> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- More Unit Converters (collapsible) --> | |
| <div class="bg-white rounded-xl shadow-md overflow-hidden"> | |
| <button id="moreUnitsBtn" class="w-full flex justify-between items-center p-4 font-medium text-left"> | |
| <span>Más conversores</span> | |
| <i class="fas fa-chevron-down transition-transform duration-300"></i> | |
| </button> | |
| <div id="moreUnitsContent" class="hidden px-4 pb-4 space-y-4"> | |
| <!-- Area Converter --> | |
| <div class="unit-converter bg-gray-50 p-4 rounded-lg" data-category="area"> | |
| <h3 class="font-medium mb-2">Área</h3> | |
| <div class="flex items-center mb-2"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="areaValue" value="1"> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="areaFrom"> | |
| <option value="mm2">mm²</option> | |
| <option value="cm2">cm²</option> | |
| <option value="m2" selected>m²</option> | |
| <option value="ha">Hectáreas</option> | |
| <option value="km2">km²</option> | |
| <option value="in2">in²</option> | |
| <option value="ft2">ft²</option> | |
| <option value="ac">Acres</option> | |
| </select> | |
| </div> | |
| <div class="flex justify-center mb-2"> | |
| <button id="areaSwap" class="p-2 bg-gray-200 rounded-full hover:bg-gray-300"> | |
| <i class="fas fa-exchange-alt"></i> | |
| </button> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="areaResult" readonly> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="areaTo"> | |
| <option value="cm2" selected>cm²</option> | |
| <option value="m2">m²</option> | |
| <option value="ha">Hectáreas</option> | |
| <option value="km2">km²</option> | |
| <option value="in2">in²</option> | |
| <option value="ft2">ft²</option> | |
| <option value="ac">Acres</option> | |
| </select> | |
| </div> | |
| </div> | |
| <!-- Volume Converter --> | |
| <div class="unit-converter bg-gray-50 p-4 rounded-lg" data-category="volume"> | |
| <h3 class="font-medium mb-2">Volumen</h3> | |
| <div class="flex items-center mb-2"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="volumeValue" value="1"> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="volumeFrom"> | |
| <option value="ml">Mililitros (ml)</option> | |
| <option value="l" selected>Litros (l)</option> | |
| <option value="m3">m³</option> | |
| <option value="gal">Galones (gal)</option> | |
| <option value="pt">Pintas (pt)</option> | |
| <option value="qt">Cuartos (qt)</option> | |
| <option value="fl-oz">Onzas líquidas (fl oz)</option> | |
| </select> | |
| </div> | |
| <div class="flex justify-center mb-2"> | |
| <button id="volumeSwap" class="p-2 bg-gray-200 rounded-full hover:bg-gray-300"> | |
| <i class="fas fa-exchange-alt"></i> | |
| </button> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="volumeResult" readonly> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="volumeTo"> | |
| <option value="ml">Mililitros (ml)</option> | |
| <option value="l">Litros (l)</option> | |
| <option value="m3" selected>m³</option> | |
| <option value="gal">Galones (gal)</option> | |
| <option value="pt">Pintas (pt)</option> | |
| <option value="qt">Cuartos (qt)</option> | |
| <option value="fl-oz">Onzas líquidas (fl oz)</option> | |
| </select> | |
| </div> | |
| </div> | |
| <!-- Time Converter --> | |
| <div class="unit-converter bg-gray-50 p-4 rounded-lg" data-category="time"> | |
| <h3 class="font-medium mb-2">Tiempo</h3> | |
| <div class="flex items-center mb-2"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="timeValue" value="1"> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="timeFrom"> | |
| <option value="ms">Milisegundos (ms)</option> | |
| <option value="s">Segundos (s)</option> | |
| <option value="min" selected>Minutos (min)</option> | |
| <option value="h">Horas (h)</option> | |
| <option value="d">Días (d)</option> | |
| <option value="wk">Semanas</option> | |
| <option value="mo">Meses</option> | |
| <option value="y">Años</option> | |
| </select> | |
| </div> | |
| <div class="flex justify-center mb-2"> | |
| <button id="timeSwap" class="p-2 bg-gray-200 rounded-full hover:bg-gray-300"> | |
| <i class="fas fa-exchange-alt"></i> | |
| </button> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="timeResult" readonly> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="timeTo"> | |
| <option value="s" selected>Segundos (s)</option> | |
| <option value="min">Minutos (min)</option> | |
| <option value="h">Horas (h)</option> | |
| <option value="d">Días (d)</option> | |
| <option value="wk">Semanas</option> | |
| <option value="mo">Meses</option> | |
| <option value="y">Años</option> | |
| </select> | |
| </div> | |
| </div> | |
| <!-- Speed Converter --> | |
| <div class="unit-converter bg-gray-50 p-4 rounded-lg" data-category="speed"> | |
| <h3 class="font-medium mb-2">Velocidad</h3> | |
| <div class="flex items-center mb-2"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="speedValue" value="1"> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="speedFrom"> | |
| <option value="m/s" selected>m/s</option> | |
| <option value="km/h">km/h</option> | |
| <option value="mph">mph</option> | |
| <option value="knot">nudos</option> | |
| <option value="ft/s">ft/s</option> | |
| </select> | |
| </div> | |
| <div class="flex justify-center mb-2"> | |
| <button id="speedSwap" class="p-2 bg-gray-200 rounded-full hover:bg-gray-300"> | |
| <i class="fas fa-exchange-alt"></i> | |
| </button> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="number" class="w-full p-2 border rounded-l" id="speedResult" readonly> | |
| <select class="p-2 border-t border-b border-r rounded-r bg-white" id="speedTo"> | |
| <option value="km/h" selected>km/h</option> | |
| <option value="m/s">m/s</option> | |
| <option value="mph">mph</option> | |
| <option value="knot">nudos</option> | |
| <option value="ft/s">ft/s</option> | |
| </select> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Calculation History --> | |
| <div class="bg-white rounded-xl shadow-md overflow-hidden"> | |
| <div class="p-4 border-b flex justify-between items-center"> | |
| <h3 class="font-medium">Historial</h3> | |
| <button id="clearHistory" class="text-sm text-red-500 hover:text-red-700">Limpiar</button> | |
| </div> | |
| <div id="historyList" class="p-4 max-h-60 overflow-y-auto"> | |
| <!-- History items will be added here --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Help Modal --> | |
| <div id="helpModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50"> | |
| <div class="bg-white rounded-xl p-6 max-w-2xl w-full max-h-[90vh] overflow-y-auto"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-xl font-bold">Ayuda de SciCalc Pro</h3> | |
| <button id="closeHelpModal" class="p-2 rounded-full hover:bg-gray-100"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="space-y-4"> | |
| <div> | |
| <h4 class="font-bold text-lg mb-2">Calculadora Científica</h4> | |
| <p>La calculadora incluye funciones científicas avanzadas:</p> | |
| <ul class="list-disc pl-5 mt-2 space-y-1"> | |
| <li><strong>Trigonométricas:</strong> sin, cos, tan (en radianes)</li> | |
| <li><strong>Logaritmos:</strong> log (base 10), ln (base e)</li> | |
| <li><strong>Raíz cuadrada:</strong> √</li> | |
| <li><strong>Exponenciación:</strong> ^</li> | |
| <li><strong>Constantes:</strong> π (pi), e</li> | |
| <li><strong>Factorial:</strong> x!</li> | |
| <li><strong>Porcentaje:</strong> %</li> | |
| <li><strong>Cambio de signo:</strong> ±</li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h4 class="font-bold text-lg mb-2">Conversor de Unidades</h4> | |
| <p>Conversión entre múltiples sistemas de unidades:</p> | |
| <ul class="list-disc pl-5 mt-2 space-y-1"> | |
| <li><strong>Longitud:</strong> mm, cm, m, km, pulgadas, pies, yardas, millas</li> | |
| <li><strong>Peso/Masa:</strong> mg, g, kg, toneladas, onzas, libras</li> | |
| <li><strong>Temperatura:</strong> Celsius, Fahrenheit, Kelvin</li> | |
| <li><strong>Área:</strong> mm², cm², m², hectáreas, km², in², ft², acres</li> | |
| <li><strong>Volumen:</strong> ml, l, m³, galones, pintas, cuartos, onzas líquidas</li> | |
| <li><strong>Tiempo:</strong> ms, segundos, minutos, horas, días, semanas, meses, años</li> | |
| <li><strong>Velocidad:</strong> m/s, km/h, mph, nudos, ft/s</li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h4 class="font-bold text-lg mb-2">Funcionalidades Adicionales</h4> | |
| <ul class="list-disc pl-5 mt-2 space-y-1"> | |
| <li><strong>Modo oscuro:</strong> Activable desde el botón superior derecho</li> | |
| <li><strong>Historial:</strong> Guarda tus últimos cálculos</li> | |
| <li><strong>Intercambio rápido:</strong> Botón para invertir las unidades de conversión</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Calculator functionality | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Calculator state | |
| let currentInput = '0'; | |
| let previousInput = ''; | |
| let operation = null; | |
| let resetInput = false; | |
| const history = []; | |
| // DOM elements | |
| const display = document.getElementById('display'); | |
| const currentOperation = document.getElementById('currentOperation'); | |
| const historyList = document.getElementById('historyList'); | |
| // Update display | |
| function updateDisplay() { | |
| display.value = currentInput; | |
| } | |
| // Number buttons | |
| document.querySelectorAll('.btn-num').forEach(button => { | |
| button.addEventListener('click', () => { | |
| if (currentInput === '0' || resetInput) { | |
| currentInput = button.dataset.value; | |
| resetInput = false; | |
| } else { | |
| currentInput += button.dataset.value; | |
| } | |
| updateDisplay(); | |
| }); | |
| }); | |
| // Operation buttons | |
| document.querySelectorAll('.btn-op').forEach(button => { | |
| button.addEventListener('click', () => { | |
| if (operation !== null) calculate(); | |
| previousInput = currentInput; | |
| operation = button.dataset.value; | |
| currentOperation.textContent = `${previousInput} ${operation}`; | |
| resetInput = true; | |
| }); | |
| }); | |
| // Function buttons | |
| document.querySelectorAll('.btn-func').forEach(button => { | |
| button.addEventListener('click', () => { | |
| const func = button.dataset.value; | |
| switch(func) { | |
| case '±': | |
| currentInput = (parseFloat(currentInput) * -1).toString(); | |
| break; | |
| case '%': | |
| currentInput = (parseFloat(currentInput) / 100).toString(); | |
| break; | |
| case '√': | |
| currentInput = Math.sqrt(parseFloat(currentInput)).toString(); | |
| break; | |
| case '^': | |
| previousInput = currentInput; | |
| operation = '^'; | |
| currentOperation.textContent = `${previousInput} ^`; | |
| resetInput = true; | |
| return; | |
| case 'sin': | |
| currentInput = Math.sin(parseFloat(currentInput)).toString(); | |
| break; | |
| case 'cos': | |
| currentInput = Math.cos(parseFloat(currentInput)).toString(); | |
| break; | |
| case 'tan': | |
| currentInput = Math.tan(parseFloat(currentInput)).toString(); | |
| break; | |
| case 'log': | |
| currentInput = Math.log10(parseFloat(currentInput)).toString(); | |
| break; | |
| case 'ln': | |
| currentInput = Math.log(parseFloat(currentInput)).toString(); | |
| break; | |
| case 'π': | |
| if (currentInput === '0' || resetInput) { | |
| currentInput = Math.PI.toString(); | |
| resetInput = false; | |
| } else { | |
| currentInput += Math.PI.toString(); | |
| } | |
| break; | |
| case 'e': | |
| if (currentInput === '0' || resetInput) { | |
| currentInput = Math.E.toString(); | |
| resetInput = false; | |
| } else { | |
| currentInput += Math.E.toString(); | |
| } | |
| break; | |
| case '!': | |
| currentInput = factorial(parseInt(currentInput)).toString(); | |
| break; | |
| case '(': | |
| if (currentInput === '0' || resetInput) { | |
| currentInput = '('; | |
| resetInput = false; | |
| } else { | |
| currentInput += '('; | |
| } | |
| break; | |
| case ')': | |
| currentInput += ')'; | |
| break; | |
| } | |
| updateDisplay(); | |
| }); | |
| }); | |
| // Factorial function | |
| function factorial(n) { | |
| if (n < 0) return NaN; | |
| if (n === 0 || n === 1) return 1; | |
| let result = 1; | |
| for (let i = 2; i <= n; i++) { | |
| result *= i; | |
| } | |
| return result; | |
| } | |
| // Equals button | |
| document.querySelector('.btn-equals').addEventListener('click', () => { | |
| calculate(); | |
| currentOperation.textContent = ''; | |
| }); | |
| // Calculate function | |
| function calculate() { | |
| if (operation === null || resetInput) return; | |
| let result; | |
| const prev = parseFloat(previousInput); | |
| const current = parseFloat(currentInput); | |
| switch(operation) { | |
| case '+': | |
| result = prev + current; | |
| break; | |
| case '-': | |
| result = prev - current; | |
| break; | |
| case '*': | |
| result = prev * current; | |
| break; | |
| case '/': | |
| result = prev / current; | |
| break; | |
| case '^': | |
| result = Math.pow(prev, current); | |
| break; | |
| } | |
| // Add to history | |
| const historyEntry = `${previousInput} ${operation} ${currentInput} = ${result}`; | |
| history.unshift(historyEntry); | |
| updateHistory(); | |
| currentInput = result.toString(); | |
| operation = null; | |
| resetInput = true; | |
| updateDisplay(); | |
| } | |
| // Clear button | |
| document.getElementById('clearBtn').addEventListener('click', () => { | |
| currentInput = '0'; | |
| previousInput = ''; | |
| operation = null; | |
| currentOperation.textContent = ''; | |
| updateDisplay(); | |
| }); | |
| // Backspace button | |
| document.getElementById('backspaceBtn').addEventListener('click', () => { | |
| if (currentInput.length === 1) { | |
| currentInput = '0'; | |
| } else { | |
| currentInput = currentInput.slice(0, -1); | |
| } | |
| updateDisplay(); | |
| }); | |
| // Update history display | |
| function updateHistory() { | |
| historyList.innerHTML = ''; | |
| history.slice(0, 10).forEach(item => { | |
| const div = document.createElement('div'); | |
| div.className = 'history-item py-2 px-3 rounded hover:bg-blue-50'; | |
| div.textContent = item; | |
| div.addEventListener('click', () => { | |
| // When history item is clicked, use the result as current input | |
| const parts = item.split(' = '); | |
| currentInput = parts[1]; | |
| updateDisplay(); | |
| }); | |
| historyList.appendChild(div); | |
| }); | |
| } | |
| // Clear history | |
| document.getElementById('clearHistory').addEventListener('click', () => { | |
| history.length = 0; | |
| updateHistory(); | |
| }); | |
| // Unit converter tabs | |
| document.querySelectorAll('.unit-tab').forEach(tab => { | |
| tab.addEventListener('click', () => { | |
| // Remove active class from all tabs | |
| document.querySelectorAll('.unit-tab').forEach(t => { | |
| t.classList.remove('active', 'text-blue-600', 'border-blue-500'); | |
| t.classList.add('text-gray-600'); | |
| }); | |
| // Add active class to clicked tab | |
| tab.classList.add('active', 'text-blue-600', 'border-blue-500'); | |
| tab.classList.remove('text-gray-600'); | |
| // Hide all converters | |
| document.querySelectorAll('.unit-converter').forEach(converter => { | |
| converter.classList.add('hidden'); | |
| converter.classList.remove('active'); | |
| }); | |
| // Show selected converter | |
| const category = tab.dataset.category; | |
| document.querySelector(`.unit-converter[data-category="${category}"]`).classList.remove('hidden'); | |
| document.querySelector(`.unit-converter[data-category="${category}"]`).classList.add('active'); | |
| }); | |
| }); | |
| // More units toggle | |
| document.getElementById('moreUnitsBtn').addEventListener('click', () => { | |
| const content = document.getElementById('moreUnitsContent'); | |
| const icon = document.querySelector('#moreUnitsBtn i'); | |
| content.classList.toggle('hidden'); | |
| icon.classList.toggle('rotate-180'); | |
| }); | |
| // Unit conversion functions | |
| function convertLength() { | |
| const from = document.getElementById('lengthFrom').value; | |
| const to = document.getElementById('lengthTo').value; | |
| const value = parseFloat(document.getElementById('lengthValue').value); | |
| // Convert to meters first | |
| let meters; | |
| switch(from) { | |
| case 'mm': meters = value / 1000; break; | |
| case 'cm': meters = value / 100; break; | |
| case 'm': meters = value; break; | |
| case 'km': meters = value * 1000; break; | |
| case 'in': meters = value * 0.0254; break; | |
| case 'ft': meters = value * 0.3048; break; | |
| case 'yd': meters = value * 0.9144; break; | |
| case 'mi': meters = value * 1609.344; break; | |
| } | |
| // Convert from meters to target unit | |
| let result; | |
| switch(to) { | |
| case 'mm': result = meters * 1000; break; | |
| case 'cm': result = meters * 100; break; | |
| case 'm': result = meters; break; | |
| case 'km': result = meters / 1000; break; | |
| case 'in': result = meters / 0.0254; break; | |
| case 'ft': result = meters / 0.3048; break; | |
| case 'yd': result = meters / 0.9144; break; | |
| case 'mi': result = meters / 1609.344; break; | |
| } | |
| document.getElementById('lengthResult').value = result.toFixed(8).replace(/\.?0+$/, ''); | |
| } | |
| function convertWeight() { | |
| const from = document.getElementById('weightFrom').value; | |
| const to = document.getElementById('weightTo').value; | |
| const value = parseFloat(document.getElementById('weightValue').value); | |
| // Convert to kilograms first | |
| let kg; | |
| switch(from) { | |
| case 'mg': kg = value / 1000000; break; | |
| case 'g': kg = value / 1000; break; | |
| case 'kg': kg = value; break; | |
| case 't': kg = value * 1000; break; | |
| case 'oz': kg = value * 0.0283495; break; | |
| case 'lb': kg = value * 0.453592; break; | |
| } | |
| // Convert from kg to target unit | |
| let result; | |
| switch(to) { | |
| case 'mg': result = kg * 1000000; break; | |
| case 'g': result = kg * 1000; break; | |
| case 'kg': result = kg; break; | |
| case 't': result = kg / 1000; break; | |
| case 'oz': result = kg / 0.0283495; break; | |
| case 'lb': result = kg / 0.453592; break; | |
| } | |
| document.getElementById('weightResult').value = result.toFixed(8).replace(/\.?0+$/, ''); | |
| } | |
| function convertTemperature() { | |
| const from = document.getElementById('tempFrom').value; | |
| const to = document.getElementById('tempTo').value; | |
| const value = parseFloat(document.getElementById('tempValue').value); | |
| // Convert to Celsius first | |
| let celsius; | |
| switch(from) { | |
| case 'c': celsius = value; break; | |
| case 'f': celsius = (value - 32) * 5/9; break; | |
| case 'k': celsius = value - 273.15; break; | |
| } | |
| // Convert from Celsius to target unit | |
| let result; | |
| switch(to) { | |
| case 'c': result = celsius; break; | |
| case 'f': result = (celsius * 9/5) + 32; break; | |
| case 'k': result = celsius + 273.15; break; | |
| } | |
| document.getElementById('tempResult').value = result.toFixed(4).replace(/\.?0+$/, ''); | |
| } | |
| function convertArea() { | |
| const from = document.getElementById('areaFrom').value; | |
| const to = document.getElementById('areaTo').value; | |
| const value = parseFloat(document.getElementById('areaValue').value); | |
| // Convert to square meters first | |
| let sqm; | |
| switch(from) { | |
| case 'mm2': sqm = value / 1000000; break; | |
| case 'cm2': sqm = value / 10000; break; | |
| case 'm2': sqm = value; break; | |
| case 'ha': sqm = value * 10000; break; | |
| case 'km2': sqm = value * 1000000; break; | |
| case 'in2': sqm = value * 0.00064516; break; | |
| case 'ft2': sqm = value * 0.092903; break; | |
| case 'ac': sqm = value * 4046.86; break; | |
| } | |
| // Convert from sqm to target unit | |
| let result; | |
| switch(to) { | |
| case 'mm2': result = sqm * 1000000; break; | |
| case 'cm2': result = sqm * 10000; break; | |
| case 'm2': result = sqm; break; | |
| case 'ha': result = sqm / 10000; break; | |
| case 'km2': result = sqm / 1000000; break; | |
| case 'in2': result = sqm / 0.00064516; break; | |
| case 'ft2': result = sqm / 0.092903; break; | |
| case 'ac': result = sqm / 4046.86; break; | |
| } | |
| document.getElementById('areaResult').value = result.toFixed(8).replace(/\.?0+$/, ''); | |
| } | |
| function convertVolume() { | |
| const from = document.getElementById('volumeFrom').value; | |
| const to = document.getElementById('volumeTo').value; | |
| const value = parseFloat(document.getElementById('volumeValue').value); | |
| // Convert to liters first | |
| let liters; | |
| switch(from) { | |
| case 'ml': liters = value / 1000; break; | |
| case 'l': liters = value; break; | |
| case 'm3': liters = value * 1000; break; | |
| case 'gal': liters = value * 3.78541; break; | |
| case 'pt': liters = value * 0.473176; break; | |
| case 'qt': liters = value * 0.946353; break; | |
| case 'fl-oz': liters = value * 0.0295735; break; | |
| } | |
| // Convert from liters to target unit | |
| let result; | |
| switch(to) { | |
| case 'ml': result = liters * 1000; break; | |
| case 'l': result = liters; break; | |
| case 'm3': result = liters / 1000; break; | |
| case 'gal': result = liters / 3.78541; break; | |
| case 'pt': result = liters / 0.473176; break; | |
| case 'qt': result = liters / 0.946353; break; | |
| case 'fl-oz': result = liters / 0.0295735; break; | |
| } | |
| document.getElementById('volumeResult').value = result.toFixed(8).replace(/\.?0+$/, ''); | |
| } | |
| function convertTime() { | |
| const from = document.getElementById('timeFrom').value; | |
| const to = document.getElementById('timeTo').value; | |
| const value = parseFloat(document.getElementById('timeValue').value); | |
| // Convert to seconds first | |
| let seconds; | |
| switch(from) { | |
| case 'ms': seconds = value / 1000; break; | |
| case 's': seconds = value; break; | |
| case 'min': seconds = value * 60; break; | |
| case 'h': seconds = value * 3600; break; | |
| case 'd': seconds = value * 86400; break; | |
| case 'wk': seconds = value * 604800; break; | |
| case 'mo': seconds = value * 2629746; break; // Approximate | |
| case 'y': seconds = value * 31556952; break; // Approximate | |
| } | |
| // Convert from seconds to target unit | |
| let result; | |
| switch(to) { | |
| case 'ms': result = seconds * 1000; break; | |
| case 's': result = seconds; break; | |
| case 'min': result = seconds / 60; break; | |
| case 'h': result = seconds / 3600; break; | |
| case 'd': result = seconds / 86400; break; | |
| case 'wk': result = seconds / 604800; break; | |
| case 'mo': result = seconds / 2629746; break; | |
| case 'y': result = seconds / 31556952; break; | |
| } | |
| document.getElementById('timeResult').value = result.toFixed(8).replace(/\.?0+$/, ''); | |
| } | |
| function convertSpeed() { | |
| const from = document.getElementById('speedFrom').value; | |
| const to = document.getElementById('speedTo').value; | |
| const value = parseFloat(document.getElementById('speedValue').value); | |
| // Convert to m/s first | |
| let mps; | |
| switch(from) { | |
| case 'm/s': mps = value; break; | |
| case 'km/h': mps = value / 3.6; break; | |
| case 'mph': mps = value * 0.44704; break; | |
| case 'knot': mps = value * 0.514444; break; | |
| case 'ft/s': mps = value * 0.3048; break; | |
| } | |
| // Convert from m/s to target unit | |
| let result; | |
| switch(to) { | |
| case 'm/s': result = mps; break; | |
| case 'km/h': result = mps * 3.6; break; | |
| case 'mph': result = mps / 0.44704; break; | |
| case 'knot': result = mps / 0.514444; break; | |
| case 'ft/s': result = mps / 0.3048; break; | |
| } | |
| document.getElementById('speedResult').value = result.toFixed(8).replace(/\.?0+$/, ''); | |
| } | |
| // Swap units | |
| document.getElementById('lengthSwap').addEventListener('click', () => { | |
| const from = document.getElementById('lengthFrom'); | |
| const to = document.getElementById('lengthTo'); | |
| const temp = from.value; | |
| from.value = to.value; | |
| to.value = temp; | |
| convertLength(); | |
| }); | |
| document.getElementById('weightSwap').addEventListener('click', () => { | |
| const from = document.getElementById('weightFrom'); | |
| const to = document.getElementById('weightTo'); | |
| const temp = from.value; | |
| from.value = to.value; | |
| to.value = temp; | |
| convertWeight(); | |
| }); | |
| document.getElementById('tempSwap').addEventListener('click', () => { | |
| const from = document.getElementById('tempFrom'); | |
| const to = document.getElementById('tempTo'); | |
| const temp = from.value; | |
| from.value = to.value; | |
| to.value = temp; | |
| convertTemperature(); | |
| }); | |
| document.getElementById('areaSwap').addEventListener('click', () => { | |
| const from = document.getElementById('areaFrom'); | |
| const to = document.getElementById('areaTo'); | |
| const temp = from.value; | |
| from.value = to.value; | |
| to.value = temp; | |
| convertArea(); | |
| }); | |
| document.getElementById('volumeSwap').addEventListener('click', () => { | |
| const from = document.getElementById('volumeFrom'); | |
| const to = document.getElementById('volumeTo'); | |
| const temp = from.value; | |
| from.value = to.value; | |
| to.value = temp; | |
| convertVolume(); | |
| }); | |
| document.getElementById('timeSwap').addEventListener('click', () => { | |
| const from = document.getElementById('timeFrom'); | |
| const to = document.getElementById('timeTo'); | |
| const temp = from.value; | |
| from.value = to.value; | |
| to.value = temp; | |
| convertTime(); | |
| }); | |
| document.getElementById('speedSwap').addEventListener('click', () => { | |
| const from = document.getElementById('speedFrom'); | |
| const to = document.getElementById('speedTo'); | |
| const temp = from.value; | |
| from.value = to.value; | |
| to.value = temp; | |
| convertSpeed(); | |
| }); | |
| // Event listeners for unit conversions | |
| document.getElementById('lengthValue').addEventListener('input', convertLength); | |
| document.getElementById('lengthFrom').addEventListener('change', convertLength); | |
| document.getElementById('lengthTo').addEventListener('change', convertLength); | |
| document.getElementById('weightValue').addEventListener('input', convertWeight); | |
| document.getElementById('weightFrom').addEventListener('change', convertWeight); | |
| document.getElementById('weightTo').addEventListener('change', convertWeight); | |
| document.getElementById('tempValue').addEventListener('input', convertTemperature); | |
| document.getElementById('tempFrom').addEventListener('change', convertTemperature); | |
| document.getElementById('tempTo').addEventListener('change', convertTemperature); | |
| document.getElementById('areaValue').addEventListener('input', convertArea); | |
| document.getElementById('areaFrom').addEventListener('change', convertArea); | |
| document.getElementById('areaTo').addEventListener('change', convertArea); | |
| document.getElementById('volumeValue').addEventListener('input', convertVolume); | |
| document.getElementById('volumeFrom').addEventListener('change', convertVolume); | |
| document.getElementById('volumeTo').addEventListener('change', convertVolume); | |
| document.getElementById('timeValue').addEventListener('input', convertTime); | |
| document.getElementById('timeFrom').addEventListener('change', convertTime); | |
| document.getElementById('timeTo').addEventListener('change', convertTime); | |
| document.getElementById('speedValue').addEventListener('input', convertSpeed); | |
| document.getElementById('speedFrom').addEventListener('change', convertSpeed); | |
| document.getElementById('speedTo').addEventListener('change', convertSpeed); | |
| // Initialize conversions | |
| convertLength(); | |
| convertWeight(); | |
| convertTemperature(); | |
| convertArea(); | |
| convertVolume(); | |
| convertTime(); | |
| convertSpeed(); | |
| // Dark mode toggle | |
| document.getElementById('darkModeToggle').addEventListener('click', () => { | |
| document.body.classList.toggle('dark-mode'); | |
| const icon = document.querySelector('#darkModeToggle i'); | |
| if (document.body.classList.contains('dark-mode')) { | |
| icon.classList.remove('fa-moon'); | |
| icon.classList.add('fa-sun'); | |
| } else { | |
| icon.classList.remove('fa-sun'); | |
| icon.classList.add('fa-moon'); | |
| } | |
| }); | |
| // Help modal | |
| document.getElementById('helpBtn').addEventListener('click', () => { | |
| document.getElementById('helpModal').classList.remove('hidden'); | |
| }); | |
| document.getElementById('closeHelpModal').addEventListener('click', () => { | |
| document.getElementById('helpModal').classList.add('hidden'); | |
| }); | |
| // Close modal when clicking outside | |
| document.getElementById('helpModal').addEventListener('click', (e) => { | |
| if (e.target === document.getElementById('helpModal')) { | |
| document.getElementById('helpModal').classList.add('hidden'); | |
| } | |
| }); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=appliworks/scicalc-pro" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |