Calculadora CalPad Código HTML
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculadora Científica com Salvamento de Resultados</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
color: #f8fafc;
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
header {
text-align: center;
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
h1 {
font-size: 2.5rem;
margin-bottom: 10px;
background: linear-gradient(to right, #3b82f6, #8b5cf6);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.subtitle {
color: #94a3b8;
font-size: 1.1rem;
}
.app-container {
display: grid;
grid-template-columns: 1.5fr 1fr;
gap: 30px;
}
@media (max-width: 1024px) {
.app-container {
grid-template-columns: 1fr;
}
}
.calculator-container {
background: rgba(30, 41, 59, 0.8);
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
.calculator-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.mode-selector {
display: flex;
gap: 10px;
}
.mode-btn {
padding: 8px 16px;
border: none;
border-radius: 8px;
background: #334155;
color: #cbd5e1;
cursor: pointer;
font-weight: 600;
transition: all 0.2s;
}
.mode-btn.active {
background: #3b82f6;
color: white;
}
.display {
background-color: #1e293b;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
text-align: right;
font-size: 2.2rem;
min-height: 100px;
word-break: break-all;
overflow-wrap: break-word;
border: 2px solid #3b82f6;
font-family: 'Courier New', monospace;
}
.calculator-basic, .calculator-advanced {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 12px;
}
.calculator-advanced {
display: none;
}
button {
border: none;
border-radius: 10px;
padding: 18px 5px;
font-size: 1.1rem;
font-weight: bold;
cursor: pointer;
transition: all 0.2s ease;
color: white;
}
button:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
button:active {
transform: translateY(1px);
}
.number {
background-color: #475569;
}
.number:hover {
background-color: #64748b;
}
.operator {
background-color: #1d4ed8;
}
.operator:hover {
background-color: #2563eb;
}
.advanced {
background-color: #7c3aed;
}
.advanced:hover {
background-color: #8b5cf6;
}
.equals {
background-color: #059669;
}
.equals:hover {
background-color: #10b981;
}
.clear, .backspace {
background-color: #dc2626;
}
.clear:hover, .backspace:hover {
background-color: #ef4444;
}
.memory {
background-color: #f59e0b;
}
.memory:hover {
background-color: #fbbf24;
}
.constant {
background-color: #0d9488;
}
.constant:hover {
background-color: #14b8a6;
}
.save-section {
background: rgba(30, 41, 59, 0.8);
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
.save-form {
margin-bottom: 25px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
color: #cbd5e1;
font-weight: 600;
}
input, textarea, select {
width: 100%;
padding: 15px;
background-color: #1e293b;
border: 2px solid #3b82f6;
border-radius: 10px;
color: white;
font-size: 1rem;
}
textarea {
height: 100px;
resize: vertical;
}
.btn-save {
background-color: #059669;
width: 100%;
padding: 18px;
font-size: 1.2rem;
margin-top: 10px;
}
.btn-save:hover {
background-color: #10b981;
}
.results-log {
background-color: #1e293b;
border-radius: 10px;
padding: 20px;
max-height: 350px;
overflow-y: auto;
margin-bottom: 20px;
}
.results-log h3 {
margin-bottom: 15px;
color: #cbd5e1;
display: flex;
justify-content: space-between;
align-items: center;
}
.clear-results {
background: #dc2626;
color: white;
border: none;
border-radius: 6px;
padding: 6px 12px;
font-size: 0.8rem;
cursor: pointer;
}
.result-item {
background-color: rgba(255, 255, 255, 0.05);
border-left: 4px solid #3b82f6;
padding: 15px;
margin-bottom: 15px;
border-radius: 0 8px 8px 0;
}
.result-expression {
font-size: 1.1rem;
font-weight: bold;
margin-bottom: 5px;
font-family: 'Courier New', monospace;
}
.result-comment {
color: #94a3b8;
font-style: italic;
margin-bottom: 5px;
}
.result-date {
font-size: 0.8rem;
color: #64748b;
display: flex;
justify-content: space-between;
}
.export-section {
text-align: center;
padding-top: 20px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.export-options {
display: flex;
gap: 10px;
margin-bottom: 15px;
}
.export-btn {
flex: 1;
background-color: #7c3aed;
padding: 15px;
font-size: 1rem;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.export-btn:hover {
background-color: #8b5cf6;
}
.import-section {
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.btn-import {
background-color: #f59e0b;
color: #1e293b;
font-weight: bold;
}
.btn-import:hover {
background-color: #fbbf24;
}
.empty-log {
text-align: center;
color: #94a3b8;
padding: 20px;
font-style: italic;
}
.instructions {
background-color: rgba(30, 41, 59, 0.8);
border-radius: 10px;
padding: 25px;
margin-top: 30px;
font-size: 0.95rem;
line-height: 1.6;
}
.instructions h3 {
color: #3b82f6;
margin-bottom: 15px;
}
.instructions-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
.instruction-group {
background: rgba(15, 23, 42, 0.6);
padding: 15px;
border-radius: 8px;
}
.instruction-group h4 {
color: #8b5cf6;
margin-bottom: 10px;
}
.instruction-group ul {
padding-left: 20px;
color: #cbd5e1;
}
.instruction-group li {
margin-bottom: 6px;
}
.memory-display {
display: flex;
justify-content: space-between;
background: rgba(30, 41, 59, 0.9);
padding: 10px;
border-radius: 8px;
margin-top: 15px;
font-size: 0.9rem;
color: #cbd5e1;
}
.memory-value {
color: #fbbf24;
font-weight: bold;
}
footer {
text-align: center;
margin-top: 30px;
padding-top: 20px;
color: #64748b;
font-size: 0.9rem;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>Calculadora Científica com Salvamento</h1>
<p class="subtitle">Calculadora avançada com funções científicas e sistema de salvamento em JSON</p>
</header>
<div class="app-container">
<!-- Calculadora -->
<section class="calculator-container">
<div class="calculator-header">
<h2>Calculadora</h2>
<div class="mode-selector">
<button class="mode-btn active" id="basic-mode">Básica</button>
<button class="mode-btn" id="advanced-mode">Avançada</button>
</div>
</div>
<div class="display" id="display">0</div>
<!-- Modo Básico -->
<div class="calculator-basic" id="basic-calculator">
<button class="clear" onclick="clearDisplay()">C</button>
<button class="backspace" onclick="backspace()">⌫</button>
<button class="operator" onclick="appendToDisplay('/')">/</button>
<button class="operator" onclick="appendToDisplay('*')">×</button>
<button class="memory" onclick="memoryRecall()">MR</button>
<button class="number" onclick="appendToDisplay('7')">7</button>
<button class="number" onclick="appendToDisplay('8')">8</button>
<button class="number" onclick="appendToDisplay('9')">9</button>
<button class="operator" onclick="appendToDisplay('-')">-</button>
<button class="memory" onclick="memoryClear()">MC</button>
<button class="number" onclick="appendToDisplay('4')">4</button>
<button class="number" onclick="appendToDisplay('5')">5</button>
<button class="number" onclick="appendToDisplay('6')">6</button>
<button class="operator" onclick="appendToDisplay('+')">+</button>
<button class="memory" onclick="memoryAdd()">M+</button>
<button class="number" onclick="appendToDisplay('1')">1</button>
<button class="number" onclick="appendToDisplay('2')">2</button>
<button class="number" onclick="appendToDisplay('3')">3</button>
<button class="equals" onclick="calculate()" style="grid-row: span 2;">=</button>
<button class="memory" onclick="memorySubtract()">M-</button>
<button class="number" onclick="appendToDisplay('0')" style="grid-column: span 2;">0</button>
<button class="number" onclick="appendToDisplay('.')">.</button>
<button class="operator" onclick="appendToDisplay('%')">%</button>
<button class="advanced" onclick="toggleCalculatorMode()">Científica ▶</button>
</div>
<!-- Modo Avançado -->
<div class="calculator-advanced" id="advanced-calculator">
<button class="clear" onclick="clearDisplay()">C</button>
<button class="backspace" onclick="backspace()">⌫</button>
<button class="operator" onclick="appendToDisplay('(')">(</button>
<button class="operator" onclick="appendToDisplay(')')">)</button>
<button class="advanced" onclick="toggleCalculatorMode()">◀ Básica</button>
<button class="advanced" onclick="appendFunction('sqrt(')">√</button>
<button class="advanced" onclick="appendFunction('Math.pow(')">xʸ</button>
<button class="advanced" onclick="appendToDisplay('Math.PI')">π</button>
<button class="advanced" onclick="appendToDisplay('Math.E')">e</button>
<button class="memory" onclick="memoryRecall()">MR</button>
<button class="advanced" onclick="appendFunction('Math.sin(')">sin</button>
<button class="advanced" onclick="appendFunction('Math.cos(')">cos</button>
<button class="advanced" onclick="appendFunction('Math.tan(')">tan</button>
<button class="advanced" onclick="appendFunction('Math.log(')">ln</button>
<button class="memory" onclick="memoryClear()">MC</button>
<button class="advanced" onclick="appendFunction('Math.asin(')">sin⁻¹</button>
<button class="advanced" onclick="appendFunction('Math.acos(')">cos⁻¹</button>
<button class="advanced" onclick="appendFunction('Math.atan(')">tan⁻¹</button>
<button class="advanced" onclick="appendFunction('Math.log10(')">log</button>
<button class="memory" onclick="memoryAdd()">M+</button>
<button class="constant" onclick="appendToDisplay('Math.sqrt(2)')">√2</button>
<button class="constant" onclick="appendToDisplay('1/')">1/x</button>
<button class="advanced" onclick="appendToDisplay('**2')">x²</button>
<button class="advanced" onclick="appendToDisplay('**')">^</button>
<button class="memory" onclick="memorySubtract()">M-</button>
<button class="advanced" onclick="appendFunction('Math.abs(')">|x|</button>
<button class="advanced" onclick="appendToDisplay('!')">n!</button>
<button class="advanced" onclick="appendToDisplay('%')">%</button>
<button class="equals" onclick="calculate()">=</button>
<button class="advanced" onclick="appendToDisplay('Math.random()')">Rand</button>
</div>
<div class="memory-display">
<span>Memória:</span>
<span class="memory-value" id="memory-value">0</span>
</div>
</section>
<!-- Seção de salvamento -->
<section class="save-section">
<div class="save-form">
<div class="form-group">
<label for="result-type">Tipo de resultado:</label>
<select id="result-type">
<option value="calculation">Cálculo</option>
<option value="scientific">Científico</option>
<option value="financial">Financeiro</option>
<option value="statistical">Estatístico</option>
<option value="engineering">Engenharia</option>
</select>
</div>
<div class="form-group">
<label for="comment">Comentário sobre o cálculo:</label>
<textarea id="comment" placeholder="Digite um comentário sobre este cálculo (opcional)"></textarea>
</div>
<button class="btn-save" onclick="saveResult()">
💾 Salvar Resultado Atual
</button>
</div>
<div class="results-log">
<h3>
Resultados Salvos
<button class="clear-results" onclick="clearAllResults()">Limpar Tudo</button>
</h3>
<div id="results-list">
<!-- Os resultados salvos aparecerão aqui -->
<div class="empty-log">Nenhum resultado salvo ainda</div>
</div>
</div>
<div class="export-section">
<div class="export-options">
<button class="export-btn" onclick="exportToJSON()">
📥 JSON
</button>
<button class="export-btn" onclick="exportToCSV()">
📊 CSV
</button>
<button class="export-btn" onclick="exportToTXT()">
📝 TXT
</button>
</div>
<div class="import-section">
<input type="file" id="import-file" accept=".json" style="display: none;">
<button class="export-btn btn-import" onclick="importFromJSON()">
📤 Importar JSON
</button>
</div>
</div>
</section>
</div>
<div class="instructions">
<h3>Instruções de Uso:</h3>
<div class="instructions-grid">
<div class="instruction-group">
<h4>Funções Básicas</h4>
<ul>
<li><strong>C</strong>: Limpa a tela</li>
<li><strong>⌫</strong>: Apaga o último caractere</li>
<li><strong>%</strong>: Calcula porcentagem</li>
<li><strong>MR/MC/M+/M-</strong>: Funções de memória</li>
<li><strong>Enter</strong>: Calcula o resultado</li>
</ul>
</div>
<div class="instruction-group">
<h4>Funções Avançadas</h4>
<ul>
<li><strong>√</strong>: Raiz quadrada</li>
<li><strong>xʸ</strong>: Potência (x elevado a y)</li>
<li><strong>sin/cos/tan</strong>: Funções trigonométricas</li>
<li><strong>sin⁻¹/cos⁻¹/tan⁻¹</strong>: Funções trigonométricas inversas</li>
<li><strong>ln/log</strong>: Logaritmo natural e base 10</li>
</ul>
</div>
<div class="instruction-group">
<h4>Constantes</h4>
<ul>
<li><strong>π</strong>: Pi (3.14159...)</li>
<li><strong>e</strong>: Número de Euler (2.71828...)</li>
<li><strong>√2</strong>: Raiz quadrada de 2</li>
<li><strong>Rand</strong>: Número aleatório entre 0 e 1</li>
</ul>
</div>
<div class="instruction-group">
<h4>Sistema de Salvamento</h4>
<ul>
<li>Salve resultados com comentários</li>
<li>Classifique por tipo de cálculo</li>
<li>Exporte para JSON, CSV ou TXT</li>
<li>Importe resultados de arquivos JSON</li>
<li>Dados são salvos automaticamente</li>
</ul>
</div>
</div>
</div>
<footer>
<p>Calculadora Científica com Salvamento de Resultados | Desenvolvida em HTML, CSS e JavaScript</p>
</footer>
</div>
<script>
// Variáveis globais
let display = document.getElementById('display');
let currentResult = null;
let savedResults = JSON.parse(localStorage.getItem('calculatorResults')) || [];
let memory = 0;
let isAdvancedMode = false;
// Elementos da interface
const basicModeBtn = document.getElementById('basic-mode');
const advancedModeBtn = document.getElementById('advanced-mode');
const basicCalculator = document.getElementById('basic-calculator');
const advancedCalculator = document.getElementById('advanced-calculator');
// Alternar entre modos básico e avançado
basicModeBtn.addEventListener('click', () => {
setCalculatorMode(false);
});
advancedModeBtn.addEventListener('click', () => {
setCalculatorMode(true);
});
function setCalculatorMode(advanced) {
isAdvancedMode = advanced;
if (advanced) {
basicModeBtn.classList.remove('active');
advancedModeBtn.classList.add('active');
basicCalculator.style.display = 'none';
advancedCalculator.style.display = 'grid';
} else {
basicModeBtn.classList.add('active');
advancedModeBtn.classList.remove('active');
basicCalculator.style.display = 'grid';
advancedCalculator.style.display = 'none';
}
}
// Alternar entre modos básico e científico (botão na calculadora)
function toggleCalculatorMode() {
setCalculatorMode(!isAdvancedMode);
}
// Função para adicionar conteúdo ao display
function appendToDisplay(value) {
if (display.innerText === '0' && value !== '.' && !value.includes('Math.')) {
display.innerText = value;
} else {
display.innerText += value;
}
}
// Função para adicionar funções matemáticas
function appendFunction(func) {
if (display.innerText === '0') {
display.innerText = func;
} else {
// Se o último caractere é um número ou fecha parênteses, adiciona operador de multiplicação
const lastChar = display.innerText.slice(-1);
if (lastChar.match(/[\d\)]/)) {
display.innerText += '*' + func;
} else {
display.innerText += func;
}
}
}
// Função para limpar o display
function clearDisplay() {
display.innerText = '0';
}
// Função para apagar o último caractere
function backspace() {
if (display.innerText.length > 1) {
display.innerText = display.innerText.slice(0, -1);
} else {
display.innerText = '0';
}
}
// Função para calcular fatorial
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;
}
// Função para calcular a expressão
function calculate() {
try {
let expression = display.innerText;
// Substituir símbolos para avaliação
expression = expression
.replace(/×/g, '*')
.replace(/÷/g, '/')
.replace(/π/g, 'Math.PI')
.replace(/e/g, 'Math.E')
.replace(/\^/g, '**')
.replace(/√2/g, 'Math.sqrt(2)');
// Processar fatorial
if (expression.includes('!')) {
// Substituir n! pelo fatorial de n
expression = expression.replace(/(\d+)!/g, (match, n) => {
return factorial(parseInt(n));
});
}
// Processar porcentagem
if (expression.includes('%')) {
expression = expression.replace(/([\d\.]+)%/g, (match, n) => {
return parseFloat(n) / 100;
});
}
// Avaliar a expressão
currentResult = eval(expression);
// Verificar se o resultado é um número válido
if (isNaN(currentResult) || !isFinite(currentResult)) {
display.innerText = 'Erro';
currentResult = null;
} else {
// Formatar o resultado
if (Math.abs(currentResult) < 1e-6 && currentResult !== 0) {
// Notação científica para números muito pequenos
display.innerText = currentResult.toExponential(8);
} else if (Math.abs(currentResult) > 1e12) {
// Notação científica para números muito grandes
display.innerText = currentResult.toExponential(8);
} else {
// Número com precisão razoável
const formatted = parseFloat(currentResult.toPrecision(12));
display.innerText = formatted.toString().length > 15 ?
formatted.toExponential(8) : formatted;
}
}
} catch (error) {
console.error('Erro no cálculo:', error);
display.innerText = 'Erro';
currentResult = null;
}
}
// Funções de memória
function memoryClear() {
memory = 0;
updateMemoryDisplay();
}
function memoryRecall() {
if (display.innerText === '0') {
display.innerText = memory.toString();
} else {
display.innerText += memory.toString();
}
}
function memoryAdd() {
try {
const currentValue = parseFloat(eval(display.innerText.replace(/×/g, '*').replace(/÷/g, '/'))) || 0;
memory += currentValue;
updateMemoryDisplay();
} catch (error) {
console.error('Erro ao adicionar à memória:', error);
}
}
function memorySubtract() {
try {
const currentValue = parseFloat(eval(display.innerText.replace(/×/g, '*').replace(/÷/g, '/'))) || 0;
memory -= currentValue;
updateMemoryDisplay();
} catch (error) {
console.error('Erro ao subtrair da memória:', error);
}
}
function updateMemoryDisplay() {
document.getElementById('memory-value').textContent = memory.toString();
}
// Função para salvar o resultado atual com comentário
function saveResult() {
if (display.innerText === '0' || display.innerText === 'Erro') {
alert('Primeiro calcule um resultado válido antes de salvar!');
return;
}
const comment = document.getElementById('comment').value.trim();
const resultType = document.getElementById('result-type').value;
const expression = display.innerText;
// Criar objeto com o resultado
const resultObj = {
id: Date.now(),
expression: expression,
result: currentResult || parseFloat(expression),
comment: comment || "Sem comentário",
type: resultType,
timestamp: new Date().toISOString(),
displayDate: new Date().toLocaleString('pt-BR')
};
// Adicionar à lista de resultados salvos
savedResults.unshift(resultObj);
// Limitar a 50 resultados salvos
if (savedResults.length > 50) {
savedResults = savedResults.slice(0, 50);
}
// Salvar no localStorage
localStorage.setItem('calculatorResults', JSON.stringify(savedResults));
// Atualizar a lista de resultados na interface
updateResultsList();
// Limpar o campo de comentário
document.getElementById('comment').value = '';
// Feedback visual
showNotification('Resultado salvo com sucesso!');
}
// Função para atualizar a lista de resultados na interface
function updateResultsList() {
const resultsList = document.getElementById('results-list');
if (savedResults.length === 0) {
resultsList.innerHTML = '<div class="empty-log">Nenhum resultado salvo ainda</div>';
return;
}
resultsList.innerHTML = savedResults.map(result => `
<div class="result-item">
<div class="result-expression">${result.expression} = <strong>${result.result}</strong></div>
<div class="result-comment">${result.comment} <span style="color: #3b82f6; font-size: 0.9rem;">[${result.type}]</span></div>
<div class="result-date">
<span>Salvo em: ${result.displayDate}</span>
<button onclick="deleteResult(${result.id})" style="background: none; border: none; color: #ef4444; cursor: pointer; font-size: 0.8rem;">🗑️</button>
</div>
</div>
`).join('');
}
// Função para deletar um resultado
function deleteResult(id) {
savedResults = savedResults.filter(result => result.id !== id);
localStorage.setItem('calculatorResults', JSON.stringify(savedResults));
updateResultsList();
showNotification('Resultado excluído!');
}
// Função para limpar todos os resultados
function clearAllResults() {
if (confirm('Tem certeza que deseja apagar todos os resultados salvos?')) {
savedResults = [];
localStorage.removeItem('calculatorResults');
updateResultsList();
showNotification('Todos os resultados foram excluídos!');
}
}
// Função para exportar os resultados para JSON
function exportToJSON() {
if (savedResults.length === 0) {
alert('Nenhum resultado salvo para exportar!');
return;
}
// Criar objeto com metadados e resultados
const exportData = {
exportedAt: new Date().toISOString(),
totalResults: savedResults.length,
calculatorType: "Calculadora Científica",
results: savedResults
};
// Converter para JSON formatado
const jsonData = JSON.stringify(exportData, null, 2);
// Criar um blob com os dados
const blob = new Blob([jsonData], { type: 'application/json' });
// Criar um link para download
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `calculadora_resultados_${new Date().toISOString().slice(0, 10)}.json`;
document.body.appendChild(a);
a.click();
// Limpar
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, 100);
showNotification(`Arquivo JSON com ${savedResults.length} resultados foi baixado!`);
}
// Função para exportar os resultados para CSV
function exportToCSV() {
if (savedResults.length === 0) {
alert('Nenhum resultado salvo para exportar!');
return;
}
// Cabeçalhos do CSV
let csvContent = "ID,Expressão,Resultado,Comentário,Tipo,Data/Hora\n";
// Adicionar cada resultado
savedResults.forEach(result => {
const row = [
result.id,
`"${result.expression.replace(/"/g, '""')}"`,
result.result,
`"${result.comment.replace(/"/g, '""')}"`,
result.type,
`"${result.displayDate}"`
];
csvContent += row.join(",") + "\n";
});
// Criar blob e fazer download
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `calculadora_resultados_${new Date().toISOString().slice(0, 10)}.csv`;
document.body.appendChild(a);
a.click();
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, 100);
showNotification(`Arquivo CSV com ${savedResults.length} resultados foi baixado!`);
}
// Função para exportar os resultados para TXT
function exportToTXT() {
if (savedResults.length === 0) {
alert('Nenhum resultado salvo para exportar!');
return;
}
// Criar conteúdo do texto
let txtContent = `Resultados da Calculadora - Exportados em ${new Date().toLocaleString('pt-BR')}\n`;
txtContent += "=".repeat(60) + "\n\n";
savedResults.forEach((result, index) => {
txtContent += `Resultado ${index + 1}:\n`;
txtContent += `Expressão: ${result.expression}\n`;
txtContent += `Resultado: ${result.result}\n`;
txtContent += `Comentário: ${result.comment}\n`;
txtContent += `Tipo: ${result.type}\n`;
txtContent += `Data: ${result.displayDate}\n`;
txtContent += "-".repeat(40) + "\n\n";
});
// Criar blob e fazer download
const blob = new Blob([txtContent], { type: 'text/plain;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `calculadora_resultados_${new Date().toISOString().slice(0, 10)}.txt`;
document.body.appendChild(a);
a.click();
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, 100);
showNotification(`Arquivo TXT com ${savedResults.length} resultados foi baixado!`);
}
// Função para importar resultados de um arquivo JSON
function importFromJSON() {
const fileInput = document.getElementById('import-file');
fileInput.click();
fileInput.onchange = function(e) {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(event) {
try {
const importedData = JSON.parse(event.target.result);
if (!importedData.results || !Array.isArray(importedData.results)) {
throw new Error("Formato de arquivo inválido");
}
// Adicionar os resultados importados
importedData.results.forEach(result => {
// Adicionar um novo ID para evitar conflitos
result.id = Date.now() + Math.random();
savedResults.unshift(result);
});
// Limitar a 50 resultados
if (savedResults.length > 50) {
savedResults = savedResults.slice(0, 50);
}
// Salvar no localStorage
localStorage.setItem('calculatorResults', JSON.stringify(savedResults));
// Atualizar a lista
updateResultsList();
// Limpar o input de arquivo
fileInput.value = '';
showNotification(`${importedData.results.length} resultados importados com sucesso!`);
} catch (error) {
alert('Erro ao importar arquivo: ' + error.message);
fileInput.value = '';
}
};
reader.readAsText(file);
};
}
// Função para mostrar notificação
function showNotification(message) {
// Criar elemento de notificação
const notification = document.createElement('div');
notification.textContent = message;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #059669;
color: white;
padding: 15px 20px;
border-radius: 8px;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
z-index: 1000;
font-weight: bold;
animation: slideIn 0.3s ease-out;
`;
document.body.appendChild(notification);
// Remover após 3 segundos
setTimeout(() => {
notification.style.animation = 'slideOut 0.3s ease-in';
setTimeout(() => {
if (notification.parentNode) {
notification.parentNode.removeChild(notification);
}
}, 300);
}, 3000);
// Adicionar estilos de animação se não existirem
if (!document.querySelector('#notification-styles')) {
const style = document.createElement('style');
style.id = 'notification-styles';
style.textContent = `
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slideOut {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(100%); opacity: 0; }
}
`;
document.head.appendChild(style);
}
}
// Suporte a teclado
document.addEventListener('keydown', function(event) {
const key = event.key;
// Números
if (key >= '0' && key <= '9') {
appendToDisplay(key);
}
// Operadores básicos
else if (key === '+' || key === '-' || key === '*' || key === '/') {
appendToDisplay(key === '*' ? '×' : key);
}
// Ponto decimal
else if (key === '.' || key === ',') {
appendToDisplay('.');
}
// Parênteses
else if (key === '(' || key === ')') {
appendToDisplay(key);
}
// Enter para calcular
else if (key === 'Enter') {
event.preventDefault();
calculate();
}
// Backspace para apagar
else if (key === 'Backspace') {
backspace();
}
// Escape para limpar
else if (key === 'Escape') {
clearDisplay();
}
// Teclas para funções avançadas
else if (key === 'p' || key === 'P') {
if (event.ctrlKey) appendToDisplay('Math.PI');
}
else if (key === 'e' || key === 'E') {
if (event.ctrlKey) appendToDisplay('Math.E');
}
else if (key === 's' || key === 'S') {
if (event.ctrlKey) appendFunction('Math.sin(');
}
else if (key === 'c' || key === 'C') {
if (event.ctrlKey && !event.shiftKey) appendFunction('Math.cos(');
}
else if (key === 't' || key === 'T') {
if (event.ctrlKey) appendFunction('Math.tan(');
}
});
// Inicialização
document.addEventListener('DOMContentLoaded', function() {
updateResultsList();
updateMemoryDisplay();
// Carregar memória do localStorage se existir
const savedMemory = localStorage.getItem('calculatorMemory');
if (savedMemory) {
memory = parseFloat(savedMemory);
updateMemoryDisplay();
}
});
// Salvar memória antes de fechar a página
window.addEventListener('beforeunload', function() {
localStorage.setItem('calculatorMemory', memory.toString());
});
</script>
</body>
</html>
Comentários
Postar um comentário