Proje Detayları

Proje Tanımı

Bu projede, JavaScript kullanarak gerçek zamanlı hava durumu verilerini gösteren bir web uygulaması geliştireceğiz. Uygulama, kullanıcının aradığı şehir için güncel hava durumu bilgilerini ve 5 günlük tahminleri gösterecek. Bu proje, API entegrasyonu, asenkron JavaScript, DOM manipülasyonu ve responsive tasarım konularını uygulamalı olarak öğrenmenize yardımcı olacak.

Adım Adım Geliştirme

Bu bölümde, hava durumu uygulamasını adım adım nasıl geliştirebileceğinizi öğreneceksiniz. Her adımda, ilgili kod parçalarını ve açıklamalarını bulacaksınız.

Adım 1: Proje Yapısını Oluşturma

İlk olarak, projemiz için gerekli dosyaları oluşturalım:

  • index.html - Ana HTML dosyası
  • style.css - CSS stil dosyası
  • script.js - JavaScript kod dosyası
index.html
<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hava Durumu Uygulaması</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body>
    <div class="weather-app">
        <div class="weather-header">
            <h2>Hava Durumu Uygulaması</h2>
            <p>Şehir adı girerek hava durumunu öğrenin</p>
        </div>
        
        <div class="weather-error" id="weatherError">
            Şehir bulunamadı. Lütfen geçerli bir şehir adı girin.
        </div>
        
        <div class="weather-loading" id="weatherLoading">
            <i class="fas fa-spinner fa-spin"></i> Hava durumu bilgileri yükleniyor...
        </div>
        
        <div class="weather-search">
            <input type="text" id="cityInput" placeholder="Şehir adı girin..." aria-label="Şehir adı">
            <button id="searchButton"><i class="fas fa-search"></i></button>
        </div>
        
        <div class="weather-info" id="weatherInfo">
            <div class="weather-city" id="weatherCity"></div>
            <div class="weather-date" id="weatherDate"></div>
            <img src="" alt="Hava durumu ikonu" class="weather-icon" id="weatherIcon">
            <div class="weather-temp" id="weatherTemp"></div>
            <div class="weather-desc" id="weatherDesc"></div>
            
            <div class="weather-details">
                <div class="weather-detail">
                    <div class="weather-detail-label">Hissedilen</div>
                    <div class="weather-detail-value" id="weatherFeelsLike"></div>
                </div>
                <div class="weather-detail">
                    <div class="weather-detail-label">Nem</div>
                    <div class="weather-detail-value" id="weatherHumidity"></div>
                </div>
                <div class="weather-detail">
                    <div class="weather-detail-label">Rüzgar</div>
                    <div class="weather-detail-value" id="weatherWind"></div>
                </div>
            </div>
        </div>
        
        <div class="weather-forecast" id="weatherForecast">
            <div class="forecast-title">5 Günlük Tahmin</div>
            <div class="forecast-container" id="forecastContainer">
                <!-- Forecast items will be added here dynamically -->
            </div>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>
style.css
/* Genel Stiller */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #f0f2f5;
    color: #333;
    line-height: 1.6;
    padding: 20px;
}

/* Hava Durumu Uygulaması Stilleri */
.weather-app {
    max-width: 600px;
    margin: 0 auto;
    background-color: #fff;
    border-radius: 10px;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
    overflow: hidden;
}

.weather-header {
    background-color: #4caf50;
    color: white;
    padding: 20px;
    text-align: center;
}

.weather-header h2 {
    margin-bottom: 5px;
    font-size: 24px;
}

.weather-header p {
    font-size: 14px;
    opacity: 0.9;
}

.weather-search {
    display: flex;
    padding: 20px;
    background-color: #f9f9f9;
    border-bottom: 1px solid #eee;
}

.weather-search input {
    flex: 1;
    padding: 12px 15px;
    border: 1px solid #ddd;
    border-radius: 4px 0 0 4px;
    font-size: 16px;
    outline: none;
}

.weather-search input:focus {
    border-color: #4caf50;
}

