Scientific Calculator: Extreme Premium Edition.

 <

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CYBERPUNK CALCULATOR v3.0</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/chart.js/3.9.1/chart.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/11.8.0/math.min.js"></script> <style> :root { --primary: #0a0a1a; --secondary: #121432; --accent: #00ffd5; --accent-alt: #ff2a6d; --text: #e0f7ff; --display-bg: #050510; --neon-glow: 0 0 10px rgba(0, 255, 213, 0.7), 0 0 20px rgba(0, 255, 213, 0.5), 0 0 30px rgba(0, 255, 213, 0.3); --pink-glow: 0 0 10px rgba(255, 42, 109, 0.7), 0 0 20px rgba(255, 42, 109, 0.5), 0 0 30px rgba(255, 42, 109, 0.3); } @font-face { font-family: 'Cyberpunk'; src: url('https://fonts.cdnfonts.com/css/blender-pro') format('woff2'); } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Courier New', monospace; background: linear-gradient(135deg, #000428, #082546); margin: 0; padding: 20px; min-height: 100vh; color: var(--text); position: relative; overflow-x: hidden; } body::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: linear-gradient(90deg, rgba(0, 255, 213, 0.07) 1px, transparent 1px), linear-gradient(rgba(0, 255, 213, 0.07) 1px, transparent 1px); background-size: 40px 40px; z-index: -1; } .glitch-text { position: relative; text-shadow: 0 0 5px var(--accent); animation: glitch 3s infinite; } @keyframes glitch { 0% { text-shadow: 0 0 5px var(--accent); } 1% { text-shadow: -2px 0 var(--accent-alt); } 2% { text-shadow: 2px 0 var(--accent); } 3% { text-shadow: 0 0 5px var(--accent); } 50% { text-shadow: 0 0 5px var(--accent); } 51% { text-shadow: 1px 0 var(--accent-alt); } 52% { text-shadow: -1px 0 var(--accent); } 53% { text-shadow: 0 0 5px var(--accent); } 100% { text-shadow: 0 0 5px var(--accent); } } .container { display: flex; flex-wrap: wrap; gap: 20px; justify-content: center; max-width: 1200px; margin: 0 auto; } .header { width: 100%; text-align: center; margin-bottom: 20px; } .header h1 { font-size: 2.5rem; color: var(--accent); text-transform: uppercase; letter-spacing: 2px; margin-bottom: 5px; } .header p { color: var(--accent-alt); font-size: 1rem; opacity: 0.8; } .calculator { width: 400px; background: var(--primary); border-radius: 10px; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.7); border: 1px solid rgba(0, 255, 213, 0.3); overflow: hidden; position: relative; } .calculator::before { content: ""; position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; background: linear-gradient(45deg, var(--accent), var(--accent-alt), var(--accent)); z-index: -1; border-radius: 12px; opacity: 0.5; animation: border-flow 3s linear infinite; } @keyframes border-flow { 0% { background-position: 0 0; } 100% { background-position: 400% 0; } } .graph-container { width: 600px; background: var(--primary); border-radius: 10px; padding: 15px; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.7); border: 1px solid rgba(0, 255, 213, 0.3); position: relative; } .graph-container::before { content: ""; position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; background: linear-gradient(45deg, var(--accent-alt), var(--accent), var(--accent-alt)); z-index: -1; border-radius: 12px; opacity: 0.5; animation: border-flow 3s linear infinite; animation-delay: -1.5s; } .display { padding: 25px; background: var(--display-bg); min-height: 120px; text-align: right; position: relative; border-bottom: 1px solid rgba(0, 255, 213, 0.2); } .display::after { content: "SYS//CALC-QBIT-V3"; position: absolute; top: 5px; left: 10px; font-size: 10px; color: var(--accent); opacity: 0.6; } #input { font-size: 20px; color: var(--accent); min-height: 28px; font-family: 'Courier New', monospace; position: relative; overflow-wrap: break-word; word-break: break-all; } #output { font-size: 36px; margin-top: 15px; overflow-wrap: break-word; word-break: break-all; transition: all 0.2s ease; } .button-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; padding: 15px; } .btn { border: none; border-radius: 5px; padding: 18px 0; font-size: 18px; cursor: pointer; background: var(--secondary); color: var(--text); transition: all 0.15s; position: relative; overflow: hidden; text-shadow: 0 0 3px rgba(224, 247, 255, 0.7); } .btn::after { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: linear-gradient(90deg, transparent, var(--accent), transparent); opacity: 0; transition: opacity 0.3s; } .btn:hover::after { opacity: 1; } .btn:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); } .btn:active { transform: translateY(1px); } .btn-operator { background: #1a1a4a; color: var(--accent); } .btn-advanced { background: #25254a; color: var(--accent); font-size: 16px; } .btn-equals { background: var(--accent); color: #000; font-weight: bold; box-shadow: var(--neon-glow); } .btn-clear { background: #3d0f22; color: var(--accent-alt); } .btn-const { background: #2a206c; color: #c792ea; } .btn-complex { background: #381f72; color: #ff9edb; } .btn-rpn { background: #622a00; color: #ffae00; } .btn-matrix { background: #432b63; color: #c77dff; } .history-panel { max-height: 100px; overflow-y: auto; margin-top: 10px; padding: 10px; background: rgba(0, 0, 0, 0.3); border-radius: 5px; border: 1px solid rgba(0, 255, 213, 0.1); font-size: 14px; } .history-panel::-webkit-scrollbar { width: 5px; } .history-panel::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.2); } .history-panel::-webkit-scrollbar-thumb { background: var(--accent); border-radius: 5px; } .history-item { padding: 5px; cursor: pointer; border-bottom: 1px solid rgba(0, 255, 213, 0.1); transition: all 0.2s; } .history-item:hover { background: rgba(0, 255, 213, 0.1); padding-left: 10px; } .tabs { display: flex; margin-bottom: 10px; } .tab { padding: 10px 15px; background: var(--secondary); cursor: pointer; border-radius: 5px 5px 0 0; margin-right: 5px; position: relative; overflow: hidden; transition: all 0.3s; } .tab::before { content: ""; position: absolute; bottom: 0; left: 0; width: 100%; height: 2px; background: var(--accent); transform: scaleX(0); transition: transform 0.3s; } .tab:hover::before { transform: scaleX(0.8); } .tab.active { background: var(--accent); color: #000; } .tab.active::before { transform: scaleX(1); background: var(--accent-alt); } .mode-indicator { position: absolute; top: 10px; right: 10px; font-size: 12px; padding: 3px 6px; border-radius: 3px; background: rgba(0, 0, 0, 0.3); border: 1px solid var(--accent); color: var(--accent); opacity: 0; transition: opacity 0.3s; } .mode-indicator.active { opacity: 1; } #matrixInput { width: 100%; background: #16213e; color: var(--text); border: 1px solid rgba(0, 255, 213, 0.3); padding: 10px; border-radius: 5px; font-family: 'Courier New', monospace; resize: vertical; margin-bottom: 10px; } #matrixInput:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px rgba(0, 255, 213, 0.2); } #matrixResult { margin-top: 10px; padding: 10px; background: rgba(0, 0, 0, 0.2); border-radius: 5px; border: 1px solid rgba(0, 255, 213, 0.1); } /* Logo and decorative elements */ .logo { position: absolute; top: 10px; left: 10px; font-size: 14px; color: var(--accent); z-index: 100; } .decoration { position: fixed; bottom: 20px; right: 20px; font-size: 10px; color: var(--accent); opacity: 0.3; z-index: -1; } @media (max-width: 992px) { .calculator, .graph-container { width: 90%; margin: 0 auto; } } </style> </head> <body> <div class="header"> <h1 class="glitch-text">CYBERPUNK CALCULATOR v3.0</h1> <p>QUANTUM COMPUTATIONAL MATRIX SYSTEM</p> </div> <div class="container"> <div class="calculator"> <div class="mode-indicator" id="rpnIndicator">RPN</div> <div class="display"> <div id="input"></div> <div id="output">0</div> <div class="history-panel" id="history"></div> </div> <div class="button-grid"> <button class="btn btn-clear" onclick="clearAll()">AC</button> <button class="btn btn-clear" onclick="backspace()"></button> <button class="btn btn-advanced" onclick="addToInput('%')">%</button> <button class="btn btn-advanced" onclick="addToInput('√(')"></button> <button class="btn btn-operator" onclick="addToInput('^')">^</button> <button class="btn btn-advanced" onclick="addToInput('sin(')">sin</button> <button class="btn btn-advanced" onclick="addToInput('cos(')">cos</button> <button class="btn btn-advanced" onclick="addToInput('tan(')">tan</button> <button class="btn btn-operator" onclick="addToInput('/')">/</button> <button class="btn btn-const" onclick="addToInput('π')">π</button> <button class="btn btn-advanced" onclick="addToInput('log(')">log</button> <button class="btn btn-advanced" onclick="addToInput('ln(')">ln</button> <button class="btn btn-advanced" onclick="addToInput('(')">(</button> <button class="btn btn-advanced" onclick="addToInput(')')">)</button> <button class="btn btn-operator" onclick="addToInput('*')">×</button> <button class="btn btn-advanced" onclick="addToInput('!')">x!</button> <button class="btn" onclick="addToInput('7')">7</button> <button class="btn" onclick="addToInput('8')">8</button> <button class="btn" onclick="addToInput('9')">9</button> <button class="btn btn-operator" onclick="addToInput('-')"></button> <button class="btn btn-complex" onclick="addToInput('i')">i</button> <button class="btn" onclick="addToInput('4')">4</button> <button class="btn" onclick="addToInput('5')">5</button> <button class="btn" onclick="addToInput('6')">6</button> <button class="btn btn-operator" onclick="addToInput('+')">+</button> <button class="btn btn-rpn" onclick="toggleRPN()" id="rpnButton">RPN</button> <button class="btn" onclick="addToInput('1')">1</button> <button class="btn" onclick="addToInput('2')">2</button> <button class="btn" onclick="addToInput('3')">3</button> <button class="btn btn-equals" onclick="calculate()">=</button> <button class="btn btn-matrix" onclick="addToInput('[')">[ ]</button> <button class="btn" onclick="addToInput('0')">0</button> <button class="btn" onclick="addToInput('.')">.</button> <button class="btn btn-advanced" onclick="addToInput('e')">e</button> <button class="btn btn-advanced" onclick="openPlot()">PLOT</button> </div> </div> <div class="graph-container"> <div class="tabs"> <div class="tab active" id="graphTab" onclick="switchTab('graph')">Visualizer</div> <div class="tab" id="matrixTab" onclick="switchTab('matrix')">Matrix Lab</div> <div class="tab" id="plotTab" onclick="switchTab('plot')">Function Plot</div> </div> <div id="graphPanel" style="display:block;"> <canvas id="graphCanvas" style="width:100%; height:400px;"></canvas> </div> <div id="matrixEditor" style="display:none;"> <textarea id="matrixInput" rows="5" placeholder="Enter matrix operations (Example: [[1,2],[3,4]] * [[5,6],[7,8]])"></textarea> <div class="button-grid" style="grid-template-columns: repeat(3, 1fr);"> <button class="btn btn-matrix" onclick="insertMatrixTemplate('identity')">Identity</button> <button class="btn btn-matrix" onclick="insertMatrixTemplate('zero')">Zero</button> <button class="btn btn-matrix" onclick="insertMatrixTemplate('random')">Random</button> <button class="btn btn-matrix" onclick="insertMatrixOp('det')">Determinant</button> <button class="btn btn-matrix" onclick="insertMatrixOp('inv')">Inverse</button> <button class="btn btn-matrix" onclick="insertMatrixOp('transpose')">Transpose</button> </div> <button class="btn btn-equals" style="margin-top:10px; width:100%;" onclick="calculateMatrix()">Compute</button> <div id="matrixResult"></div> </div> <div id="plotEditor" style="display:none;"> <div style="display:flex; margin-bottom:10px;"> <input type="text" id="functionInput" placeholder="Enter function of x (e.g., sin(x) + cos(x))" style="flex:1; padding:10px; background:#16213e; color:var(--text); border:1px solid rgba(0,255,213,0.3); border-radius:5px;"> </div> <div style="display:flex; gap:10px; margin-bottom:10px;"> <div style="flex:1;"> <label for="xMin" style="display:block; margin-bottom:5px; font-size:12px;">X Min</label> <input type="number" id="xMin" value="-10" style="width:100%; padding:8px; background:#16213e; color:var(--text); border:1px solid rgba(0,255,213,0.3); border-radius:5px;"> </div> <div style="flex:1;"> <label for="xMax" style="display:block; margin-bottom:5px; font-size:12px;">X Max</label> <input type="number" id="xMax" value="10" style="width:100%; padding:8px; background:#16213e; color:var(--text); border:1px solid rgba(0,255,213,0.3); border-radius:5px;"> </div> </div> <button class="btn btn-equals" style="width:100%;" onclick="plotUserFunction()">Generate Plot</button> </div> </div> </div> <div class="decoration"> NETRUNNER//SYS-ACCESS::GRANTED<br> QUANTUM-CORE::ACTIVATED<br> CRYPTO-MATRIX::INITIALIZED<br> CYB0X//V3.0::RUNNING </div> <script> // Initialize Math.js with proper configuration math.config({ number: 'number', // Use regular JavaScript numbers for better performance precision: 64 // High precision for accurate calculations }); // Global Variables let input = ""; let isRPN = false; let rpnStack = []; let currentPlot = null; // DOM elements const inputElement = document.getElementById("input"); const outputElement = document.getElementById("output"); const historyElement = document.getElementById("history"); const rpnIndicator = document.getElementById("rpnIndicator"); const canvasContext = document.getElementById("graphCanvas").getContext('2d'); // Initialize the calculator function initialize() { loadHistory(); resizeCanvas(); window.addEventListener('resize', resizeCanvas); } // Resize the canvas to fit its container function resizeCanvas() { const canvas = document.getElementById("graphCanvas"); const container = canvas.parentElement; canvas.width = container.clientWidth; canvas.height = 400; if (currentPlot) { redrawPlot(); } } // Load calculation history from localStorage function loadHistory() { try { const history = JSON.parse(localStorage.getItem('cyberCalcHistory')) || []; historyElement.innerHTML = history.map(item => `<div class="history-item" onclick="useHistory('${item.input.replace(/'/g, "\\'")}')">${item.input} = ${item.result}</div>` ).join(''); } catch (error) { console.error("Error loading history:", error); localStorage.removeItem('cyberCalcHistory'); historyElement.innerHTML = ""; } } // Save calculation to history function saveToHistory(expr, result) { try { const history = JSON.parse(localStorage.getItem('cyberCalcHistory')) || []; // Add to start of array, and convert complex results to string history.unshift({ input: expr, result: typeof result === 'object' && result.hasOwnProperty('re') ? `${result.re} + ${result.im}i` : String(result) }); // Keep only the most recent 100 entries if (history.length > 100) history.pop(); localStorage.setItem('cyberCalcHistory', JSON.stringify(history)); loadHistory(); } catch (error) { console.error("Error saving to history:", error); } } // Use an item from history function useHistory(expr) { input = expr; inputElement.textContent = input; } // Toggle RPN mode function toggleRPN() { isRPN = !isRPN; rpnIndicator.classList.toggle('active', isRPN); document.getElementById("rpnButton").style.boxShadow = isRPN ? '0 0 10px #ffae00, 0 0 20px rgba(255, 174, 0, 0.5)' : 'none'; inputElement.textContent = isRPN ? "RPN Mode: " + rpnStack.join(" ") : input; } // RPN calculation function calculateRPN() { try { if (rpnStack.length < 2) { outputElement.textContent = "Need at least 2 numbers"; return; } // Parse the last input as an operator const operator = input.trim(); // Need at least two operands if (rpnStack.length < 2) { outputElement.textContent = "Need more operands"; return; } // Pop the last two operands const b = rpnStack.pop(); const a = rpnStack.pop(); let result; // Perform operation switch (operator) { case '+': result = math.add(math.bignumber(a), math.bignumber(b)); break; case '-': result = math.subtract(math.bignumber(a), math.bignumber(b)); break; case '*': result = math.multiply(math.bignumber(a), math.bignumber(b)); break; case '/': result = math.divide(math.bignumber(a), math.bignumber(b)); break; case '^': result = math.pow(math.bignumber(a), math.bignumber(b)); break; default: outputElement.textContent = "Unknown operator"; return; } // Convert result to string and push back to stack result = result.toString(); rpnStack.push(result); // Display result outputElement.textContent = result; inputElement.textContent = "RPN Mode: " + rpnStack.join(" "); // Save to history saveToHistory(`${a} ${b} ${operator}`, result); input = ""; } catch (error) { console.error("RPN Error:", error); outputElement.textContent = "RPN Error: " + error.message; } } // Standard calculation function calculate() { if (isRPN) { // In RPN mode and we have a new operator if (input.trim() === "+" || input.trim() === "-" || input.trim() === "*" || input.trim() === "/" || input.trim() === "^") { calculateRPN(); } return; } if (!input.trim()) { return; // Nothing to calculate } try { // Normalize input for math.js let expr = input .replace(/×/g, "*") .replace(/÷/g, "/") .replace(/\^/g, "**") .replace(/√\(/g, "sqrt(") .replace(/π/g, "pi"); // Handle factorial separately as math.js doesn't support postfix notation expr = expr.replace(/(\d+)!/g, (match, number) => { return `factorial(${number})`; }); // Handle special case for plotting if (expr.startsWith("plot(")) { plotFunction(); return; } // Evaluate expression const result = math.evaluate(expr); // Format and display result if (typeof result === 'object' && result.hasOwnProperty('re')) { // Handle complex numbers outputElement.textContent = `${result.re} + ${result.im}i`; } else if (Array.isArray(result)) { // Handle matrices outputElement.textContent = "Matrix result in Matrix tab"; switchTab('matrix'); document.getElementById('matrixResult').innerHTML = `<strong>Result:</strong><br>${math.format(result, {precision: 4})}`; } else { // Handle scalars outputElement.textContent = result; } // Save to history and clear input saveToHistory(input, result); input = ""; inputElement.textContent = ""; } catch (error) { console.error("Calculation Error:", error); outputElement.textContent = "Error: " + error.message; } } // Plot a function defined in the input field function plotFunction() { try { // Extract function and range from input const regex = /plot\(\s*([^,]+),\s*([^,]+),\s*([^)]+)\s*\)/; const match = input.match(regex); if (!match || match.length < 4) { throw new Error("Invalid plot format. Use: plot(f(x), xMin, xMax)"); } const expr = match[1].trim(); const xMin = parseFloat(match[2]); const xMax = parseFloat(match[3]); if (isNaN(xMin) || isNaN(xMax)) { throw new Error("Invalid range values"); } // Create the plot createFunctionPlot(expr, xMin, xMax); // Display confirmation outputElement.textContent = `Plotted: ${expr}`; // Switch to graph tab switchTab('graph'); } catch (error) { console.error("Plot Error:", error); outputElement.textContent = "Plot Error: " + error.message; } } // Open the plot tab with current input as the function function openPlot() { document.getElementById('functionInput').value = input; switchTab('plot'); } // Plot a user function from the plot panel function plotUserFunction() { const functionExpr = document.getElementById('functionInput').value; const xMin = parseFloat(document.getElementById('xMin').value); const xMax = parseFloat(document.getElementById('xMax').value); if (!functionExpr) { document.getElementById('graphResult').innerHTML = '<div style="color:var(--accent-alt)">Please enter a function</div>'; return; } if (isNaN(xMin) || isNaN(xMax)) { document.getElementById('graphResult').innerHTML = '<div style="color:var(--accent-alt)">Invalid range values</div>'; return; } try { createFunctionPlot(functionExpr, xMin, xMax); switchTab('graph'); } catch (error) { document.getElementById('graphResult').innerHTML = `<div style="color:var(--accent-alt)">Error: ${error.message}</div>`; } } // Create a function plot with the specified expression and range function createFunctionPlot(expr, xMin, xMax) { try { // Generate data points const points = generatePoints(expr, xMin, xMax); // Store current plot configuration currentPlot = { expr: expr, xMin: xMin, xMax: xMax, points: points }; // Create the plot createPlot(points, expr); } catch (error) { console.error("Plot creation error:", error); throw error; } } // Generate points for the function function generatePoints(expr, xMin, xMax, numPoints = 500) { const points = []; const step = (xMax - xMin) / numPoints; const scope = {}; try { // Pre-compile the expression for efficiency const compiledExpr = math.compile(expr); for (let x = xMin; x <= xMax; x += step) { scope.x = x; try { const y = compiledExpr.evaluate(scope); // Skip infinity, NaN or extremely large values if (isFinite(y) && Math.abs(y) < 1e12) { points.push({ x, y }); } } catch (e) { // Skip points that can't be evaluated continue; } } return points; } catch (error) { console.error("Error generating points:", error); throw error; } } // Create a plot using Chart.js function createPlot(points, expr) { const ctx = document.getElementById('graphCanvas').getContext('2d'); // Destroy existing chart if there is one if (window.functionPlot instanceof Chart) { window.functionPlot.destroy(); } // Extract x and y values const xValues = points.map(p => p.x); const yValues = points.map(p => p.y); // Create a new chart window.functionPlot = new Chart(ctx, { type: 'line', data: { labels: xValues, datasets: [{ label: expr, data: yValues, borderColor: 'rgba(0, 255, 213, 1)', backgroundColor: 'rgba(0, 255, 213, 0.1)', borderWidth: 2, tension: 0.1, pointRadius: 0, fill: false }] }, options: { responsive: true, maintainAspectRatio: false, scales: { x: { type: 'linear', position: 'bottom', grid: { color: 'rgba(0, 255, 213, 0.1)' }, ticks: { color: 'rgba(224, 247, 255, 0.7)' }, title: { display: true, text: 'x', color: 'rgba(224, 247, 255, 0.9)' } }, y: { grid: { color: 'rgba(0, 255, 213, 0.1)' }, ticks: { color: 'rgba(224, 247, 255, 0.7)' }, title: { display: true, text: 'f(x)', color: 'rgba(224, 247, 255, 0.9)' } } }, plugins: { legend: { labels: { color: 'rgba(224, 247, 255, 0.9)' } }, tooltip: { backgroundColor: 'rgba(0, 0, 26, 0.8)', borderColor: 'rgba(0, 255, 213, 0.8)', borderWidth: 1, titleColor: 'rgba(0, 255, 213, 1)', bodyColor: 'rgba(224, 247, 255, 1)', displayColors: false, callbacks: { title: function(tooltipItems) { const x = tooltipItems[0].parsed.x; return `x = ${x.toFixed(4)}`; }, label: function(context) { const y = context.parsed.y; return `f(x) = ${y.toFixed(6)}`; } } } }, animation: { duration: 1000, easing: 'easeOutQuart' } } }); } // Redraw the current plot (used after resize) function redrawPlot() { if (currentPlot) { createPlot(currentPlot.points, currentPlot.expr); } } // Matrix operations function calculateMatrix() { try { const matrixExpr = document.getElementById("matrixInput").value; if (!matrixExpr.trim()) { document.getElementById("matrixResult").innerHTML = '<div style="color:var(--accent-alt)">Please enter a matrix expression</div>'; return; } // Evaluate the expression const result = math.evaluate(matrixExpr); // Format the result let formattedResult; if (Array.isArray(result)) { // Format as a matrix formattedResult = formatMatrix(result); } else if (typeof result === 'number' || typeof result === 'object') { // Format scalar or complex number formattedResult = math.format(result, { precision: 6 }); } else { formattedResult = String(result); } // Display the result document.getElementById("matrixResult").innerHTML = `<div style="margin-top:10px;"><strong style="color:var(--accent)">Result:</strong> <div style="margin-top:5px;font-family:monospace;white-space:pre;">${formattedResult}</div></div>`; } catch (error) { console.error("Matrix calculation error:", error); document.getElementById("matrixResult").innerHTML = `<div style="color:var(--accent-alt)">Error: ${error.message}</div>`; } } // Format a matrix for display function formatMatrix(matrix) { if (!Array.isArray(matrix)) return String(matrix); // Check if it's a vector if (!Array.isArray(matrix[0])) { return '[ ' + matrix.map(val => math.format(val, { precision: 4 })).join(', ') + ' ]'; } // It's a 2D matrix let result = ''; for (let i = 0; i < matrix.length; i++) { result += '[ ' + matrix[i].map(val => math.format(val, { precision: 4 })).join(', ') + ' ]\n'; } return result; } // Insert matrix templates function insertMatrixTemplate(type) { let template = ''; switch (type) { case 'identity': template = 'identity(3)'; // 3x3 identity matrix break; case 'zero': template = 'zeros(3, 3)'; // 3x3 zero matrix break; case 'random': template = 'random(3, 3)'; // 3x3 random matrix break; default: return; } const matrixInput = document.getElementById('matrixInput'); matrixInput.value = template; matrixInput.focus(); } // Insert matrix operations function insertMatrixOp(op) { let template = ''; const placeholder = '[[1,2],[3,4]]'; switch (op) { case 'det': template = `det(${placeholder})`; break; case 'inv': template = `inv(${placeholder})`; break; case 'transpose': template = `transpose(${placeholder})`; break; default: return; } const matrixInput = document.getElementById('matrixInput'); matrixInput.value = template; matrixInput.focus(); } // Switch between tabs (graph/matrix/plot) function switchTab(tab) { // Update tab appearance document.querySelectorAll('.tab').forEach(t => t.classList.remove('active')); document.getElementById(`${tab}Tab`).classList.add('active'); // Hide all panels document.getElementById('graphPanel').style.display = 'none'; document.getElementById('matrixEditor').style.display = 'none'; document.getElementById('plotEditor').style.display = 'none'; // Show selected panel switch(tab) { case 'graph': document.getElementById('graphPanel').style.display = 'block'; if (currentPlot) redrawPlot(); break; case 'matrix': document.getElementById('matrixEditor').style.display = 'block'; break; case 'plot': document.getElementById('plotEditor').style.display = 'block'; break; } } // Add to input display function addToInput(value) { // Special case for RPN mode if (isRPN) { if (/^[\d.e]+$/.test(value)) { // Number input in RPN mode rpnStack.push(value); input = ""; inputElement.textContent = "RPN Mode: " + rpnStack.join(" "); } else if (['+', '-', '*', '/', '^'].includes(value)) { // Operator in RPN mode, store it for calculation input = value; inputElement.textContent = "RPN Mode: " + rpnStack.join(" ") + " " + value; } return; } // Handle opening bracket for matrices with automatic closing bracket if (value === '[') { input += '[]'; inputElement.textContent = input; // Set cursor position inside brackets const range = document.createRange(); const sel = window.getSelection(); range.setStart(inputElement.firstChild || inputElement, input.length - 1); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); return; } // Normal input handling input += value; inputElement.textContent = input; // Show live preview calculation for simple expressions if (/^[\d+\-*/.()^]+$/.test(input)) { try { const result = math.evaluate(input); if (!isNaN(result)) { outputElement.textContent = result; outputElement.style.opacity = '0.7'; } } catch { // Ignore errors in live preview } } } // Clear all input and output function clearAll() { input = ""; inputElement.textContent = ""; outputElement.textContent = "0"; outputElement.style.opacity = '1'; if (isRPN) { rpnStack = []; inputElement.textContent = "RPN Mode: "; } } // Backspace (delete last character) function backspace() { if (isRPN && rpnStack.length > 0) { rpnStack.pop(); input = ""; inputElement.textContent = "RPN Mode: " + rpnStack.join(" "); } else { input = input.slice(0, -1); inputElement.textContent = input; } } // Add keyboard support document.addEventListener('keydown', (e) => { // Prevent default for calculator keys to avoid page scrolling if (/[0-9+\-*/().^]/.test(e.key) || e.key === 'Enter' || e.key === 'Backspace' || e.key === 'Escape') { e.preventDefault(); } // Handle key presses if (/[0-9+\-*/().^]/.test(e.key)) { addToInput(e.key); } else if (e.key === 'Enter') { calculate(); } else if (e.key === 'Backspace') { backspace(); } else if (e.key === 'Escape') { clearAll(); } }); // Add cyberpunk typing effect to outputs function applyTypingEffect(element, text, speed = 30) { const originalText = text; element.textContent = ''; let i = 0; function type() { if (i < originalText.length) { element.textContent += originalText.charAt(i); i++; setTimeout(type, speed); } } type(); } // Add visual feedback when a button is clicked document.querySelectorAll('.btn').forEach(button => { button.addEventListener('click', function() { this.style.transform = 'scale(0.95)'; setTimeout(() => { this.style.transform = ''; }, 100); }); }); // Add glowing effect on calculator startup function startupAnimation() { const calculator = document.querySelector('.calculator'); const graph = document.querySelector('.graph-container'); calculator.style.opacity = '0'; graph.style.opacity = '0'; setTimeout(() => { calculator.style.transition = 'all 1s ease'; graph.style.transition = 'all 1s ease'; calculator.style.opacity = '1'; graph.style.opacity = '1'; }, 300); setTimeout(() => { applyTypingEffect(outputElement, '0', 50); }, 800); } // Initialize everything window.addEventListener('load', () => { initialize(); startupAnimation(); });

Comments

Popular posts from this blog

Articles for Calculator.ist

Calc.ist: List of all Calculators: Total of 592.

HP-65 Calculator Simulator (1974)