天气预报云服务器部署实战

发布于:2025-09-07 ⋅ 阅读:(13) ⋅ 点赞:(0)

引言

一款采用现代前端技术构建的美观、实用的天气预报单页应用,提供直观的天气信息展示和流畅的用户体验。

一 项目概述

本项目是一个纯前端实现的天气预报单页应用,结合了精美的UI设计和流畅的动画效果,为用户提供实时天气信息和未来天气预报。应用支持响应式设计,可在各种设备上完美展示。

二 功能特性

- **实时天气信息**:显示当前温度、体感温度、湿度、风速、气压等详细气象数据

- **未来天气预报**:提供未来几天的天气趋势预测

- **动态天气图标**:根据天气状况展示相应的动画效果(太阳旋转、云朵浮动、雨滴下落等)

- **数据可视化**:使用Chart.js展示温度变化趋势图表

- **响应式设计**:完美适配手机、平板和桌面设备

- **优雅的UI**:采用蓝色渐变背景和半透明卡片设计,营造清新、专业的视觉效果

- **平滑动画**:页面元素添加入场动画和平滑过渡效果

三 技术栈

- **HTML5**:构建语义化的页面结构

- **Tailwind CSS v3**:快速实现响应式布局和现代化UI设计

- **JavaScript (ES6+)**:处理交互逻辑和数据展示

- **Font Awesome**:提供丰富的天气图标

- **Chart.js**:用于绘制温度变化趋势图表

四 快速开始

indel.html 文件启动

五 核心代码展示

下面是应用中最核心的功能实现代码,展示了天气数据处理、UI更新、动态效果和数据可视化的关键部分:

5.1. 天气数据获取与处理

function getWeatherData(city) {
    showLoading();
    
    // 模拟API调用延迟
    setTimeout(() => {
        try {
            // 在实际应用中,这里应该是真实的API调用
            // 这里使用模拟数据进行演示
            useMockData(city);
        } catch (error) {
            console.error('获取天气数据失败:', error);
            showToast('获取天气数据失败,请稍后重试');
            useMockData(city); // 即使API失败,也使用模拟数据
        } finally {
            hideLoading();
        }
    }, 1500);
}

5.2天气 UI 更新系统

// 更新天气UI
function updateWeatherUI(data) {
    // 更新城市名称
    document.getElementById('city-name').textContent = data.city;
    
    // 更新当前时间
    document.getElementById('current-time').textContent = getCurrentTime();
    
    // 获取当前天气数据
    const currentWeather = data.data[0];
    
    // 更新当前天气信息
    document.getElementById('current-temp').textContent = currentWeather.temperature;
    document.getElementById('current-weather').textContent = currentWeather.weather;
    document.getElementById('current-wind').textContent = currentWeather.wind;
    document.getElementById('air-quality').textContent = currentWeather.air_quality;
    
    // 更新天气图标
    const weatherIconContainer = document.getElementById('weather-icon');
    weatherIconContainer.innerHTML = getWeatherIcon(currentWeather.weather);
    
    // 更新预报卡片
    updateForecastCards(data.data);
    
    // 更新温度图表
    updateTemperatureChart(data.data);
    
    // 滚动到当前天气
    document.getElementById('current').scrollIntoView({ behavior: 'smooth' });
    
    // 添加动画效果
    weatherContent.classList.remove('animate-fade-in');
    void weatherContent.offsetWidth; // 触发重绘
    weatherContent.classList.add('animate-fade-in');
}

// 更新预报卡片
function updateForecastCards(forecastData) {
    const forecastContainer = document.querySelector('#forecast .grid');
    forecastContainer.innerHTML = '';
    
    forecastData.forEach(day => {
        const card = document.createElement('div');
        card.className = 'bg-white rounded-xl shadow-md p-4 card-hover';
        
        // 获取天气图标
        const weatherIcon = getWeatherIcon(day.weather);
        
        card.innerHTML = `
            <div class="text-center">
                <p class="font-medium text-gray-700">${day.date}</p>
                ${weatherIcon}
                <p class="text-gray-600">${day.weather}</p>
                <p class="font-bold mt-2">${day.temperature}</p>
                <p class="text-sm text-gray-500 mt-1">${day.wind}</p>
            </div>
        `;
        
        forecastContainer.appendChild(card);
    });
}

5.3. 动态天气图标系统

// 获取天气图标
function getWeatherIcon(weather) {
    let iconClass = '';
    let animationClass = '';
    
    if (weather.includes('晴')) {
        iconClass = 'fa-sun';
        animationClass = 'animate-sun';
    } else if (weather.includes('云')) {
        iconClass = 'fa-cloud';
        animationClass = 'animate-cloud';
    } else if (weather.includes('雨')) {
        iconClass = 'fa-cloud-rain';
        animationClass = 'animate-rain';
    } else if (weather.includes('雪')) {
        iconClass = 'fa-snowflake';
        animationClass = 'animate-snow';
    } else if (weather.includes('雾')) {
        iconClass = 'fa-smog';
        animationClass = 'animate-fog';
    } else if (weather.includes('雷')) {
        iconClass = 'fa-bolt';
        animationClass = 'animate-thunder';
    } else {
        iconClass = 'fa-cloud-sun';
        animationClass = '';
    }
    
    return `<i class="fa ${iconClass} text-primary text-4xl ${animationClass}"></i>`;
}