.weather-search button {
    padding: 12px 20px;
    background-color: #4caf50;
    color: white;
    border: none;
    border-radius: 0 4px 4px 0;
    cursor: pointer;
    font-size: 16px;
    transition: background-color 0.3s;
}

.weather-search button:hover {
    background-color: #45a049;
}

.weather-info {
    padding: 30px;
    text-align: center;
    display: none;
}

.weather-city {
    font-size: 28px;
    font-weight: bold;
    margin-bottom: 5px;
}

.weather-date {
    color: #666;
    margin-bottom: 20px;
    font-size: 14px;
}

.weather-icon {
    width: 100px;
    height: 100px;
    margin: 0 auto 10px;
}

.weather-temp {
    font-size: 48px;
    font-weight: bold;
    margin-bottom: 10px;
}

.weather-desc {
    font-size: 18px;
    margin-bottom: 20px;
    color: #555;
    text-transform: capitalize;
}

.weather-details {
    display: flex;
    justify-content: space-around;
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid #eee;
}

.weather-detail {
    text-align: center;
}

.weather-detail-label {
    font-size: 14px;
    color: #666;
    margin-bottom: 5px;
}

.weather-detail-value {
    font-size: 18px;
    font-weight: bold;
}

.weather-error {
    color: #e74c3c;
    text-align: center;
    padding: 15px;
    background-color: #fdecea;
    border-radius: 4px;
    margin: 20px;
    display: none;
}

.weather-loading {
    text-align: center;
    padding: 30px;
    color: #666;
    display: none;
}

.weather-forecast {
    padding: 20px;
    background-color: #f9f9f9;
    display: none;
}

.forecast-title {
    font-size: 18px;
    margin-bottom: 15px;
    text-align: center;
    color: #333;
}

.forecast-container {
    display: flex;
    overflow-x: auto;
    padding-bottom: 10px;
    scrollbar-width: thin;
    scrollbar-color: #ccc #f9f9f9;
}

.forecast-container::-webkit-scrollbar {
    height: 6px;
}

.forecast-container::-webkit-scrollbar-track {
    background: #f9f9f9;
}

.forecast-container::-webkit-scrollbar-thumb {
    background-color: #ccc;
    border-radius: 6px;
}

.forecast-item {
    min-width: 120px;
    padding: 15px;
    background-color: #fff;
    border-radius: 8px;
    margin-right: 10px;
    box-shadow: 0 2px 5px rgba(0,0,0,0.1);
    text-align: center;
    flex-shrink: 0;
}

.forecast-day {
    font-weight: bold;
    margin-bottom: 10px;
    font-size: 14px;
}

.forecast-icon {
    width: 50px;
    height: 50px;
    margin: 0 auto 10px;
}

.forecast-temp {
    font-size: 18px;
    font-weight: bold;
}

.forecast-desc {
    font-size: 12px;
    color: #666;
    margin-top: 5px;
    text-transform: capitalize;
}

/* Responsive Tasarım */
@media (max-width: 768px) {
    .weather-app {
        max-width: 100%;
    }
    
    .weather-details {
        flex-direction: column;
        gap: 15px;
    }
    
    .weather-temp {
        font-size: 36px;
    }
    
    .weather-city {
        font-size: 24px;
    }
}

Adım 2: OpenWeatherMap API Anahtarı Alma

Hava durumu verilerini almak için OpenWeatherMap API'sini kullanacağız. Bunun için bir API anahtarı almanız gerekiyor:

  1. OpenWeatherMap web sitesine gidin ve ücretsiz bir hesap oluşturun.
  2. Hesabınıza giriş yaptıktan sonra, "API keys" bölümünden bir API anahtarı oluşturun.
  3. API anahtarınızın aktif hale gelmesi birkaç saat sürebilir, bu yüzden sabırlı olun.

Not: Bu projede kullanacağımız API uçları şunlardır:

  • Güncel hava durumu: https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric&lang=tr
  • 5 günlük tahmin: https://api.openweathermap.org/data/2.5/forecast?q={city}&appid={API_KEY}&units=metric&lang=tr

Adım 3: JavaScript Kodunu Yazma

