Калькулятор ипотеки
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 20px;
min-height: 100vh;
}
.calculator {
max-width: 1000px;
margin: 0 auto;
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 28px;
margin-bottom: 10px;
}
.header p {
opacity: 0.9;
font-size: 14px;
}
.content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
padding: 30px;
}
.input-section {
display: flex;
flex-direction: column;
gap: 25px;
}
.input-group {
display: flex;
flex-direction: column;
gap: 10px;
}
.input-group label {
font-weight: 600;
color: #333;
font-size: 14px;
}
.input-wrapper {
position: relative;
}
.input-wrapper input {
width: 100%;
padding: 12px 50px 12px 15px;
border: 2px solid #e0e0e0;
border-radius: 10px;
font-size: 16px;
transition: all 0.3s;
}
.input-wrapper input:focus {
outline: none;
border-color: #667eea;
}
.input-wrapper .unit {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
color: #999;
font-weight: 600;
}
.slider {
width: 100%;
height: 6px;
border-radius: 5px;
background: #e0e0e0;
outline: none;
-webkit-appearance: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: #667eea;
cursor: pointer;
transition: all 0.3s;
}
.slider::-webkit-slider-thumb:hover {
transform: scale(1.2);
background: #764ba2;
}
.slider::-moz-range-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
background: #667eea;
cursor: pointer;
border: none;
transition: all 0.3s;
}
.results-section {
background: #f8f9fa;
border-radius: 15px;
padding: 25px;
display: flex;
flex-direction: column;
gap: 20px;
}
.result-card {
background: white;
padding: 20px;
border-radius: 12px;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
.result-card h3 {
font-size: 14px;
color: #666;
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.result-card .value {
font-size: 28px;
font-weight: 700;
color: #667eea;
}
.chart-container {
grid-column: 1 / -1;
background: #f8f9fa;
border-radius: 15px;
padding: 25px;
margin-top: 10px;
}
.chart-wrapper {
position: relative;
height: 300px;
}
.payment-schedule {
grid-column: 1 / -1;
margin-top: 20px;
}
.payment-schedule h2 {
color: #333;
margin-bottom: 20px;
font-size: 20px;
}
.schedule-table {
width: 100%;
border-collapse: collapse;
background: white;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
.schedule-table th {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 15px;
text-align: left;
font-weight: 600;
font-size: 13px;
}
.schedule-table td {
padding: 12px 15px;
border-bottom: 1px solid #f0f0f0;
font-size: 14px;
}
.schedule-table tr:last-child td {
border-bottom: none;
}
.schedule-table tr:hover {
background: #f8f9fa;
}
.schedule-table .highlight {
background: #fff3cd;
}
@media (max-width: 768px) {
.content {
grid-template-columns: 1fr;
}
.chart-container {
grid-column: 1;
}
.payment-schedule {
grid-column: 1;
}
.schedule-table {
font-size: 12px;
}
.schedule-table th,
.schedule-table td {
padding: 10px 8px;
}
}
График платежей (первый год)
| Месяц |
Платеж |
Основной долг |
Проценты |
Остаток |
let chart = null;
function formatCurrency(value) {
return '$' + Math.round(value).toLocaleString('en-US');
}
function calculateMortgage() {
const price = parseFloat(document.getElementById('price').value);
const downPayment = parseFloat(document.getElementById('downPayment').value);
const termYears = parseInt(document.getElementById('term').value);
const annualRate = parseFloat(document.getElementById('rate').value);
const loanAmount = price - downPayment;
const monthlyRate = annualRate / 100 / 12;
const numberOfPayments = termYears * 12;
const monthlyPayment = loanAmount *
(monthlyRate * Math.pow(1 + monthlyRate, numberOfPayments)) /
(Math.pow(1 + monthlyRate, numberOfPayments) - 1);
const totalPayment = monthlyPayment * numberOfPayments;
const totalInterest = totalPayment - loanAmount;
document.getElementById('monthlyPayment').textContent = formatCurrency(monthlyPayment);
document.getElementById('loanAmount').textContent = formatCurrency(loanAmount);
document.getElementById('totalInterest').textContent = formatCurrency(totalInterest);
document.getElementById('totalPayment').textContent = formatCurrency(totalPayment);
updateChart(loanAmount, totalInterest);
updateSchedule(loanAmount, monthlyPayment, monthlyRate, numberOfPayments);
}
function updateChart(principal, interest) {
const ctx = document.getElementById('paymentChart').getContext('2d');
if (chart) {
chart.destroy();
}
chart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Основной долг', 'Проценты'],
datasets: [{
data: [principal, interest],
backgroundColor: [
'rgba(102, 126, 234, 0.8)',
'rgba(118, 75, 162, 0.8)'
],
borderColor: [
'rgba(102, 126, 234, 1)',
'rgba(118, 75, 162, 1)'
],
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: {
padding: 20,
font: {
size: 14
}
}
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.label || '';
if (label) {
label += ': ';
}
label += formatCurrency(context.parsed);
return label;
}
}
}
}
}
});
}
function updateSchedule(loanAmount, monthlyPayment, monthlyRate, totalPayments) {
const tbody = document.getElementById('scheduleBody');
tbody.innerHTML = '';
let balance = loanAmount;
for (let month = 1; month <= Math.min(12, totalPayments); month++) {
const interestPayment = balance * monthlyRate;
const principalPayment = monthlyPayment - interestPayment;
balance -= principalPayment;
const row = tbody.insertRow();
row.innerHTML = `
${month} |
${formatCurrency(monthlyPayment)} |
${formatCurrency(principalPayment)} |
${formatCurrency(interestPayment)} |
${formatCurrency(Math.max(0, balance))} |
`;
}
}
function syncInputs(inputId, sliderId) {
const input = document.getElementById(inputId);
const slider = document.getElementById(sliderId);
input.addEventListener('input', function() {
slider.value = this.value;
if (inputId === 'price') {
const downPaymentSlider = document.getElementById('downPaymentSlider');
downPaymentSlider.max = this.value;
}
calculateMortgage();
});
slider.addEventListener('input', function() {
input.value = this.value;
if (inputId === 'price') {
const downPaymentSlider = document.getElementById('downPaymentSlider');
downPaymentSlider.max = this.value;
}
calculateMortgage();
});
}
syncInputs('price', 'priceSlider');
syncInputs('downPayment', 'downPaymentSlider');
syncInputs('term', 'termSlider');
syncInputs('rate', 'rateSlider');
calculateMortgage();