5.4 数据可视化实现

// 更新温度图表
function updateTemperatureChart(forecastData) {
    const ctx = document.getElementById('temperature-chart').getContext('2d');
    
    // 销毁已存在的图表
    if (window.temperatureChart) {
        window.temperatureChart.destroy();
    }
    
    const dates = forecastData.map(day => day.date);
    const minTemps = forecastData.map(day => {
        return parseInt(day.temperature.split('-')[0].replace('℃', ''));
    });
    const maxTemps = forecastData.map(day => {
        return parseInt(day.temperature.split('-')[1].replace('℃', ''));
    });
    
    // 创建新图表
    window.temperatureChart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: dates,
            datasets: [
                {
                    label: '最高温度',
                    data: maxTemps,
                    borderColor: '#F97316',
                    backgroundColor: 'rgba(249, 115, 22, 0.1)',
                    borderWidth: 2,
                    tension: 0.3,
                    fill: false,
                    pointBackgroundColor: '#F97316',
                    pointRadius: 4
                },
                {
                    label: '最低温度',
                    data: minTemps,
                    borderColor: '#3B82F6',
                    backgroundColor: 'rgba(59, 130, 246, 0.1)',
                    borderWidth: 2,
                    tension: 0.3,
                    fill: false,
                    pointBackgroundColor: '#3B82F6',
                    pointRadius: 4
                }
            ]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            // 更多配置选项...
        }
    });
}

5.5 页面交互也用户体验化

// 移动端菜单切换
mobileMenuButton.addEventListener('click', () => {
    mobileMenu.classList.toggle('hidden');
});

// 城市搜索
searchButton.addEventListener('click', () => {
    const city = citySearch.value.trim();
    if (city) {
        getWeatherData(city);
    } else {
        showToast('请输入城市名称');
    }
});

// 热门城市点击
const cityTags = document.querySelectorAll('.city-tag');
cityTags.forEach(tag => {
    tag.addEventListener('click', () => {
        const city = tag.textContent;
        citySearch.value = city;
        getWeatherData(city);
    });
});

// 显示提示信息
function showToast(message) {
    // 创建toast元素
    const toast = document.createElement('div');
    toast.className = 'fixed top-20 left-1/2 transform -translate-x-1/2 bg-dark text-white px-6 py-3 rounded-lg shadow-lg z-50 transition-all duration-300 opacity-0';
    toast.textContent = message;
    
    document.body.appendChild(toast);
    
    // 显示toast
    setTimeout(() => {
        toast.classList.remove('opacity-0');
        toast.classList.add('opacity-100');
    }, 10);
    
    // 3秒后隐藏
    setTimeout(() => {
        toast.classList.remove('opacity-100');
        toast.classList.add('opacity-0');
        
        setTimeout(() => {
            document.body.removeChild(toast);
        }, 300);
    }, 3000);
}

5.6 动态效果实现

/* 太阳动画 */
@keyframes sun {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

/* 云朵动画 */
@keyframes cloud {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-5px);
    }
}

/* 雨滴动画 */
@keyframes fall {
    0% {
        transform: translateY(-20px);
        opacity: 0;
    }
    10% {
        opacity: 1;
    }
    90% {
        opacity: 1;
    }
    100% {
        transform: translateY(40px);
        opacity: 0;
    }
}

/* 雪花动画 */
@keyframes snow {
    0% {
        transform: translateY(-20px) rotate(0deg);
        opacity: 0;
    }
    50% {
        opacity: 1;
    }
    100% {
        transform: translateY(20px) rotate(360deg);
        opacity: 0;
    }
}

/* 雾动画 */
@keyframes fog {
    0%, 100% {
        opacity: 0.6;
    }
    50% {
        opacity: 0.3;
    }
}

六 设计亮点

6.1 视觉设计

- **渐变背景**:使用蓝色系渐变作为页面背景,营造天空的感觉

- **半透明卡片**:采用半透明的白色卡片展示天气信息,创造层次感

- **阴影效果**:为卡片添加柔和的阴影,增强立体感

- **圆角设计**:统一使用圆角元素,营造亲和、现代的视觉感受

- **文本层次**:通过不同的字体大小、粗细和颜色,建立清晰的文本信息层次结构

6.2 动态效果

- **太阳动画**:缓慢旋转效果,模拟太阳东升西落

- **云朵动画**:上下浮动效果,仿佛在天空中轻轻飘动

- **雨滴动画**:自然下落效果,营造下雨的真实感

- **雪花动画**:轻盈飘落效果,模拟雪花从天空降落

- **雾动画**:淡入淡出效果,表现雾气的朦胧感

- **雷电动画**:闪烁效果,呈现雷暴天气的特点


网站公告

今日签到

点亮在社区的每一天
去签到