HTML5 SVG 实现日出日落动画与实时天气可视化

目录

前言

一、系统介绍

1、功能特点

2、项目结构

二、技术实现

1、日出日落计算

2、仪表盘生成

3、数据加载

三、成果展示

1、日出日落展示

2、气温信息展示

四、总结


前言

在日常的天气应用中,我们已习惯了静态的数字与图标------一个太阳图标代表晴天,一个月亮代表夜晚,温度以干冷的阿拉伯数字悬浮在屏幕中央。这种设计固然高效,却剥离了天气本应具有的时空叙事感。当我们查看地区的天气时,真正想了解的不仅是"xx℃"这个数字,更是此刻太阳在上空的位置、距离日落还有多久。传统前端技术栈中,CSS 动画虽能实现简单的元素位移,却难以绘制基于真实天文算法的太阳轨迹;SVG 在矢量图形上表现出色,恰好填补了这一空白,它为前端开发者提供了直接操作像素的画笔,使浏览器具备了实时渲染复杂视觉效果的能力,让天气预报从"数据报告"进化为"时空可视化体验"。

本文将完整呈现如何基于 HTML5 SVG 构建一套融合天文计算与气象数据的实时可视化系统。核心技术架构分为三层:数据层通过接入第三方百度气象 API 获取地区的实时温度、湿度、天气状况及地理位置信息;计算层引入 SunCalc 等天文算法库,基于经纬度精确计算太阳高度角、方位角及日出日落时刻,将抽象的时间数据转化为可视化的空间坐标;渲染层则全权交由 SVG进行上下文处理,用贝塞尔曲线绘制太阳视运动轨迹。这种"数据驱动+物理仿真"的设计思路,正是现代前端可视化开发的核心范式。本文是可视化内容的一个重要环节,即网页静态数据的可视化。

一、系统介绍

这是一个基于HTML、CSS和JavaScript实现的天气预报页面,重点展示了吉首地区的天气信息,包括实时温度、日出日落时间和动态太阳位置。本节将从功能特点、项目特点等几个方面来进行说明。

1、功能特点

  • **动态太阳位置:**根据当前时间计算太阳在日出日落路径上的位置。
  • **日出日落时间:**显示精确的日出(如:07:28)和日落(如:18:23)时间。
  • **SVG仪表盘:**使用SVG实现的美观太阳路径和时间标记。
  • **天气详情:**展示降水量、风向、相对湿度和体感温度。
  • **空气质量和舒适度:**显示空气质量等级和舒适度评价。
  • **响应式设计:**适配不同屏幕尺寸。

2、项目结构

整体项目使用以下技术:HTML5:页面结构和SVG元素;CSS3:样式设计和布局;JavaScript:太阳位置计算和时间更新。整体的项目结构如下:

bash 复制代码
weather_demo/
├── index.html          # 主页面
├── style.css           # 样式文件
├── script.js           # JavaScript文件
├── weather_data.json   # 天气数据文件
└── README.md           # 项目说明

二、技术实现

从本节开始介绍具体的技术实现。包含以下三个方面的内容,第一个是日出日落的计算,其次是仪表盘的生成,最后是如何进行数据加载。

1、日出日落计算

首先来来介绍如何来实现日出日落的位置计算。太阳位置的计算包含使用二次贝塞尔曲线公式计算太阳在路径上的位置,从JSON数据中读取日出日落时间以及如何根据当前时间实时更新太阳位置。

