此版本「经典原版」为老版本,现在已经停止更新,后续不再进行大更新和改动。后续建议使用新版「光谱观测版」(首页「更多项目」菜单与页脚都有入口)。Skyglow 是基于第三方 couletian/Skyglow 的独立移植增强项目,不属于 Sunglow / 霞光预报,也不是霞光预报的一个版本。如有特别需要的用户仍可继续使用经典原版,此版本保留开放。
前往光谱观测版读懂朝霞与晚霞的预报
霞光预报是一个单文件 Web 应用:输入地点与日期,预测朝霞 / 晚霞(火烧云)出现的概率与观赏质量,并在周边 500 km 画出霞光分布。这份教程分四档,按身份取用。
- 3套模型合成
- 500 km周边网格
- 0注册 · 纯前端
四档教程,各取所需
它到底在算什么
一句话:把「今晚有没有火烧云」从玄学变成可量化的概率与质量分。
- 朝霞 / 晚霞
- 日出前与日落后的低空霞光(火烧云)。两者的大气条件不同,所以应用分开预报、可分别切换。
- 概率 %
- 出现霞光的可能性,由云量、湿度、能见度等条件推算 —— 不是「会不会出太阳」。
- 质量评分
- 在「会出现」的前提下,霞光的观赏质量(色彩浓度、覆盖范围),分优 / 良 / 一般 / 差四档。
- 多模型合成
- GFS / ECMWF / 光追算法三路各自出分,再按 0.30 / 0.34 / 0.36 的权重合成,降低单一来源偏差。
地图上那条从白到红的热力色阶,本教程沿用为视觉线索:看到这条带子,就代表「霞光强度」。
语言与主题
右上角两个按钮管整页:左边切语言(简体中文 / 繁體中文 / English),右边切主题(跟随系统 / 浅色 / 深色)。选择会写进主程序同一个偏好键 —— 在这里改成英文,回主页也是英文。
主题不进链接:别人分享给你的地址不该强行改你的界面颜色。
用户版 · 上手指南
从一次查询到一张分享图
面向摄影爱好者与日常使用者。下面的顺序,基本就是一次完整使用的路径。
1 · 查一次朝霞 / 晚霞预报
- 选地点。在查询区搜索城市名,或允许浏览器定位,或点开预设里的常用地点。地名走白名单,外源地名的异常字符会被安全处理。
- 选日期与时段。默认今天;时段在「朝霞 / 晚霞」之间切换 —— 两者大气条件不同,分开算。
- 读结论卡。核心三格:概率 %、质量评分、等级(优 / 良 / 一般 / 差)。下方「主要影响因素」逐项分解,告诉你这次是云量、湿度还是能见度在拖后腿。
- 看多模型。卡内列出 GFS / ECMWF / 光追三路各自的分数与合成结果;模型之间分歧大时,悬停信息里会提示不确定性。
2 · 看懂周边地图
地图把查询点周边 500 km 的霞光强度画成热力图,是「今天去哪个方向拍」最直观的答案。
怎么把它画出来
- 有缓存时自动画。上次看过的城市 + 日期,新开页会零请求直接画出来(走缓存快路径,不占额度)。
- 没缓存时点击加载。点地图面板里的「刷新地图」才发起请求(约 171 个加权调用)—— 它直接影响你自己的日额度。
图上是什么
- 色面
- 采样点插值出的霞光强度,白 → 黄 → 橙 → 红分档。色阶是固定的 0–100 绝对刻度,所以同一片区域的深浅可以跨日期直接对比。
- 云纹
- 采样点上的云量,按四档铺成半透明的纯色云影色块(纯色平铺,不是斜纹)。晴天不铺(否则整张图都是色块,等于没有信息),有云才显形。
- 等值线
- 档与档之间一条 1px 线(屏幕空间矢量,放大不变粗),帮你看清梯度往哪边走。
- 数据范围虚线
- 采样点凸包外缘的虚线:线内是插值、线外是外推,外推区可信度更低。
- 经纬网
- 1° 网格底衬,可在显示层里关闭。
四个显示层开关
数值直标 / 采样点 / 云纹 / 经纬网 —— 按需开关,偏好写进本地存储,重开页恢复。
交互
地图面板里可切时段、日期、模型与着色依据;鼠标悬停或点击出具体数值,外推区会附「离最近采样点多远」的距离口径;全屏按钮在地图卡标题栏右上角。
3 · 趋势与最佳窗口
趋势曲线
未来十天逐日打分,可切换朝霞 / 晚霞。算好的结果会落盘缓存,重开页命中时零请求直接画出。
最佳窗口日历
趋势的另一种读法:把未来几天按「哪天值得去」排成日历格(朝 / 晚两个色块 + 质量分),并标出前三名。点格子直接切过去 —— 渲染这张日历零取数,只有点格子(你的显式意图)才走一次单点取数。
4 · 多观测点对比
回答「今天去哪儿拍」:收藏最多 5 个机位,一次取数横向按质量分排序。
- 取数只能由「对比这些点」按钮触发;命中单点缓存的点不进请求(先单独查过的点零成本)。
- 默认只比当前时段;界面会写明「本次将消耗约 N 个计费调用」。
- 位置 / 日期 / 时段任一变化,对比结果作废 —— 避免显示上一个地点的数字。
5 · 分享与导出
一键分享卡 PNG
把结论卡导出为图片(纯 canvas 绘制,与页面同一套文案与配色),直接发到聊天工具。分享卡固定浅色底,发到任何环境都稳妥。
结果快照链接
链接带 snap= 参数,零气象请求即可还原结论(解码前限长并逐字段校验,恶意载荷只作纯文本落地)。语言、时段随链接走。">链接带 snap= 参数,零气象请求即可还原结论(解码前限长并逐字段校验,恶意载荷只作纯文本落地)。语言、时段随链接走。
6 · 偏好设置
- 语言
- 简体中文 / 繁體中文(中国台湾·香港用语)/ English,写进偏好与分享链接。优先级:链接参数 > 偏好 > 浏览器语言 > 简体。
- 主题
- 跟随系统 / 浅色 / 深色三态,刷新不闪(引导脚本早于样式执行)。主题不进链接 —— 别人发的链接不该强制你的界面变黑。地图深浅跟随主题,不再有第二个开关。
- 单位与时间制
- 公制 / 英制、24 时 / 12 时,按习惯切换,写进同一份偏好。
- 显示层与折叠
- 数值直标 / 采样点 / 云纹 / 经纬网,以及几张技术卡的开合状态,都写进同一个本地键,重开页恢复。
7 · 本地校准
事后回来点一档「实际看到了什么」,本机累积之后,结论卡下方会多出一行本地校准:模型在这一档平均报多少、你标注了几次、实际出现率多少、偏差多少。
- 只展示、不回改模型概率 / 等级 / 因素表任何一个字。
- 只存本机 —— 数据不出设备、可一键关闭、可清空。
- 样本不够不给结论:累计 ≥8 次、且当前这一档 ≥3 次才显示,之前只显示进度。
- 关掉 ≠ 删除:开关只关入口与展示,已存标注不删;清空是另一个按钮,且要二次确认。
- 「没看到(无法判断)」不计入统计,以免系统性拉低校准。
8 · 手机端
- 顶部两行:第一行是目录、标题、语言与主题按钮,第二行是当前结果徽标。滚到哪都能开目录。
- 地图提示卡改成贴底通栏并自带关闭;可再点一次、点卡片外,或直接拖动地图收起。
- 关闭后不留隐形热区(触摸交还地图);拖动超过 12px 视为收卡,以下算点击。
- 页面不能横向拖出空白;地图区单指可拖,手势交给地图 SDK。
9 · 常见疑问
- 为什么地图有时直接显示、有时要点击?
- 有缓存(看过同城市同日期)开页自动画、零额度;无缓存仍需你点「刷新地图」。
- 额度怎么算?
- 免费层按访客自己的出口 IP 计(10000 次 / 天 / 人)。静态站不做代转,站点本身不消耗配额。
- 本地双击打开地图不显示?
- 预期行为:地图代理地址在没有部署时是一个占位符,页面会说明原因;单点查询不受影响。要联调完整功能需按开发者版的说明构建一次。
- 地图的深浅和界面主题是一回事吗?
- 现在是一回事:底图深浅跟随界面主题(浅色主题配浅底图,深色配深底图)。原先那个独立的「深色底图」开关已取消 —— 一个页面不该有两套深浅。
开发者版 · 工程说明
结构、构建与部署
产物是 index.html —— 一个自包含 HTML(内联全部 JS 与城市 / 高程数据),可直接部署为静态站点;地图模块另有一个可选的同源服务端中转端点。
1 · 源码结构
单文件产物由脚本拼装,不要手改产物。教程页是唯一例外:它是独立手写文件,不进拼装流程。
# 源(改这些) tpl/template.html 版式来源(HTML + CSS + 4 个内联 <script> 占位块) tpl/404.html 404 页模板(第二个产物,共用设计令牌) _p2.js … _p5b.js 业务代码片段(与 _pi18n.js 同属一号脚本块) _p6.js 地图模块(单独一个脚本块) _pi18n.js 多语言词典(简 / 繁 / 英) refs/*.txt 内联数据(城市表 / 地名别名 / 0.5° 高程网格 b64) tutorial.html 本教程(独立文件,不参与拼装) # 构建与产物 functions/ Cloudflare Pages Functions(地图代理,可选) assemble.py 拼装 → index.html 与 404.html mkpreview.py 拼装 → _check/preview.html(用 SDK 桩替换腾讯地图脚本) _check/ 回归套件
_p*.js / tpl/ / refs/ 之后都必须重跑 assemble.py 与 mkpreview.py。两个产物都不许手改。2 · 构建命令
# 默认构建(站点在域名根 /) python assemble.py # GitHub Pages 项目页(子路径 /sunglow/) SITE_BASE=sunglow python assemble.py # 带地图代理(同源路径,key 走环境变量,不进产物) TMAP_SERVICE_HOST=https://你的域名/_TMapService python assemble.py # 可选 PWA(多产 manifest / sw / 图标,单文件约束默认仍成立) PWA=1 SITE_BASE=sunglow python assemble.py # 生成带 SDK 桩的预览文件(回归套件跑这个) python mkpreview.py
不设 TMAP_SERVICE_HOST 时,assemble.py 回落到本地预览用的占位符形态,开发行为不变。
3 · 部署
3.1 纯静态(地图不可用)
把 index.html(以及可选的 tutorial.html、404.html)丢到任意静态托管:Cloudflare Pages、GitHub Pages、对象存储。查询、趋势、分享卡全部可用;地图模块因为没有腾讯地图 key 会显示一段说明。
3.2 带地图(Cloudflare Pages + Pages Functions)
腾讯地图 JS API 的 key 不能明文写进产物(单文件 HTML 谁都能看到,拿去刷配额)。已实现代理方案:
- 去 lbs.qq.com 申请 Web 端(JS API)key,把站点域名加进白名单。
- 把本目录作为 Pages 项目(构建命令留空,产物目录
/)。functions/_TMapService/[[path]].js会被自动识别为 Function。 - Pages 的 Settings → Environment variables 加
TMAP_KEY = 你的 key。 - 构建时把地图代理指到同源路径:
TMAP_SERVICE_HOST=https://你的域名/_TMapService python assemble.py。
代理与前端同源 ⇒ 无 CORS、无混合内容。key 只存在于服务端环境变量,永不进入产物。
3.3 404 页
纯静态站没有前端路由,「访问不存在的路径」由托管平台兜底(Cloudflare Pages / GitHub Pages / Netlify 都取站点根下的 404.html 并以 404 返回)。assemble.py 一并生成,无需 rewrite 配置;页内地址写成站点根的绝对形式,由构建期注入 SITE_BASE。
3.4 可选 PWA
PWA=1 会多产 manifest.json / sw.js / 两枚图标,可被「添加到主屏幕」;断网时只能打开应用外壳与已缓存的结果,新的预报与地图仍需联网。三条纪律:① SW 绝不缓存气象响应(只认预缓存名单);② 缓存名带产物 sha256 前 12 位,内容一变旧缓存作废;③ 注册是「增强」—— 失败或 file:// 打开全部静默跳过。默认不开,因为它与「单文件产物」的核心约束冲突。
3.5 本地预览
python assemble.py # 生成 index.html python mkpreview.py # 生成 _check/preview.html(SDK 桩)
_check/preview.html 的地图 SDK 是桩实现(复刻 Heat 核函数叠加与投影),可离线、可断言、不消耗额度。回归套件全部跑这个文件。
4 · 回归套件
python _check/all.py # 总表 python _check/all.py -v # 附完整输出 python _check/all.py --fast # cdp 只跑快段(跳过两段最慢) python _check/all.py -k cdp # 只跑名字含 cdp 的
| 探针 | 覆盖要点 |
|---|---|
| syntax / globals | 内联 script 块语法;跨块命名冲突(静默覆盖最难查) |
| run_self / datacheck | 色阶 / 等级纯函数自测;城市表不变量 + 港澳台合规 |
| localgrid / timeoutprobe | 局部网格几何 / 缓存闸门 / 首屏地图加载;请求超时 + 429 双分类 |
| mapaudit / mobileprobe | 地图审计(图层、缩放、全屏出口);手机端适配合成两档视口 |
| persist / uiprobe | 偏好写盘↔读回;默认态 / 天色带 / 顶栏与目录 |
| a11y / i18n / dark | 无障碍;多语言键覆盖;深色模式(含浅色漏网扫描) |
| spot / snap / calib | F3 / F2 额度纪律;快照零请求;F4 校准 |
| xss / 404 / docfacts | XSS 防护;404 页;文档↔代码一致性 |
| tutorialprobe | 本教程:三语键覆盖、主题三态、窄屏无溢出、四档切换、偏好共享 |
_check/preview.html;改了源码忘了重新生成 preview,整套断言测的就是旧代码 —— 本项目踩过多次的坑。另有少数探针直接读源码或产物:syntax.py 读 index.html,globals.js 读 _p2 ~ _p6 源码,tutorialprobe.js 测 tutorial.html 与 index.html。不进一键序列(会花真实额度或依赖实时接口):consistency.js / shotdefault.js / tzprobe.js 等。
5 · 已知边界(改动前必读)
- 额度
- 首屏只取单点(约 65)。地图默认必须由用户显式点击「刷新地图」才取(约 171);例外有两处:缓存命中自动画(零请求、零额度),以及打开「地图跟随查询自动刷新」后换查询且无缓存时自动取数。缓存命中的零请求由「缓存快路径之后、网络调用之前」的一行提前返回保证。
- 色面与范围
- 色面值域是固定的 0–100 绝对刻度(不做当日拉伸),边缘取采样点凸包并仅向外羽化;凸包之外即外推,用虚线标出。悬停卡另有「离最近采样点多远」的口径 —— 与「在不在采样区」是两个量。
- 云纹
- 按云量分四档铺半透明纯色云影(同一种深蓝,深浅只由 alpha 表达,不是斜纹),晴档不铺(否则整张图都变闷)。档界同时是图例边界;图例里「晴」是空心描边,代表「这里没有色块是因为没有云」。
- 模型分歧
- 地图的「模型分歧」只取三套模型的极差;少于两套有值时返回「无数据」而不是 0。
- 偏好持久化
- 所有显示类偏好写进同一个本地键;应用顺序有硬约束 —— 必须在任何控件初值 / 派生状态赋值之前调用。
- 趋势缓存
- 算好的 rows 落盘(约 1.9KB / 条,上限 3 条),重开页命中零请求;不存原始响应(约 5MB,会撑爆配额)。权重 / 阈值一改就用版本号兜住。
- 深色模式
- 三态;刷新不闪(引导脚本在
<style>之前);color-scheme跟着切;写进 DOM 的语义色要重画。分享卡固定浅色;主题不进链接。">三态;刷新不闪(引导脚本在<style>之前);color-scheme跟着切;写进 DOM 的语义色要重画。分享卡固定浅色;主题不进链接。 - XSS
- 输出侧
esc()+ 输入侧safeLabel()(URL 地名白名单)。新增渲染代码必须走这两个函数;仍未做:CSP 与其余分批替换。 - F2 / F3 / F4
- F3 日历渲染零取数,点格子才取数;F2 取数只能由按钮触发、命中缓存不进请求、上限 5 点;F4 只展示不回改、样本不够不给结论、关掉≠删除。
- 手机端布局
- 任何横向滚动容器必须
min-width:0;#map必须touch-action:none且不能设在.mapwrap;判越界用documentElement.clientWidth而不是innerWidth。
6 · 合规
在中国境内展示地图,底图服务需具备测绘资质。腾讯地图是合规的;为省一个 key 换成 OSM 等境外底图,会把合规问题一起换进来,不建议。
数据源:气象与空气质量来自 Open-Meteo(免费公开、非商业),省界来自阿里云 DataV,地图来自腾讯位置服务 —— 请遵守各自的服务条款。
创作者版 · 演示素材
怎么把霞光预报讲给人看
面向自媒体与内容创作者:最值得讲的亮点、演示叙事线,以及可以放心引用的卖点。
1 · 一句话开场
这句同时覆盖了差异化(量化而非玄学)与易得性(免费 / 无注册 / 纯前端),适合做短视频开头或图文首段。
2 · 最值得讲的六个亮点
概率 + 质量评分,衬线大字
结论卡用大号衬线数字呈现概率 % 与质量分,配优 / 良 / 一般 / 差等级与「主要影响因素」分解 —— 截图即干货,观众一眼看懂。
周边 500 km 霞光分布
热力图把「去哪个方向拍」画出来。白 → 黄 → 橙 → 红色阶 + 等值线 + 数据范围虚线,演示时可以说「红色那片很可能就是今晚最该去的地方」—— 热力图目前仍是测试功能,结果仅供参考,不要说成确定结论。
哪天去,日历直接排好
未来几天按「哪天值得去」排成日历格并标出前三名。适合做「未来一周什么时候拍照最好」这类选题。
今天去哪儿拍
收藏最多 5 个机位,一次取数横向排序。演示「家附近 vs 海边 vs 山顶,今晚哪个出片」最直观。
分享卡与快照链接
结论卡导出 PNG 直接发群;snap= 链接零请求还原结论,别人点开就是同一张预报。降低观众「我也想试试」的门槛。
越用越懂你那片天
事后回填「实际看到了什么」,本机累积出本地校准。强调「纯展示不回改模型、数据不出设备」—— 隐私友好,适合做信任感叙事。
3 · 适合的题材
| 题材 | 切入点 |
|---|---|
| 摄影教程 | 用最佳窗口日历选拍摄日、用多机位对比选机位、用地图定方向。 |
| 天气 / 大气科普 | 朝霞晚霞大气条件不同、为什么分两个时段、模型分歧代表什么。 |
| 出行 / 生活攻略 | 「今晚值不值得专门跑出去拍」「未来一周哪天最适合」。 |
| 工具推荐 | 免费、无注册、纯前端、隐私友好、可装成 App(PWA)。 |
4 · 演示叙事线
- 抛出痛点:「每次等晚霞都靠赌,今天教你用数据赌。」
- 一次查询:搜城市 → 切晚霞 → 结论卡大数字 + 因素分解。
- 放大地图:点「刷新地图」→ 指红色区域说「去这儿」。
- 拉长时间:开最佳窗口日历 → 「这周三是冠军」。
- 横向比较:开多机位对比 → 「山顶比海边稳」。
- 收尾转化:导出分享卡 / 发快照链接 → 「链接放评论区,自己查你那片天」。
5 · 可放心引用的卖点
- 免费、无需注册,纯前端直连公开气象接口(Open-Meteo)。
- 三模型合成(GFS / ECMWF / 光追,权重 0.30 / 0.34 / 0.36),降低单一来源偏差。
- 隐私友好:本地校准只存本机、可关闭可清空、不回改模型。
- 额度对访客友好:首屏只取单点,地图显式点击才取,缓存命中零请求。
- 可装成 App(PWA,可选);断网时只能查看已缓存的结果,新预报需要联网。
6 · 注意事项(别踩坑)
- 额度
- 免费层按访客自己的出口 IP 计(10000 次 / 天 / 人)。演示时自己多刷几次没关系,但别让观众以为「无限调用」。
- 地图需要部署
- 双击本地文件打开时地图不显示(代理是占位符形态),这是预期行为;完整地图功能需要带代理的部署。
- 合规底图
- 中国境内展示地图需测绘资质,项目用的腾讯地图是合规方案;不要为省事换成境外底图。
- 概率指的是霞光
- 避免观众误解 —— 它预报的是低空霞光出现的可能性与质量,不是晴雨。
- 热力图仍在测试
- 地图热力图目前为测试功能,结果仅供参考;演示时请避免把它说成确定的结论。