← 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);
    }
});