javascript 复制代码
// 计算太阳位置
function calculateSunPosition() {
    if (!weatherData) return;
    // 解析日出日落时间(分钟)
    const sunriseParts = weatherData.sunrise.split(':');
    const sunrise = parseInt(sunriseParts[0]) * 60 + parseInt(sunriseParts[1]);
    const sunsetParts = weatherData.sunset.split(':');
    const sunset = parseInt(sunsetParts[0]) * 60 + parseInt(sunsetParts[1]);
    // 当前时间(分钟)
    const now = new Date();
    const currentTime = now.getHours() * 60 + now.getMinutes();
    // 计算太阳位置比例
    let positionRatio;
    if (currentTime < sunrise) {
        positionRatio = 0; // 日出前
    } else if (currentTime > sunset) {
        positionRatio = 1; // 日落后
    } else {
        positionRatio = (currentTime - sunrise) / (sunset - sunrise);
    }
    // 计算太阳在SVG中的坐标
    // SVG路径:M50 150 Q200 -50 350 150
    const startX = 50;
    const startY = 150;
    const controlX = 200;
    const controlY = -50;
    const endX = 350;
    const endY = 150;
    // 使用二次贝塞尔曲线公式计算太阳位置
    const t = positionRatio;
    const sunX = (1 - t) * (1 - t) * startX + 2 * (1 - t) * t * controlX + t * t * endX;
    const sunY = (1 - t) * (1 - t) * startY + 2 * (1 - t) * t * controlY + t * t * endY;
    // 设置太阳位置
    const sun = document.getElementById('sun');
    sun.setAttribute('cx', sunX);
    sun.setAttribute('cy', sunY);
    // 设置当前时间标记
    const timeLine = document.getElementById('current-time-line');
    const timeText = document.getElementById('current-time-text');
    timeLine.setAttribute('x1', sunX);
    timeLine.setAttribute('x2', sunX);
    timeText.setAttribute('x', sunX);
    // 显示当前时间
    const hours = now.getHours().toString().padStart(2, '0');
    const minutes = now.getMinutes().toString().padStart(2, '0');
    timeText.textContent = `${hours}:${minutes}`;
}

在上面的代码中,日出和日落的时间我们使用的是模拟数据。在实际计算过程中,可以通过后台接口计算指定城市的日出日落时间后动态传入到系统中。代码中介绍了如何计算贝塞尔曲线的太阳位置,

javascript 复制代码
// 使用二次贝塞尔曲线公式计算太阳位置
const t = positionRatio;
const sunX = (1 - t) * (1 - t) * startX + 2 * (1 - t) * t * controlX + t * t * endX;
const sunY = (1 - t) * (1 - t) * startY + 2 * (1 - t) * t * controlY + t * t * endY;

2、仪表盘生成

我们在Html页面中首先生成一个展示太阳升起和日落的表盘,实现代码使用svg源码如下:

当页面加载后,当时间发生变更后,再通过程序动态更新表盘:

javascript 复制代码
// 更新仪表盘当前时间
function updateDashboardTime() {
    const now = new Date();
    const hours = now.getHours().toString().padStart(2, '0');
    const minutes = now.getMinutes().toString().padStart(2, '0');
    const timeString = `${hours}:${minutes}`;
    document.getElementById('dashboard-current-time').textContent = timeString;
}

3、数据加载

这里动态的加载日出日落以及动态标注时间位置后,同时还需要展示天气信息。这里将简单介绍天气和日出日落的数据参数说明,以JSON数据为例:

javascript 复制代码
```json
{
  "location": "吉首",
  "temperature": "8.8°C",
  "updateTime": "09:40",
  "sunrise": "07:28",
  "sunset": "18:23",
  "weatherDetails": {
    "precipitation": "0mm",
    "wind": "西南风 微风",
    "humidity": "78%",
    "feelsLike": "7.9°C"
  },
  "airQuality": "良",
  "comfort": "凉,不舒适"
}

字段说明如下:

javascript 复制代码
- `location`: 城市名称
- `temperature`: 实时温度
- `updateTime`: 数据更新时间
- `sunrise`: 日出时间
- `sunset`: 日落时间
- `weatherDetails`: 天气详情
  - `precipitation`: 降水量
  - `wind`: 风向和风力
  - `humidity`: 相对湿度
  - `feelsLike`: 体感温度
- `airQuality`: 空气质量
- `comfort`: 舒适度评价

在页面中如何把上面的数据加载到页面中,这里我们设计一个更新时间和天气实况的方法,方法如下:

javascript 复制代码
// 更新页面上的天气信息
function updateWeatherInfo() {
    if (!weatherData) return;
    
    // 更新位置和温度
    document.querySelector('.location').textContent = weatherData.location;
    document.querySelector('.temperature').textContent = weatherData.temperature;
    
    // 更新更新时间
    document.querySelector('.update-time').textContent = `☀️ ${weatherData.updateTime}更新`;
    
    // 更新仪表盘时间
    document.querySelector('.dashboard-item.sunrise .dashboard-value').textContent = weatherData.sunrise;
    document.querySelector('.dashboard-item.sunset .dashboard-value').textContent = weatherData.sunset;
    
    // 更新天气详情
    const detailItems = document.querySelectorAll('.detail-item');
    detailItems[0].querySelector('.detail-value').textContent = weatherData.weatherDetails.precipitation;
    detailItems[1].querySelector('.detail-value').textContent = weatherData.weatherDetails.wind;
    detailItems[2].querySelector('.detail-value').textContent = weatherData.weatherDetails.humidity;
    detailItems[3].querySelector('.detail-value').textContent = weatherData.weatherDetails.feelsLike;
    
    // 更新空气质量和舒适度
    const airQualityElements = document.querySelectorAll('.air-quality span');
    airQualityElements[0].textContent = `空气质量: ${weatherData.airQuality}`;
    airQualityElements[1].textContent = `舒适度: ${weatherData.comfort}`;
    
    // 更新SVG时间标记
    const timeMarkers = document.querySelectorAll('.sun-dashboard text');
    if (timeMarkers.length >= 2) {
        timeMarkers[0].textContent = weatherData.sunrise;
        timeMarkers[timeMarkers.length - 1].textContent = weatherData.sunset;
    }
}

到这里基本就完成了数据的加载和展示,更多的例子,可以从CSDN中进行下载源码。源码传送门

三、成果展示

本节将对实际的效果进行一个展示,让大家直观的看到系统的效果。

1、日出日落展示

上图是是包含日出日落的动态展示效果,展示了太阳从日出到日落的一个动态过程,并且在日出日落的位置展示具体的时间。在仪表盘的下方,则直观的展示对应的时间。

2、气温信息展示

除了日出日落以外,这里我们同时需要展示目标城市的天气信息。效果如下:

这里则展示城市名称、温度信息、降水量、风向、相对湿度和体感温度、空气质量等信息。如果有更多的信息,大家可以根据需要自行添加。

四、总结

以上就是本文的主要内容,本文将完整呈现如何基于 HTML5 SVG 构建一套融合天文计算与气象数据的实时可视化系统。对于前端开发者而言,这不仅是一次 SVG API 的实战演练,更是理解"如何将科学计算转化为视觉语言"的绝佳契机。在可视化需求爆炸式增长的今天,掌握像素级渲染能力,意味着拥有了打破"CSS 盒子模型"束缚的钥匙,能够在数字世界中重建更贴近物理直觉的用户体验。读完本文,希望对你有帮助。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。

相关推荐
夏幻灵4 小时前
HTML5里最常用的十大标签
前端·html·html5
Mr Xu_4 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝4 小时前
RBAC前端架构-01:项目初始化
前端·架构
程序员agions5 小时前
2026年,微前端终于“死“了
前端·状态模式
万岳科技系统开发5 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
程序员猫哥_5 小时前
HTML 生成网页工具推荐:从手写代码到 AI 自动生成网页的进化路径
前端·人工智能·html
龙飞055 小时前
Systemd -systemctl - journalctl 速查表:服务管理 + 日志排障
linux·运维·前端·chrome·systemctl·journalctl
我爱加班、、5 小时前
Websocket能携带token过去后端吗
前端·后端·websocket
AAA阿giao5 小时前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架