Şimdi, uygulamanın işlevselliğini sağlayacak JavaScript kodunu yazalım:

script.js
// API anahtarınızı buraya ekleyin
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.openweathermap.org/data/2.5';

// DOM elementlerini seçme
const cityInput = document.getElementById('cityInput');
const searchButton = document.getElementById('searchButton');
const weatherInfo = document.getElementById('weatherInfo');
const weatherForecast = document.getElementById('weatherForecast');
const weatherError = document.getElementById('weatherError');
const weatherLoading = document.getElementById('weatherLoading');
const weatherCity = document.getElementById('weatherCity');
const weatherDate = document.getElementById('weatherDate');
const weatherIcon = document.getElementById('weatherIcon');
const weatherTemp = document.getElementById('weatherTemp');
const weatherDesc = document.getElementById('weatherDesc');
const weatherFeelsLike = document.getElementById('weatherFeelsLike');
const weatherHumidity = document.getElementById('weatherHumidity');
const weatherWind = document.getElementById('weatherWind');
const forecastContainer = document.getElementById('forecastContainer');

// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
    // LocalStorage'dan son aranan şehri al
    const lastCity = localStorage.getItem('lastCity');
    if (lastCity) {
        cityInput.value = lastCity;
        getWeather(lastCity);
    }
    
    // Arama butonuna tıklama olayı
    searchButton.addEventListener('click', () => {
        const city = cityInput.value.trim();
        if (city) {
            getWeather(city);
        }
    });
    
    // Enter tuşuna basma olayı
    cityInput.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') {
            const city = cityInput.value.trim();
            if (city) {
                getWeather(city);
            }
        }
    });
});

// Hava durumu verilerini alma fonksiyonu
async function getWeather(city) {
    try {
        // Yükleniyor durumunu göster
        showLoading();
        
        // Güncel hava durumu verilerini al
        const weatherResponse = await fetch(`${BASE_URL}/weather?q=${city}&appid=${API_KEY}&units=metric&lang=tr`);
        
        if (!weatherResponse.ok) {
            throw new Error('Şehir bulunamadı');
        }
        
        const weatherData = await weatherResponse.json();
        
        // 5 günlük tahmin verilerini al
        const forecastResponse = await fetch(`${BASE_URL}/forecast?q=${city}&appid=${API_KEY}&units=metric&lang=tr`);
        const forecastData = await forecastResponse.json();
        
        // Verileri göster
        displayWeather(weatherData);
        displayForecast(forecastData);
        
        // Son aranan şehri kaydet
        localStorage.setItem('lastCity', city);
        
        // Hata mesajını gizle
        weatherError.style.display = 'none';
    } catch (error) {
        // Hata durumunda
        console.error('Hava durumu alınamadı:', error);
        weatherInfo.style.display = 'none';
        weatherForecast.style.display = 'none';
        weatherError.style.display = 'block';
    } finally {
        // Yükleniyor durumunu gizle
        weatherLoading.style.display = 'none';
    }
}

// Güncel hava durumu verilerini gösterme fonksiyonu
function displayWeather(data) {
    // Şehir ve ülke
    weatherCity.textContent = `${data.name}, ${data.sys.country}`;
    
    // Tarih
    const date = new Date();
    const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
    weatherDate.textContent = date.toLocaleDateString('tr-TR', options);
    
    // Hava durumu ikonu
    weatherIcon.src = `https://openweathermap.org/img/wn/${data.weather[0].icon}@2x.png`;
    weatherIcon.alt = data.weather[0].description;
    
    // Sıcaklık
    weatherTemp.textContent = `${Math.round(data.main.temp)}°C`;
    
    // Hava durumu açıklaması
    weatherDesc.textContent = data.weather[0].description;
    
    // Hissedilen sıcaklık
    weatherFeelsLike.textContent = `${Math.round(data.main.feels_like)}°C`;
    
    // Nem
    weatherHumidity.textContent = `${data.main.humidity}%`;
    
    // Rüzgar
    weatherWind.textContent = `${Math.round(data.wind.speed)} km/s`;
    
    // Hava durumu bilgilerini göster
    weatherInfo.style.display = 'block';
}

