Optimize landscape layout: 4-column grid, transport icons, improved sizing and spacing
This commit is contained in:
102
weather.js
102
weather.js
@@ -131,11 +131,13 @@ class WeatherManager {
|
||||
* Process current weather data from API response
|
||||
*/
|
||||
processCurrentWeather(data) {
|
||||
const iconCode = data.weather[0].icon;
|
||||
return {
|
||||
temperature: Math.round(data.main.temp * 10) / 10, // Round to 1 decimal place
|
||||
condition: data.weather[0].main,
|
||||
description: data.weather[0].description,
|
||||
icon: this.getWeatherIconUrl(data.weather[0].icon),
|
||||
icon: this.getWeatherIconUrl(iconCode),
|
||||
iconCode: iconCode, // Store icon code for classification
|
||||
wind: {
|
||||
speed: Math.round(data.wind.speed * 3.6), // Convert m/s to km/h
|
||||
direction: data.wind.deg
|
||||
@@ -155,11 +157,13 @@ class WeatherManager {
|
||||
processForecast(data) {
|
||||
// Get the next 7 forecasts (covering about 24 hours)
|
||||
return data.list.slice(0, 7).map(item => {
|
||||
const iconCode = item.weather[0].icon;
|
||||
return {
|
||||
temperature: Math.round(item.main.temp * 10) / 10,
|
||||
condition: item.weather[0].main,
|
||||
description: item.weather[0].description,
|
||||
icon: this.getWeatherIconUrl(item.weather[0].icon),
|
||||
icon: this.getWeatherIconUrl(iconCode),
|
||||
iconCode: iconCode, // Store icon code for classification
|
||||
timestamp: new Date(item.dt * 1000),
|
||||
precipitation: item.rain ? (item.rain['3h'] || 0) : 0
|
||||
};
|
||||
@@ -173,6 +177,42 @@ class WeatherManager {
|
||||
return `https://openweathermap.org/img/wn/${iconCode}@2x.png`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if icon represents sun (even behind clouds)
|
||||
*/
|
||||
isSunIcon(iconCode, condition) {
|
||||
// Icon codes: 01d, 01n = clear, 02d, 02n = few clouds, 03d, 03n = scattered, 04d, 04n = broken clouds
|
||||
const sunIconCodes = ['01d', '01n', '02d', '02n', '03d', '03n', '04d', '04n'];
|
||||
return sunIconCodes.includes(iconCode) ||
|
||||
condition.includes('Clear') ||
|
||||
condition.includes('Clouds');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if icon is clear sun (no clouds)
|
||||
*/
|
||||
isClearSun(iconCode, condition) {
|
||||
const clearIconCodes = ['01d', '01n'];
|
||||
return clearIconCodes.includes(iconCode) || condition === 'Clear';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if icon is sun behind clouds
|
||||
*/
|
||||
isSunBehindClouds(iconCode, condition) {
|
||||
const cloudIconCodes = ['02d', '02n', '03d', '03n', '04d', '04n'];
|
||||
return cloudIconCodes.includes(iconCode) || (condition.includes('Clouds') && !condition.includes('Clear'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if icon represents snow
|
||||
*/
|
||||
isSnowIcon(iconCode, condition) {
|
||||
// Icon code: 13d, 13n = snow
|
||||
const snowIconCodes = ['13d', '13n'];
|
||||
return snowIconCodes.includes(iconCode) || condition.includes('Snow');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create default weather data for fallback
|
||||
*/
|
||||
@@ -182,6 +222,7 @@ class WeatherManager {
|
||||
condition: 'Clear',
|
||||
description: 'clear sky',
|
||||
icon: 'https://openweathermap.org/img/wn/01d@2x.png',
|
||||
iconCode: '01d',
|
||||
wind: {
|
||||
speed: 14.8,
|
||||
direction: 270
|
||||
@@ -209,9 +250,10 @@ class WeatherManager {
|
||||
|
||||
forecasts.push({
|
||||
temperature: 7.1 - (i * 0.3), // Decrease temperature slightly each hour
|
||||
condition: i < 2 ? 'Clear' : 'Partly Cloudy',
|
||||
condition: i < 2 ? 'Clear' : 'Clouds',
|
||||
description: i < 2 ? 'clear sky' : 'few clouds',
|
||||
icon: i < 2 ? 'https://openweathermap.org/img/wn/01n@2x.png' : 'https://openweathermap.org/img/wn/02n@2x.png',
|
||||
iconCode: i < 2 ? '01n' : '02n',
|
||||
timestamp: forecastTime,
|
||||
precipitation: 0
|
||||
});
|
||||
@@ -242,6 +284,18 @@ class WeatherManager {
|
||||
if (iconElement) {
|
||||
iconElement.src = this.weatherData.icon;
|
||||
iconElement.alt = this.weatherData.description;
|
||||
// Add classes and data attributes for color filtering
|
||||
iconElement.setAttribute('data-condition', this.weatherData.condition);
|
||||
iconElement.classList.remove('weather-sun', 'weather-snow', 'weather-clear-sun', 'weather-clouds-sun');
|
||||
if (this.isSnowIcon(this.weatherData.iconCode, this.weatherData.condition)) {
|
||||
iconElement.classList.add('weather-snow');
|
||||
} else if (this.isClearSun(this.weatherData.iconCode, this.weatherData.condition)) {
|
||||
iconElement.classList.add('weather-sun', 'weather-clear-sun');
|
||||
} else if (this.isSunBehindClouds(this.weatherData.iconCode, this.weatherData.condition)) {
|
||||
iconElement.classList.add('weather-sun', 'weather-clouds-sun');
|
||||
} else if (this.isSunIcon(this.weatherData.iconCode, this.weatherData.condition)) {
|
||||
iconElement.classList.add('weather-sun');
|
||||
}
|
||||
}
|
||||
|
||||
const temperatureElement = document.querySelector('#custom-weather .temperature');
|
||||
@@ -255,16 +309,29 @@ class WeatherManager {
|
||||
// Clear existing forecast
|
||||
forecastContainer.innerHTML = '';
|
||||
|
||||
// Add current weather as "Now"
|
||||
// Add current weather as "Nu" (Swedish for "Now")
|
||||
const nowElement = document.createElement('div');
|
||||
nowElement.className = 'forecast-hour';
|
||||
const nowIcon = document.createElement('img');
|
||||
nowIcon.src = this.weatherData.icon;
|
||||
nowIcon.alt = this.weatherData.description;
|
||||
nowIcon.width = 56;
|
||||
nowIcon.setAttribute('data-condition', this.weatherData.condition);
|
||||
if (this.isSnowIcon(this.weatherData.iconCode, this.weatherData.condition)) {
|
||||
nowIcon.classList.add('weather-snow');
|
||||
} else if (this.isClearSun(this.weatherData.iconCode, this.weatherData.condition)) {
|
||||
nowIcon.classList.add('weather-sun', 'weather-clear-sun');
|
||||
} else if (this.isSunBehindClouds(this.weatherData.iconCode, this.weatherData.condition)) {
|
||||
nowIcon.classList.add('weather-sun', 'weather-clouds-sun');
|
||||
} else if (this.isSunIcon(this.weatherData.iconCode, this.weatherData.condition)) {
|
||||
nowIcon.classList.add('weather-sun');
|
||||
}
|
||||
nowElement.innerHTML = `
|
||||
<div class="time">Now</div>
|
||||
<div class="icon">
|
||||
<img src="${this.weatherData.icon}" alt="${this.weatherData.description}" width="40" />
|
||||
</div>
|
||||
<div class="time">Nu</div>
|
||||
<div class="icon"></div>
|
||||
<div class="temp">${this.weatherData.temperature} °C</div>
|
||||
`;
|
||||
nowElement.querySelector('.icon').appendChild(nowIcon);
|
||||
forecastContainer.appendChild(nowElement);
|
||||
|
||||
// Add hourly forecasts
|
||||
@@ -274,13 +341,26 @@ class WeatherManager {
|
||||
|
||||
const forecastElement = document.createElement('div');
|
||||
forecastElement.className = 'forecast-hour';
|
||||
const forecastIcon = document.createElement('img');
|
||||
forecastIcon.src = forecast.icon;
|
||||
forecastIcon.alt = forecast.description;
|
||||
forecastIcon.width = 56;
|
||||
forecastIcon.setAttribute('data-condition', forecast.condition);
|
||||
if (this.isSnowIcon(forecast.iconCode, forecast.condition)) {
|
||||
forecastIcon.classList.add('weather-snow');
|
||||
} else if (this.isClearSun(forecast.iconCode, forecast.condition)) {
|
||||
forecastIcon.classList.add('weather-sun', 'weather-clear-sun');
|
||||
} else if (this.isSunBehindClouds(forecast.iconCode, forecast.condition)) {
|
||||
forecastIcon.classList.add('weather-sun', 'weather-clouds-sun');
|
||||
} else if (this.isSunIcon(forecast.iconCode, forecast.condition)) {
|
||||
forecastIcon.classList.add('weather-sun');
|
||||
}
|
||||
forecastElement.innerHTML = `
|
||||
<div class="time">${timeString}</div>
|
||||
<div class="icon">
|
||||
<img src="${forecast.icon}" alt="${forecast.description}" width="40" />
|
||||
</div>
|
||||
<div class="icon"></div>
|
||||
<div class="temp">${forecast.temperature} °C</div>
|
||||
`;
|
||||
forecastElement.querySelector('.icon').appendChild(forecastIcon);
|
||||
forecastContainer.appendChild(forecastElement);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user