← Kapat
bmi-calculator.js
// BMI Calculator JavaScript
document.addEventListener('DOMContentLoaded', function () {
// Elements
const heightSlider = document.getElementById('bmi-heightSlider');
const heightInput = document.getElementById('bmi-heightInput');
const weightSlider = document.getElementById('bmi-weightSlider');
const weightInput = document.getElementById('bmi-weightInput');
const targetBmiSlider = document.getElementById('targetBmiSlider');
const targetBmiValue = document.getElementById('targetBmiValue');
const canvas = document.getElementById('bmiGauge');
const ctx = canvas ? canvas.getContext('2d') : null;
const faqButtons = document.querySelectorAll('.faq-button');
// Current values
let currentHeight = 170;
let currentWeight = 70;
let currentBMI = 0;
let targetBMI = 22;
// Initialize
init();
function init() {
setupEventListeners();
updateCalculations();
if (ctx) drawGauge();
updateTargetCalculations();
}
function setupEventListeners() {
// Height slider and input
if (heightSlider) {
heightSlider.addEventListener('input', function () {
currentHeight = parseInt(this.value);
if (heightInput) heightInput.value = currentHeight;
updateSliderBackground(this);
updateCalculations();
updateTargetCalculations();
});
}
if (heightInput) {
heightInput.addEventListener('input', function () {
let value = parseInt(this.value);
if (value >= 140 && value <= 220) {
currentHeight = value;
if (heightSlider) {
heightSlider.value = value;
updateSliderBackground(heightSlider);
}
updateCalculations();
updateTargetCalculations();
}
});
}
// Weight slider and input
if (weightSlider) {
weightSlider.addEventListener('input', function () {
currentWeight = parseInt(this.value);
if (weightInput) weightInput.value = currentWeight;
updateSliderBackground(this);
updateCalculations();
updateTargetCalculations();
});
}
if (weightInput) {
weightInput.addEventListener('input', function () {
let value = parseInt(this.value);
if (value >= 40 && value <= 200) {
currentWeight = value;
if (weightSlider) {
weightSlider.value = value;
updateSliderBackground(weightSlider);
}
updateCalculations();
updateTargetCalculations();
}
});
}
// Target BMI slider
if (targetBmiSlider) {
targetBmiSlider.addEventListener('input', function () {
targetBMI = parseFloat(this.value);
if (targetBmiValue) targetBmiValue.textContent = targetBMI.toFixed(1);
updateTargetSliderBackground(this);
updateTargetCalculations();
});
}
// FAQ toggles
faqButtons.forEach(button => {
button.addEventListener('click', function () {
const faqItem = this.parentElement;
const isActive = faqItem.classList.contains('active');
// Close all FAQ items
document.querySelectorAll('.faq-item').forEach(item => {
item.classList.remove('active');
});
// Toggle current item
if (!isActive) {
faqItem.classList.add('active');
}
});
});
// Initialize slider backgrounds
if (heightSlider) updateSliderBackground(heightSlider);
if (weightSlider) updateSliderBackground(weightSlider);
if (targetBmiSlider) updateTargetSliderBackground(targetBmiSlider);
}
function updateSliderBackground(slider) {
const min = parseFloat(slider.min);
const max = parseFloat(slider.max);
const value = parseFloat(slider.value);
const percentage = ((value - min) / (max - min)) * 100;
slider.style.background = `linear-gradient(to right, #ff8c00 0%, #ff8c00 ${percentage}%, #3f3f46 ${percentage}%, #3f3f46 100%)`;
}
function updateTargetSliderBackground(slider) {
const min = parseFloat(slider.min);
const max = parseFloat(slider.max);
const value = parseFloat(slider.value);
const percentage = ((value - min) / (max - min)) * 100;
slider.style.background = `linear-gradient(to right, #ff8c00 0%, #ff8c00 ${percentage}%, #3f3f46 ${percentage}%, #3f3f46 100%)`;
}
function calculateBMI(weight, height) {
const heightInMeters = height / 100;
return weight / (heightInMeters * heightInMeters);
}
function getBMICategory(bmi) {
if (bmi < 18.5) return 'underweight';
if (bmi < 25) return 'normal';
if (bmi < 30) return 'overweight';
if (bmi < 35) return 'obese1';
return 'obese2';
}
function getBMICategoryForHTML(bmi) {
if (bmi < 18.5) return 'underweight';
if (bmi < 25) return 'normal';
if (bmi < 30) return 'overweight';
return 'obese'; // HTML'de obese kategorisi var
}
function getBMICategoryColor(category) {
const colors = {
'underweight': '#3b82f6',
'normal': '#22c55e',
'overweight': '#eab308',
'obese1': '#f97316',
'obese2': '#ef4444'
};
return colors[category] || '#3b82f6';
}
function getIdealWeightRange(height) {
const heightInMeters = height / 100;
const minBMI = 18.5;
const maxBMI = 24.9;
const minWeight = minBMI * heightInMeters * heightInMeters;
const maxWeight = maxBMI * heightInMeters * heightInMeters;
return {
min: minWeight,
max: maxWeight
};
}
function getHealthScore(bmi) {
if (bmi >= 18.5 && bmi <= 24.9) return 85;
if (bmi >= 17 && bmi < 18.5) return 70;
if (bmi >= 25 && bmi < 30) return 62;
if (bmi >= 30 && bmi < 35) return 40;
if (bmi >= 35 && bmi < 40) return 25;
if (bmi >= 40 && bmi < 45) return 15;
if (bmi >= 45 && bmi < 50) return 10;
if (bmi >= 50) return 0;
if (bmi < 17) return 20;
return 5; // Diğer durumlar için
}
function getHealthStatusText(bmi) {
if (bmi >= 18.5 && bmi <= 24.9) return 'Mükemmel! Sağlıklı kilo aralığındasınız.';
if (bmi >= 17 && bmi < 18.5) return 'Hafif zayıfsınız. Dengeli beslenmeye odaklanın.';
if (bmi >= 25 && bmi < 30) return 'Fazla kilolusunuz. Sağlıklı yaşam değişiklikleri gerekli.';
if (bmi >= 30 && bmi < 35) return 'Dikkat! Sağlıklı yaşam değişiklikleri gerekli.';
if (bmi >= 35 && bmi < 40) return 'Risk altındasınız. Uzman desteği önerilir.';
if (bmi >= 40 && bmi < 45) return 'Yüksek risk! Acil tıbbi destek alın.';
if (bmi >= 45 && bmi < 50) return 'Çok yüksek risk! Derhal doktor kontrolü.';
if (bmi >= 50) return 'Kritik durum! Acil tıbbi müdahale gerekli.';
if (bmi < 17) return 'Çok zayıfsınız. Beslenme uzmanına başvurun.';
return 'Değerlendirme yapılamadı. Uzman görüşü alın.';
}
function updateCalculations() {
currentBMI = calculateBMI(currentWeight, currentHeight);
const category = getBMICategory(currentBMI);
const idealRange = getIdealWeightRange(currentHeight);
const healthScore = getHealthScore(currentBMI);
// Update BMI value in gauge
if (ctx) drawGauge();
// Update ideal weight range
const idealWeightEl = document.getElementById('idealWeight');
if (idealWeightEl) {
idealWeightEl.textContent = `${idealRange.min.toFixed(1)} - ${idealRange.max.toFixed(1)}`;
}
// Update health score
const progressFill = document.querySelector('.progress-fill');
const progressText = document.querySelector('.progress-text');
const healthStatus = document.querySelector('.health-status');
if (progressFill) {
progressFill.style.width = `${healthScore}%`;
}
if (progressText) {
progressText.textContent = `${healthScore}%`;
}
if (healthStatus) {
healthStatus.textContent = getHealthStatusText(currentBMI);
}
// Update category highlights
updateCategoryHighlights(getBMICategoryForHTML(currentBMI));
updateGaugeLabels(getBMICategoryForHTML(currentBMI));
}
function updateCategoryHighlights(category) {
const categories = document.querySelectorAll('.bmi-category');
categories.forEach(cat => {
cat.classList.remove('active');
if (cat.dataset.category === category) {
cat.classList.add('active');
}
});
}
function updateGaugeLabels(category) {
const labels = document.querySelectorAll('.gauge-label');
labels.forEach(label => {
label.classList.remove('active');
if (label.dataset.category === category) {
label.classList.add('active');
}
});
}
function updateTargetCalculations() {
const heightInMeters = currentHeight / 100;
const targetWeight = targetBMI * heightInMeters * heightInMeters;
const weightChange = targetWeight - currentWeight;
const weeksNeeded = Math.abs(weightChange) / 0.5; // 0.5 kg per week
const targetWeightEl = document.getElementById('targetWeight');
if (targetWeightEl) {
targetWeightEl.textContent = `${targetWeight.toFixed(1)} kg`;
}
const weightChangeEl = document.getElementById('weightChange');
if (weightChangeEl) {
weightChangeEl.textContent = `${weightChange >= 0 ? '+' : ''}${weightChange.toFixed(1)} kg`;
weightChangeEl.className = `target-result-value ${weightChange < 0 ? 'success' : ''}`;
}
const targetTimeEl = document.getElementById('targetTime');
if (targetTimeEl) {
targetTimeEl.textContent = `${weeksNeeded.toFixed(1)} hafta`;
}
}
function drawGauge() {
const centerX = canvas.width / 2;
const centerY = canvas.height * 0.65; // Yarım daire için Y pozisyonunu aşağı kaydır
const radius = Math.min(canvas.width, canvas.height) * 0.35;
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Create gradient
const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
gradient.addColorStop(0, '#3b82f6');
gradient.addColorStop(0.25, '#22c55e');
gradient.addColorStop(0.5, '#eab308');
gradient.addColorStop(0.75, '#f97316');
gradient.addColorStop(1, '#ef4444');
// Draw background arc
ctx.beginPath();
ctx.arc(centerX, centerY, radius + 5, Math.PI, 0, false);
ctx.lineWidth = 50;
ctx.strokeStyle = 'rgba(255,255,255,0.1)';
ctx.lineCap = 'round';
ctx.stroke();
// Draw gradient arc (background)
ctx.beginPath();
ctx.arc(centerX, centerY, radius, Math.PI, 0, false);
ctx.lineWidth = 40;
ctx.strokeStyle = gradient;
ctx.globalAlpha = 0.4;
ctx.lineCap = 'round';
ctx.stroke();
ctx.globalAlpha = 1;
// Draw scale marks and labels
drawScaleMarks(centerX, centerY, radius);
// Calculate needle angle based on BMI
const minBMI = 15;
const maxBMI = 35;
const bmiRange = maxBMI - minBMI;
const clampedBMI = Math.max(minBMI, Math.min(maxBMI, currentBMI));
const bmiPercentage = (clampedBMI - minBMI) / bmiRange;
const needleAngle = Math.PI + (bmiPercentage * Math.PI);
// Draw needle
drawNeedle(centerX, centerY, radius - 18, needleAngle);
// Draw center info
drawCenterInfo(centerX, centerY);
}
function drawScaleMarks(centerX, centerY, radius) {
const marks = [{
bmi: 15,
label: '15.0'
},
{
bmi: 17.5,
label: '17.5'
},
{
bmi: 20,
label: '20.0'
},
{
bmi: 22.5,
label: '22.5'
},
{
bmi: 25,
label: '25.0'
},
{
bmi: 27.5,
label: '27.5'
},
{
bmi: 30,
label: '30.0'
},
{
bmi: 32.5,
label: '32.5'
},
{
bmi: 35,
label: '35.0'
}
];
marks.forEach(mark => {
const angle = Math.PI + ((mark.bmi - 15) / 20) * Math.PI;
const x1 = centerX + Math.cos(angle) * (radius - 25); // Çizgi başlangıcı halkanın dışında
const y1 = centerY + Math.sin(angle) * (radius - 25);
const x2 = centerX + Math.cos(angle) * (radius + 20); // Çizgi sonu daha dışarıda
const y2 = centerY + Math.sin(angle) * (radius + 20);
const textX = centerX + Math.cos(angle) * (radius + 35); // Metin daha dışarıda
const textY = centerY + Math.sin(angle) * (radius + 35);
// Draw mark line
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.strokeStyle = 'rgba(255,255,255,0.8)';
ctx.lineWidth = 2;
ctx.stroke();
// Draw label
ctx.fillStyle = 'rgba(255,255,255,0.9)';
ctx.font = '12px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(mark.label, textX, textY);
});
}
function drawNeedle(centerX, centerY, length, angle) {
const needleColor = getBMICategoryColor(getBMICategory(currentBMI));
// Draw needle line
ctx.beginPath();
ctx.moveTo(centerX, centerY);
ctx.lineTo(
centerX + Math.cos(angle) * length,
centerY + Math.sin(angle) * length
);
ctx.strokeStyle = needleColor;
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.stroke();
// Draw needle center
ctx.beginPath();
ctx.arc(centerX, centerY, 15, 0, 2 * Math.PI);
ctx.fillStyle = needleColor;
ctx.fill();
}
function drawCenterInfo(centerX, centerY) {
// Draw background circle
ctx.beginPath();
ctx.arc(centerX, centerY, 50, 0, 2 * Math.PI);
ctx.fillStyle = 'rgba(0,0,0,0.7)';
ctx.fill();
// Draw "BMI" label
ctx.fillStyle = '#ffffff';
ctx.font = '18px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('BMI', centerX, centerY - 15);
// Draw BMI value
const bmiColor = getBMICategoryColor(getBMICategory(currentBMI));
ctx.fillStyle = bmiColor;
ctx.font = 'bold 32px Arial';
ctx.fillText(currentBMI.toFixed(1), centerX, centerY + 15);
}
});