Calculadora de Juros para Financiamento

Calculadora de Juros para Financiamento
:root{ –bg:#f7fafc; –card:#ffffff; –muted:#4a5568; –text:#1a202c; –primary:#16a34a; /* verde do botão */ –primary-weak:#dcfce7; /* foco/hover verde suave */ –border:#e2e8f0; –danger:#dc2626; } *{box-sizing:border-box} html{scroll-behavior:smooth} body{ margin:0; font-family: system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,”Helvetica Neue”,Arial; background:var(–bg); color:var(–text); line-height:1.45; -webkit-text-size-adjust:100%; } .wrap{max-width:1100px;margin:24px auto;padding:0 16px} header h1{margin:0 0 6px;font-size:clamp(22px,3vw,32px)} header p{margin:0 0 18px;color:var(–muted)} /* ===== Layout base ===== */ .grid{display:grid;grid-template-columns:1fr 1fr;gap:16px} @media (max-width: 980px){ .grid{grid-template-columns:1fr} } .card{ background:var(–card); border:1px solid var(–border); border-radius:16px; padding:18px; box-shadow:0 6px 18px rgba(0,0,0,.04); } label{font-size:14px;color:var(–muted);display:block;margin-bottom:6px} input[type=”text”],input[type=”number”],select{ width:100%; border:1px solid var(–border); background:#fff;color:var(–text); border-radius:12px; padding:12px 14px; font-size:16px;outline:none; min-height:44px; } input:focus,select:focus{ border-color:var(–primary); box-shadow:0 0 0 3px var(–primary-weak); } .error{ border-color: var(–danger) !important; box-shadow: 0 0 0 3px rgba(220,38,38,.15) !important; } .err-msg{ font-size:12px; color: var(–danger); margin-top:6px; min-height:1.2em; } .hint{font-size:12px;color:var(–muted);margin-top:4px} /* ===== Linhas do formulário ===== */ .row { display: grid; gap: 16px; margin-bottom: 16px; align-items: end; } .row–2 { grid-template-columns: 1fr 1fr; } .row–tax-prazo { grid-template-columns: 2fr 1fr 2fr 1fr; } .row–2b { grid-template-columns: 2fr 1fr; } /* ===== Responsividade ===== */ @media (max-width: 980px) { .row–2, .row–2b, .row–tax-prazo { grid-template-columns: 1fr; } } @media (max-width: 640px) { .actions a { width: 100%; text-align:center; } } /* ===== Links no lugar dos botões ===== */ .actions{ display:flex; gap:10px; flex-wrap:wrap; } .actions a{ display:inline-block; text-decoration:none; border-radius:14px; padding:14px 18px; font-weight:800; transition:.15s transform ease,.15s box-shadow ease,.15s background-color ease; } #btnCalcular{ background:var(–primary);color:#fff; box-shadow:0 6px 14px rgba(22,163,74,.18); } #btnCalcular:hover{transform:translateY(-1px)} #btnCalcular:focus{box-shadow:0 0 0 4px var(–primary-weak)} #btnCalcular .sub{ display:block;font-weight:600;opacity:.9;font-size:12px;line-height:1.1;margin-top:2px } .actions a.secondary{ background:#fff;color:var(–primary);border:1px solid var(–primary);font-weight:700; } .actions a.secondary:hover{background:#f8fff9} /* ===== Resultados ===== */ .result-header{ display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap; } .badge{font-size:12px;padding:2px 8px;border-radius:999px;border:1px solid var(–border);color:var(–muted);background:#fff} .tabs{display:flex;gap:6px;background:#f1f5f9;padding:4px;border-radius:999px;border:1px solid var(–border)} .tab{padding:8px 14px;border-radius:999px;cursor:pointer;font-weight:700;border:1px solid transparent} .tab.active{background:#fff;border-color:var(–border);box-shadow:0 2px 6px rgba(0,0,0,.05)} @media (max-width:480px){ .tabs{width:100%;justify-content:space-between} .tab{flex:1;text-align:center} } .kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:14px} @media (max-width:900px){.kpis{grid-template-columns:1fr 1fr}} @media (max-width:480px){.kpis{grid-template-columns:1fr}} .kpi{border:1px solid var(–border);border-radius:14px;padding:12px;background:#fff} .kpi .title{font-size:12px;color:var(–muted)} .kpi .value{font-size:clamp(18px,3vw,22px);font-weight:800;margin-top:4px} table{width:100%;border-collapse:collapse;margin-top:14px;font-size:14px} thead th{ text-align:left;background:#f8fafc;border-bottom:1px solid var(–border);padding:10px; position:sticky;top:0;z-index:1; } tbody td{border-bottom:1px solid var(–border);padding:8px 10px} .scroll{max-height:360px;overflow:auto;border:1px solid var(–border);border-radius:12px;background:#fff} .footer-note{font-size:12px;color:var(–muted);margin-top:10px} .tag{font-size:11px;background:#ecfeff;color:#155e75;padding:2px 8px;border-radius:999px;border:1px solid #a5f3fc} .muted{color:var(–muted)} @media (prefers-reduced-motion: reduce){ *{animation:none !important;transition:none !important;scroll-behavior:auto !important} }

Simule parcelas de financiamento imobiliário ou financiamento de veículos pelos sistemas Price (parcela fixa) e SAC (amortização constante). Informe os dados abaixo e clique em CALCULAR.

Formulário de Simulação

Aceita 350000, 350.000,00 ou 350,000.00
ao mês (a.m.) ao ano (a.a.)
meses anos
Ex.: MIP/DFI, tarifa mensal, etc. Somado à parcela.
Price SAC
Resultados
Parcela inicial
Total pago
Juros totais
Prazo
# Parcela Juros Amortização Seguro/Taxas Parcela + Taxas Saldo Devedor
fBR.format(v||0); // Parser de moeda super tolerante function parseMoeda(str){ if (str == null) return 0; let s = String(str) .replace(/\u00A0/g, ‘ ‘) .replace(/R\$\s?/gi, ”) .replace(/\s+/g, ”) .trim(); if (!s) return 0; const hasComma = s.includes(‘,’); const hasDot = s.includes(‘.’); if (hasComma && hasDot){ const lastComma = s.lastIndexOf(‘,’); const lastDot = s.lastIndexOf(‘.’); const decSep = lastComma > lastDot ? ‘,’ : ‘.’; const thouSep = decSep === ‘,’ ? ‘.’ : ‘,’; s = s.replace(new RegExp(‘\\’ + thouSep, ‘g’), ”).replace(decSep, ‘.’); return parseFloat(s) || 0; } if (hasComma){ return parseFloat(s.replace(/\./g, ”).replace(‘,’, ‘.’)) || 0; } if (hasDot){ const parts = s.split(‘.’); const last = parts[parts.length – 1]; if (parts.length > 1 && last.length === 3) { s = s.replace(/\./g, ”); return parseFloat(s) || 0; } return parseFloat(s) || 0; } return parseFloat(s) || 0; } function toMoedaInput(el){ if(!el) return; el.addEventListener(‘blur’,()=>{ const v = parseMoeda(el.value); el.value = v ? fmt(v) : ”; }); } // Liga formatação de moeda [‘valor’,’entrada’,’seguro’].forEach(id=>toMoedaInput(document.getElementById(id))); // ===== Cálculos ===== function taxaMensal(taxa,tipo){ const i = (taxa||0)/100; return (tipo===’a.a.’) ? Math.pow(1+i,1/12)-1 : i; } function calcPrice(P,i,n,add=0){ const A = (i>0)? (P*i*Math.pow(1+i,n))/(Math.pow(1+i,n)-1) : (P/n); let saldo=P,totalPago=0,totalJuros=0; const rows=[]; for (let k=1;k<=n;k++){ const juros = saldo*i; const amort = A-juros; saldo = Math.max(0,saldo-amort); const parcelaComTaxas = A+add; totalPago += parcelaComTaxas; totalJuros += juros; rows.push({k,parcela:A,juros,amort,add,total:parcelaComTaxas,saldo}); } return {parcela:A,totalPago,totalJuros,rows}; } function calcSAC(P,i,n,add=0){ const amortConst = P/n; let saldo=P,totalPago=0,totalJuros=0; const rows=[]; for (let k=1;ksetFieldError(id,”)); } let cache=null; function calcular(){ clearErrors(); const V = parseMoeda(document.getElementById(‘valor’).value); const E = parseMoeda(document.getElementById(‘entrada’).value); const add = parseMoeda(document.getElementById(‘seguro’).value) || 0; const taxa = parseFloat(String(document.getElementById(‘taxa’).value).replace(‘,’,’.’)) || 0; const taxaTipo = document.getElementById(‘taxaTipo’).value; const prazoRaw = String(document.getElementById(‘prazo’).value || ”); const prazoNum = parseInt(prazoRaw.replace(/[^\d]/g,”),10) || 0; const prazoTipo = document.getElementById(‘prazoTipo’).value; const n = (prazoTipo===’anos’) ? prazoNum*12 : prazoNum; // validações let hasErr = false; if (!V || V<=0){ setFieldError('valor','Informe um valor do bem válido (ex.: 350.000,00).'); hasErr = true; } if (!n || n0?’ • Com taxas mensais’:”}`; tbody.innerHTML=”; R.rows.forEach(row=>{ const tr=document.createElement(‘tr’); tr.innerHTML = ` ${row.k} ${fmt(row.parcela)} ${fmt(row.juros)} ${fmt(row.amort)} ${fmt(row.add)} ${fmt(row.total)} ${fmt(row.saldo)} `; tbody.appendChild(tr); }); tblWrap.style.display=’block’; nota.style.display=’block’; } // ===== Tabs ===== function setTab(tab){ currentTab=tab; tabPrice.classList.toggle(‘active’,tab===’price’); tabSAC.classList.toggle(‘active’,tab===’sac’); render(); } tabPrice.addEventListener(‘click’,()=>setTab(‘price’)); tabSAC.addEventListener(‘click’,()=>setTab(‘sac’)); document.getElementById(‘tabelaInicial’).addEventListener(‘change’,(e)=>setTab(e.target.value)); // ===== Limpar ===== function limpar(){ [‘valor’,’entrada’,’seguro’,’taxa’,’prazo’].forEach(id=>document.getElementById(id).value=”); document.getElementById(‘taxaTipo’).value=’a.m.’; document.getElementById(‘prazoTipo’).value=’meses’; document.getElementById(‘tabelaInicial’).value=’price’; setTab(‘price’); cache=null; tbody.innerHTML=”; [‘kParcela’,’kTotalPago’,’kJuros’,’kPrazo’].forEach(id=>document.getElementById(id).textContent=’—’); resResumo.textContent=”; document.getElementById(‘tblWrap’).style.display=’none’; document.getElementById(‘nota’).style.display=’none’; clearErrors(); // também limpa a URL history.replaceState({}, ”, location.pathname); } // ===== Exportar CSV (tabela visível) ===== function exportCSV(){ if(!cache){ alert(‘Faça uma simulação antes de exportar.’); return; } const {rPrice, rSAC, add, V, E, taxa, taxaTipo, n} = cache; const tabela = (currentTab===’price’) ? ‘Price’ : ‘SAC’; const R = (currentTab===’price’) ? rPrice : rSAC; const header = [ ‘Parâmetro’,’Valor’, ‘Tabela’,tabela, ‘Valor do bem’, V, ‘Entrada’, E||0, `Taxa (${taxaTipo})`, taxa, ‘Prazo (meses)’, n, ‘Seguros/Taxas mensais’, add ]; const rows = R.rows.map(r=>[ r.k, r.parcela.toFixed(2), r.juros.toFixed(2), r.amort.toFixed(2), r.add.toFixed(2), r.total.toFixed(2), r.saldo.toFixed(2) ]); const csv = [ ‘Resumo,’, …chunk(header,2).map(([k,v])=>`${k},${v}`), ”, ‘Parcela #,Parcela,Juros,Amortização,Seguro/Taxas,Parcela + Taxas,Saldo Devedor’, …rows.map(r=>r.join(‘,’)), ”, `Totais,,`, `Total pago,${R.totalPago.toFixed(2)}`, `Juros totais,${R.totalJuros.toFixed(2)}` ].join(‘\n’); const blob = new Blob([csv],{type:’text/csv;charset=utf-8;’}); const url = URL.createObjectURL(blob); const a = document.createElement(‘a’); a.href = url; const stamp = new Date().toISOString().slice(0,19).replace(/[:T]/g,’-‘); a.download = `simulacao-${tabela.toLowerCase()}-${stamp}.csv`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } function chunk(arr,size){ const out=[]; for(let i=0;i{ const el = document.getElementById(id); if(!el) return; if(formatMoney) el.value = v ? fmt(Number(v)) : ”; else el.value = (v ?? ”); }; setVal(‘valor’, q.get(‘valor’), true); setVal(‘entrada’, q.get(‘entrada’), true); setVal(‘seguro’, q.get(‘seguro’), true); setVal(‘taxa’, q.get(‘taxa’)); const taxaTipo = q.get(‘taxaTipo’); if(taxaTipo) document.getElementById(‘taxaTipo’).value = taxaTipo; setVal(‘prazo’, q.get(‘prazo’)); const prazoTipo = q.get(‘prazoTipo’); if(prazoTipo) document.getElementById(‘prazoTipo’).value = prazoTipo; const tabela = q.get(‘tabela’); if(tabela) document.getElementById(‘tabelaInicial’).value = tabela; // calcula e ativa a aba solicitada (se houver) calcular(); const tab = (q.get(‘tab’) || ”).toLowerCase(); if(tab === ‘sac’) setTab(‘sac’); else setTab(‘price’); } // ===== Eventos (links com preventDefault) ===== document.getElementById(‘btnCalcular’).addEventListener(‘click’,(e)=>{ e.preventDefault(); calcular(); }); document.getElementById(‘btnCSV’).addEventListener(‘click’,(e)=>{ e.preventDefault(); exportCSV(); }); document.getElementById(‘btnShare’).addEventListener(‘click’,(e)=>{ e.preventDefault(); shareLink(); }); document.getElementById(‘btnLimpar’).addEventListener(‘click’,(e)=>{ e.preventDefault(); limpar(); }); // Enter para calcular quando focado nos campos principais document.addEventListener(‘keydown’,(e)=>{ if(e.key===’Enter’){ const ids=[‘valor’,’entrada’,’seguro’,’taxa’,’prazo’]; const active=document.activeElement; if(active && ids.includes(active.id)){ e.preventDefault(); calcular(); } } }); // Inicializa a partir da URL (se houver parâmetros) applyFromURL(); })(); //–>