天气预报云服务器部署实战
引言
一款采用现代前端技术构建的美观、实用的天气预报单页应用,提供直观的天气信息展示和流畅的用户体验。
一 项目概述
本项目是一个纯前端实现的天气预报单页应用,结合了精美的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);// 显示toastsetTimeout(() => {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 动态效果
- **太阳动画**:缓慢旋转效果,模拟太阳东升西落
- **云朵动画**:上下浮动效果,仿佛在天空中轻轻飘动
- **雨滴动画**:自然下落效果,营造下雨的真实感
- **雪花动画**:轻盈飘落效果,模拟雪花从天空降落
- **雾动画**:淡入淡出效果,表现雾气的朦胧感
- **雷电动画**:闪烁效果,呈现雷暴天气的特点