// 5 günlük tahmin verilerini gösterme fonksiyonu
function displayForecast(data) {
    // Forecast container'ı temizle
    forecastContainer.innerHTML = '';
    
    // Her gün için bir tahmin öğesi oluştur (3 saatlik verilerden günlük veri oluştur)
    const dailyForecasts = {};
    
    // Verileri günlere göre grupla
    data.list.forEach(item => {
        const date = new Date(item.dt * 1000);
        const day = date.toLocaleDateString('tr-TR', { weekday: 'short' });
        
        // Her gün için sadece bir tahmin (öğlen vakti)
        if (!dailyForecasts[day] && date.getHours() >= 12 && date.getHours() <= 15) {
            dailyForecasts[day] = item;
        }
    });
    
    // Günlük tahminleri göster (en fazla 5 gün)
    Object.keys(dailyForecasts).slice(0, 5).forEach(day => {
        const forecast = dailyForecasts[day];
        const forecastItem = document.createElement('div');
        forecastItem.className = 'forecast-item';
        
        forecastItem.innerHTML = `
            ${day}
            
            ${Math.round(forecast.main.temp)}°C
            ${forecast.weather[0].description}
        `;
        
        forecastContainer.appendChild(forecastItem);
    });
    
    // Tahmin bölümünü göster
    weatherForecast.style.display = 'block';
}

// Yükleniyor durumunu gösterme fonksiyonu
function showLoading() {
    weatherLoading.style.display = 'block';
    weatherInfo.style.display = 'none';
    weatherForecast.style.display = 'none';
    weatherError.style.display = 'none';
}

Uyarı: Yukarıdaki kodda YOUR_API_KEY yerine kendi API anahtarınızı eklemeyi unutmayın. Gerçek bir uygulamada, API anahtarınızı doğrudan istemci tarafı kodunda saklamak güvenli değildir. Üretim ortamında, API anahtarınızı bir sunucu tarafı proxy'si aracılığıyla kullanmalısınız.

Adım 4: Uygulamayı Test Etme

Şimdi uygulamanızı test etme zamanı! Aşağıdaki adımları izleyin:

  1. Tüm dosyaları (index.htmlstyle.cssscript.js) aynı klasöre kaydedin.
  2. script.js dosyasında YOUR_API_KEY yerine kendi API anahtarınızı ekleyin.
  3. HTML dosyasını bir web tarayıcısında açın.
  4. Arama kutusuna bir şehir adı girin (örneğin, "İstanbul") ve ara butonuna tıklayın veya Enter tuşuna basın.
  5. Hava durumu bilgilerinin ve 5 günlük tahminlerin görüntülendiğini doğrulayın.

İpucu: Eğer API anahtarınız henüz aktif değilse, OpenWeatherMap'in aktifleştirmesi için birkaç saat beklemeniz gerekebilir. Bu süre zarfında, uygulamanızın tasarımını ve kullanıcı arayüzünü geliştirmeye devam edebilirsiniz.

Projeyi Geliştirme

Temel hava durumu uygulamasını başarıyla oluşturduktan sonra, aşağıdaki özelliklerle projenizi geliştirebilirsiniz:

1. Konum Tabanlı Hava Durumu

Kullanıcının mevcut konumunu kullanarak otomatik olarak hava durumu bilgilerini gösterebilirsiniz. Bunun için Geolocation API'sini kullanabilirsiniz:

geolocation.js
// Konum butonunu HTML'e ekleyin
// <button id="locationButton"><i class="fas fa-map-marker-alt"></i></button>

// Konum butonunu seç
const locationButton = document.getElementById('locationButton');

// Konum butonuna tıklama olayı
locationButton.addEventListener('click', () => {
    if (navigator.geolocation) {
        weatherLoading.style.display = 'block';
        navigator.geolocation.getCurrentPosition(
            (position) => {
                // Konum başarıyla alındı
                const lat = position.coords.latitude;
                const lon = position.coords.longitude;
                getWeatherByCoords(lat, lon);
            },
            (error) => {
                // Konum alınamadı
                console.error('Konum alınamadı:', error);
                weatherLoading.style.display = 'none';
                weatherError.textContent = 'Konum alınamadı. Lütfen manuel olarak şehir girin.';
                weatherError.style.display = 'block';
            }
        );
    } else {
        // Tarayıcı geolocation'ı desteklemiyor
        weatherError.textContent = 'Tarayıcınız konum hizmetlerini desteklemiyor.';
        weatherError.style.display = 'block';
    }
});

// Koordinatlara göre hava durumu alma fonksiyonu
async function getWeatherByCoords(lat, lon) {
    try {
        // Güncel hava durumu verilerini al
        const weatherResponse = await fetch(`${BASE_URL}/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric&lang=tr`);
        
        if (!weatherResponse.ok) {
            throw new Error('Hava durumu verileri alınamadı');
        }
        
        const weatherData = await weatherResponse.json();
        
        // 5 günlük tahmin verilerini al
        const forecastResponse = await fetch(`${BASE_URL}/forecast?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric&lang=tr`);
        const forecastData = await forecastResponse.json();
        
        // Verileri göster
        displayWeather(weatherData);
        displayForecast(forecastData);
        
        // Şehir adını input'a ekle
        cityInput.value = weatherData.name;
        
        // Son aranan şehri kaydet
        localStorage.setItem('lastCity', weatherData.name);
        
        // Hata mesajını gizle
        weatherError.style.display = 'none';
    } catch (error) {
        console.error('Hava durumu alınamadı:', error);
        weatherError.textContent = 'Hava durumu verileri alınamadı.';
        weatherError.style.display = 'block';
    } finally {
        weatherLoading.style.display = 'none';
    }
}

2. Tema Değiştirme Özelliği

Kullanıcıların açık ve koyu tema arasında geçiş yapabilmesini sağlayabilirsiniz:

theme.js
// Tema değiştirme butonunu HTML'e ekleyin
// <button id="themeToggle"><i class="fas fa-moon"></i></button>

// Tema değiştirme butonunu seç
const themeToggle = document.getElementById('themeToggle');
const themeIcon = themeToggle.querySelector('i');

// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
    // LocalStorage'dan tema tercihini al
    const darkMode = localStorage.getItem('darkMode') === 'true';
    
    // Tema tercihini uygula
    if (darkMode) {
        document.body.classList.add('dark-mode');
        themeIcon.classList.remove('fa-moon');
        themeIcon.classList.add('fa-sun');
    }
});

// Tema değiştirme butonuna tıklama olayı
themeToggle.addEventListener('click', () => {
    // Tema değiştir
    document.body.classList.toggle('dark-mode');
    
    // İkonu güncelle
    if (document.body.classList.contains('dark-mode')) {
        themeIcon.classList.remove('fa-moon');
        themeIcon.classList.add('fa-sun');
        localStorage.setItem('darkMode', 'true');
    } else {
        themeIcon.classList.remove('fa-sun');
        themeIcon.classList.add('fa-moon');
        localStorage.setItem('darkMode', 'false');
    }
});

Ayrıca, CSS dosyanıza koyu tema için gerekli stilleri eklemelisiniz:

dark-theme.css
/* Koyu Tema Stilleri */
body.dark-mode {
    background-color: #1a1a1a;
    color: #f0f0f0;
}

body.dark-mode .weather-app {
    background-color: #2d2d2d;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
}

body.dark-mode .weather-header {
    background-color: #3a7a3d;
}

body.dark-mode .weather-search {
    background-color: #222;
    border-bottom: 1px solid #333;
}

body.dark-mode .weather-search input {
    background-color: #333;
    border: 1px solid #444;
    color: #f0f0f0;
}

body.dark-mode .weather-info {
    color: #f0f0f0;
}

body.dark-mode .weather-date {
    color: #aaa;
}

body.dark-mode .weather-desc {
    color: #ccc;
}

body.dark-mode .weather-details {
    border-top: 1px solid #333;
}

body.dark-mode .weather-detail-label {
    color: #aaa;
}

body.dark-mode .weather-forecast {
    background-color: #222;
}

body.dark-mode .forecast-title {
    color: #f0f0f0;
}

body.dark-mode .forecast-item {
    background-color: #2d2d2d;
    box-shadow: 0 2px 5px rgba(0,0,0,0.3);
}

body.dark-mode .forecast-desc {
    color: #aaa;
}

3. Sıcaklık Birimi Değiştirme

Kullanıcıların Celsius ve Fahrenheit arasında geçiş yapabilmesini sağlayabilirsiniz:

temperature-unit.js
// Sıcaklık birimi değiştirme butonunu HTML'e ekleyin
// <button id="unitToggle">°C / °F</button>

// Sıcaklık birimi değiştirme butonunu seç
const unitToggle = document.getElementById('unitToggle');

// Sıcaklık verilerini saklamak için global değişkenler
let currentTemp = 0;
let currentFeelsLike = 0;
let forecastTemps = [];
let isCelsius = true;

// Sıcaklık birimi değiştirme butonuna tıklama olayı
unitToggle.addEventListener('click', () => {
    isCelsius = !isCelsius;
    updateTemperatureDisplay();
    
    // Tercihi kaydet
    localStorage.setItem('isCelsius', isCelsius.toString());
});

// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
    // LocalStorage'dan sıcaklık birimi tercihini al
    isCelsius = localStorage.getItem('isCelsius') !== 'false';
});

// Güncel hava durumu verilerini gösterme fonksiyonunu güncelle
function displayWeather(data) {
    // ... diğer kodlar ...
    
    // Sıcaklık verilerini sakla
    currentTemp = data.main.temp;
    currentFeelsLike = data.main.feels_like;
    
    // Sıcaklık birimini güncelle
    updateTemperatureDisplay();
    
    // ... diğer kodlar ...
}

// 5 günlük tahmin verilerini gösterme fonksiyonunu güncelle
function displayForecast(data) {
    // ... diğer kodlar ...
    
    // Tahmin sıcaklıklarını sakla
    forecastTemps = [];
    
    Object.keys(dailyForecasts).slice(0, 5).forEach(day => {
        const forecast = dailyForecasts[day];
        forecastTemps.push(forecast.main.temp);
        
        // ... diğer kodlar ...
    });
    
    // Sıcaklık birimini güncelle
    updateTemperatureDisplay();
    
    // ... diğer kodlar ...
}

// Sıcaklık gösterimini güncelleme fonksiyonu
function updateTemperatureDisplay() {
    if (weatherInfo.style.display === 'block') {
        // Ana sıcaklık
        const tempValue = isCelsius ? currentTemp : celsiusToFahrenheit(currentTemp);
        weatherTemp.textContent = `${Math.round(tempValue)}${isCelsius ? '°C' : '°F'}`;
        
        // Hissedilen sıcaklık
        const feelsLikeValue = isCelsius ? currentFeelsLike : celsiusToFahrenheit(currentFeelsLike);
        weatherFeelsLike.textContent = `${Math.round(feelsLikeValue)}${isCelsius ? '°C' : '°F'}`;
    }
    
    if (weatherForecast.style.display === 'block') {
        // Tahmin sıcaklıkları
        const forecastItems = forecastContainer.querySelectorAll('.forecast-item');
        forecastItems.forEach((item, index) => {
            if (index < forecastTemps.length) {
                const tempElement = item.querySelector('.forecast-temp');
                const tempValue = isCelsius ? forecastTemps[index] : celsiusToFahrenheit(forecastTemps[index]);
                tempElement.textContent = `${Math.round(tempValue)}${isCelsius ? '°C' : '°F'}`;
            }
        });
    }
}

// Celsius'tan Fahrenheit'a dönüştürme fonksiyonu
function celsiusToFahrenheit(celsius) {
    return (celsius * 9/5) + 32;
}

4. Hava Durumuna Göre Arka Plan Değiştirme

Hava durumuna göre uygulamanın arka planını değiştirebilirsiniz:

background.js
// Hava durumuna göre arka plan değiştirme fonksiyonu
function setWeatherBackground(weatherCode) {
    const weatherApp = document.querySelector('.weather-app');
    
    // Hava durumu koduna göre arka plan rengini belirle
    // OpenWeatherMap hava durumu kodları: https://openweathermap.org/weather-conditions
    
    // Ana gruplar:
    // 2xx: Thunderstorm (Gök gürültülü fırtına)
    // 3xx: Drizzle (Çisenti)
    // 5xx: Rain (Yağmur)
    // 6xx: Snow (Kar)
    // 7xx: Atmosphere (Sis, pus, vb.)
    // 800: Clear (Açık)
    // 80x: Clouds (Bulutlu)
    
    const group = Math.floor(weatherCode / 100);
    
    switch (group) {
        case 2: // Thunderstorm
            weatherApp.style.background = 'linear-gradient(to bottom, #2c3e50, #4c5c68)';
            break;
        case 3: // Drizzle
        case 5: // Rain
            weatherApp.style.background = 'linear-gradient(to bottom, #3498db, #2c3e50)';
            break;
        case 6: // Snow
            weatherApp.style.background = 'linear-gradient(to bottom, #e0e0e0, #b3b3b3)';
            break;
        case 7: // Atmosphere
            weatherApp.style.background = 'linear-gradient(to bottom, #95a5a6, #7f8c8d)';
            break;
        case 8: // Clear or Clouds
            if (weatherCode === 800) {
                // Clear
                weatherApp.style.background = 'linear-gradient(to bottom, #2980b9, #6dd5fa)';
            } else {
                // Clouds
                weatherApp.style.background = 'linear-gradient(to bottom, #bdc3c7, #2c3e50)';
            }
            break;
        default:
            weatherApp.style.background = 'linear-gradient(to bottom, #4caf50, #2c3e50)';
    }
}

// Güncel hava durumu verilerini gösterme fonksiyonunu güncelle
function displayWeather(data) {
    // ... diğer kodlar ...
    
    // Hava durumuna göre arka planı değiştir
    setWeatherBackground(data.weather[0].id);
    
    // ... diğer kodlar ...
}

Geliştirme Zorlukları

Hava durumu uygulamanızı daha da geliştirmek için aşağıdaki zorlukları deneyebilirsiniz:

  1. Hava Durumu Grafikleri: Chart.js gibi bir kütüphane kullanarak, sıcaklık, nem ve rüzgar hızı değişimlerini gösteren grafikler ekleyin.
  2. Çoklu Şehir Desteği: Kullanıcıların birden fazla şehir ekleyebilmesini ve aralarında geçiş yapabilmesini sağlayın.
  3. Hava Durumu Bildirimleri: Kullanıcıların belirli hava koşulları için bildirim alabilmesini sağlayın (örneğin, yağmur yağacağında).
  4. Hava Durumu Haritası: Leaflet.js gibi bir kütüphane kullanarak, hava durumu verilerini bir harita üzerinde gösterin.
  5. Hava Kalitesi Verileri: OpenWeatherMap'in Air Pollution API'sini kullanarak, hava kalitesi verilerini de gösterin.

Sonuç ve Öğrenilen Dersler

Bu projede, JavaScript kullanarak gerçek zamanlı hava durumu verilerini gösteren bir web uygulaması geliştirdik. Bu süreçte şunları öğrendik:

  • Fetch API kullanarak harici bir API'den veri almayı
  • Asenkron JavaScript (async/await) ile çalışmayı
  • JSON verilerini işlemeyi ve DOM'a entegre etmeyi
  • Kullanıcı girdilerini işlemeyi ve form doğrulaması yapmayı
  • Hata yönetimi ve kullanıcı geri bildirimi sağlamayı
  • LocalStorage kullanarak kullanıcı tercihlerini kaydetmeyi
  • Responsive tasarım ilkelerini uygulamayı

Bu proje, modern web geliştirme becerilerinizi geliştirmenize ve gerçek dünya uygulamaları oluşturmanıza yardımcı olacak temel bilgileri sağlamıştır. Öğrendiğiniz teknikleri ve kavramları kullanarak, daha karmaşık ve özelleştirilmiş web uygulamaları geliştirebilirsiniz.