0

0

HTML如何制作星座图表?星空图怎么绘制?

月夜之吻

月夜之吻

发布时间:2025-08-08 09:22:01

|

1078人浏览过

|

来源于php中文网

原创

要制作星座图表或星空图,必须结合html元素与javascript进行动态绘制,css仅用于美化;1. 使用canvas创建绘图区域,并通过javascript的2d上下文绘制星星和连线;2. 通过随机生成星星的位置、大小和亮度模拟真实星空,并可用径向渐变绘制星云效果;3. 添加交互功能:通过监听wheel事件实现以鼠标为中心的缩放,结合scale和translate变换调整视口;4. 实现拖动功能需监听mousedown、mousemove和mouseup事件,动态更新视口偏移量并重绘;5. 整合真实星体数据需获取包含赤经、赤纬、视星等信息的天文数据(如hipparcos星表),将其解析为json格式;6. 将球坐标系的赤经赤纬转换为canvas的二维笛卡尔坐标,可采用简化线性映射或更精确的投影算法;7. 根据视星等决定星星大小和亮度,并通过预定义的星座连线数据绘制星座轮廓;8. 为提升真实感,可引入闪烁动画、不同颜色的恒星或结合天文库实现随时间地点变化的星空。最终需在每次交互后调用重绘函数以更新画面,完整实现一个可交互且基于真实数据的星空图。

HTML如何制作星座图表?星空图怎么绘制?

HTML要制作星座图表或绘制星空图,单靠HTML本身是无法完成的,它主要负责结构。核心在于结合JavaScript和HTML的

元素,通过编程来动态绘制图形。CSS则可以用来美化容器或添加一些基础样式。

解决方案

要绘制星空图,最直接且灵活的方式是利用HTML5的

元素配合JavaScript。Canvas提供了一个绘图上下文,允许你用像素级别的精度绘制图形。

首先,在HTML中创建一个

canvas
标签:

立即学习前端免费学习笔记(深入)”;

接着,在JavaScript中获取这个canvas元素及其2D绘图上下文:

const canvas = document.getElementById('starMapCanvas');
const ctx = canvas.getContext('2d');

// 示例:绘制一个简单的星星
function drawStar(x, y, radius, color = '#FFF') {
    ctx.beginPath();
    ctx.arc(x, y, radius, 0, Math.PI * 2, false);
    ctx.fillStyle = color;
    ctx.fill();
}

// 绘制一些随机的星星
for (let i = 0; i < 100; i++) {
    const x = Math.random() * canvas.width;
    const y = Math.random() * canvas.height;
    const radius = Math.random() * 2 + 0.5; // 星星大小随机
    drawStar(x, y, radius);
}

// 示例:绘制一条连接线(模拟星座连线)
function drawLine(x1, y1, x2, y2, color = '#00F', lineWidth = 1) {
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.strokeStyle = color;
    ctx.lineWidth = lineWidth;
    ctx.stroke();
}

// 绘制一个简单的“星座”(三颗星连接)
drawStar(100, 100, 3, '#FFD700'); // 亮星
drawStar(150, 120, 2, '#FFF');
drawStar(120, 180, 2, '#FFF');
drawLine(100, 100, 150, 120, '#00F');
drawLine(150, 120, 120, 180, '#00F');
drawLine(120, 180, 100, 100, '#00F');

这个基础框架可以让你在画布上绘制点(星星)和线(星座连线)。更复杂的星座图需要引入实际的星体数据,并根据它们的坐标进行绘制。

如何利用JavaScript和Canvas绘制逼真的星空图?

说实话,要绘制一个“逼真”的星空图,远不止画点和线那么简单,这里面涉及到不少天文学和图形学的知识。但从技术实现层面,我们可以一步步来。首先,你得明白,星空是三维的,但我们是在一个二维平面上展示,这就涉及到一个投影问题。

最基础的逼真感来源于星星的数量、大小和亮度。你可以通过循环生成大量星星,并根据一个随机函数或预设的亮度分布来决定它们的大小和颜色(比如,亮星用更亮的颜色,大一点)。

// 绘制大量星星以模拟星空背景
const numberOfStars = 1000; // 星星数量
for (let i = 0; i < numberOfStars; i++) {
    const x = Math.random() * canvas.width;
    const y = Math.random() * canvas.height;
    const brightness = Math.random(); // 0到1之间的亮度值
    const radius = brightness * 1.5 + 0.5; // 亮度越高,星星越大
    const colorValue = Math.floor(brightness * 255);
    const color = `rgb(${colorValue}, ${colorValue}, ${colorValue})`; // 模拟不同亮度的白星
    drawStar(x, y, radius, color);
}

// 如果要模拟星云或银河的模糊效果,可以使用渐变或半透明的圆形/椭圆
// 示例:绘制一个简单的星云效果
const gradient = ctx.createRadialGradient(
    canvas.width / 2, canvas.height / 2, 50, // 内圆
    canvas.width / 2, canvas.height / 2, 200 // 外圆
);
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.1)'); // 中心透明度高
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');  // 边缘透明度低

ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(canvas.width / 2, canvas.height / 2, 200, 0, Math.PI * 2);
ctx.fill();

更进一步,你可以考虑引入星星的“闪烁”效果,这可以通过定时器或

requestAnimationFrame
来周期性地改变星星的透明度或大小。不过,这会增加渲染开销,需要权衡。至于星座,它们实际上是由特定的一些亮星组成的。你需要一个数据结构来存储这些星星的坐标和它们之间的连线信息。例如,一个JSON文件可以包含每个星座的星名、坐标(赤经赤纬或X/Y)以及连接方式。

造梦阁AI
造梦阁AI

AI小说推文一键成片,你的故事值得被看见

下载

如何为星座图表添加用户交互功能,如缩放和拖动?

为星座图表添加交互功能是提升用户体验的关键。缩放和拖动通常需要监听鼠标事件,并根据事件类型调整画布的“视口”或变换矩阵。

1. 缩放 (Zooming): 最常见的是通过鼠标滚轮事件实现缩放。你需要维护一个当前的缩放级别和画布的中心点。

let scale = 1; // 初始缩放级别
let originX = 0; // 视口原点X
let originY = 0; // 视口原点Y

canvas.addEventListener('wheel', (e) => {
    e.preventDefault(); // 阻止页面滚动
    const scaleAmount = 1.1; // 每次缩放的比例
    const mouseX = e.clientX - canvas.getBoundingClientRect().left;
    const mouseY = e.clientY - canvas.getBoundingClientRect().top;

    if (e.deltaY < 0) { // 滚轮向上,放大
        scale *= scaleAmount;
    } else { // 滚轮向下,缩小
        scale /= scaleAmount;
    }

    // 调整视口原点,使缩放以鼠标位置为中心
    originX = mouseX - (mouseX - originX) * (e.deltaY < 0 ? scaleAmount : 1 / scaleAmount);
    originY = mouseY - (mouseY - originY) * (e.deltaY < 0 ? scaleAmount : 1 / scaleAmount);

    drawStarMap(); // 重新绘制
});

drawStarMap()
函数中,你需要应用这些变换:

function drawStarMap() {
    ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空画布
    ctx.save(); // 保存当前状态
    ctx.translate(originX, originY); // 移动画布原点
    ctx.scale(scale, scale); // 缩放画布

    // 在这里绘制所有星星和星座
    // 注意:绘制的坐标是相对于变换后的画布,所以星星的原始坐标需要减去 originX/Y
    // 比如:drawStar((star.x - originX) / scale, (star.y - originY) / scale, star.radius / scale);
    // 实际上,更推荐在绘制前对所有坐标进行变换,而不是在绘制函数内部
    // 更简洁的做法是,translate和scale直接影响后续的绘制命令,你只需要用原始坐标绘制即可

    // 示例:重新绘制一些星星
    for (let i = 0; i < 100; i++) {
        const x = Math.random() * canvas.width;
        const y = Math.random() * canvas.height;
        const radius = Math.random() * 2 + 0.5;
        drawStar(x, y, radius); // 这些星星现在会受到缩放和平移的影响
    }

    ctx.restore(); // 恢复之前保存的状态
}

2. 拖动 (Panning): 拖动通常通过监听

mousedown
mousemove
mouseup
事件来实现。

let isDragging = false;
let lastMouseX, lastMouseY;

canvas.addEventListener('mousedown', (e) => {
    isDragging = true;
    lastMouseX = e.clientX;
    lastMouseY = e.clientY;
    canvas.style.cursor = 'grabbing';
});

canvas.addEventListener('mousemove', (e) => {
    if (!isDragging) return;
    const dx = e.clientX - lastMouseX;
    const dy = e.clientY - lastMouseY;

    originX += dx; // 调整视口原点
    originY += dy;

    lastMouseX = e.clientX;
    lastMouseY = e.clientY;
    drawStarMap(); // 重新绘制
});

canvas.addEventListener('mouseup', () => {
    isDragging = false;
    canvas.style.cursor = 'grab';
});

canvas.addEventListener('mouseleave', () => { // 鼠标离开画布时也停止拖动
    isDragging = false;
    canvas.style.cursor = 'grab';
});

这些交互功能的核心在于,你改变的不是星星的实际位置,而是画布的“视角”。每次缩放或拖动后,都需要清空画布并根据新的

scale
originX/Y
值重新绘制所有元素。

如何获取并整合真实的星体数据到HTML星座图表中?

获取真实的星体数据并将其整合到HTML图表中,这部分是真正的挑战,也是让你的图表从“随机点”变成“专业星座图”的关键。

1. 数据来源:

  • 天文数据库/API: 这是最靠谱的方式。例如,NASA、ESA或一些天文馆通常会提供星表数据,比如Hipparcos或Tycho-2星表。这些数据通常包含星体的赤经(Right Ascension, RA)、赤纬(Declination, Dec)、视星等(Apparent Magnitude)、光谱类型等信息。
  • 开源库/数据文件: 有些项目已经整理好了常用的星体数据,可能以CSV、JSON或SQL数据库的形式提供。你可以搜索“star catalog JSON”或“constellation data API”。
  • 自行爬取/整理: 如果找不到现成的API,可能需要从一些公开的天文网站上爬取数据,但这通常比较耗时且需要处理数据格式。

2. 数据格式与解析: 无论数据来源如何,最终你都需要将其转换为JavaScript易于处理的格式,通常是JSON数组。每个对象代表一颗星星,包含其关键属性。

[
  {
    "name": "Sirius",
    "ra": 101.287, // 赤经,度
    "dec": -16.716, // 赤纬,度
    "magnitude": -1.46, // 视星等
    "constellation": "Canis Major"
  },
  {
    "name": "Betelgeuse",
    "ra": 88.792,
    "dec": 7.407,
    "magnitude": 0.5,
    "constellation": "Orion"
  }
  // ...更多星星
]

你还需要一个单独的数据集来定义星座的连线。这个数据集可以是一个数组,每个元素包含一个星座的名称和一系列连接点的索引或星名对。

3. 坐标转换: 这是最核心也最复杂的部分。星体数据通常是球坐标系(赤经、赤纬),你需要将它们投影到你二维的Canvas平面上。常用的投影方式有等距圆柱投影、墨卡托投影等,但对于小范围的星空图,简单的等距投影可能就足够了。

一个简化的转换过程:

  • 将赤经赤纬转换为笛卡尔坐标:
    // 假设你的Canvas中心是(0,0),并且你有一个视场范围
    // 这只是一个非常简化的示例,不考虑复杂的球体投影
    function convertRaDecToXY(ra, dec, centerX, centerY, scaleFactor) {
        // 赤经通常是0-360度,赤纬-90到90度
        // 简单地映射到X/Y坐标,需要根据你的视场和画布大小调整scaleFactor
        const x = centerX + ra * scaleFactor;
        const y = centerY - dec * scaleFactor; // 减号是因为Canvas的Y轴向下
        return { x, y };
    }
  • 考虑当前观察者的位置和时间: 真实的星空图会根据观察者的地理位置和时间而变化。这需要更复杂的计算,比如将J2000坐标(星表常用)转换到当前时刻的Apparent Place,再转换到本地水平坐标系。对于一个静态的星座图,你可以忽略这一步,直接使用星表坐标。但如果你想做成可交互的、显示实时星空的,那就得引入天文计算库(如
    skyfield
    astropy
    在Python中,或者
    astronomy-engine
    在JS中)。

4. 绘制: 一旦你有了星星的X/Y坐标,就可以像前面那样用

ctx.arc()
绘制星星,用
ctx.lineTo()
绘制星座连线。

// 假设 starsData 是你加载的星星JSON数据
// 假设 constellationLines 是你加载的星座连线数据

// 绘制所有星星
starsData.forEach(star => {
    const { x, y } = convertRaDecToXY(star.ra, star.dec, canvas.width / 2, canvas.height / 2, 5); // 5是一个示例缩放因子
    const radius = Math.max(0.5, 3 - star.magnitude * 0.2); // 视星等越小越亮,半径越大
    drawStar(x, y, radius, '#FFF'); // 或者根据星等调整颜色
});

// 绘制星座连线
constellationLines.forEach(constellation => {
    constellation.lines.forEach(line => {
        const star1 = starsData.find(s => s.name === line[0]);
        const star2 = starsData.find(s => s.name === line[1]);
        if (star1 && star2) {
            const p1 = convertRaDecToXY(star1.ra, star1.dec, canvas.width / 2, canvas.height / 2, 5);
            const p2 = convertRaDecToXY(star2.ra, star2.dec, canvas.width / 2, canvas.height / 2, 5);
            drawLine(p1.x, p1.y, p2.x, p2.y, '#00F', 1);
        }
    });
});

整合真实数据意味着你需要处理数据加载(例如,使用

fetch
API加载JSON文件)、数据解析以及最关键的坐标转换逻辑。这是一个相对复杂的工程,但成果会非常有成就感。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

754

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

636

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

758

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

618

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1262

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

577

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

707

2023.08.11

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

6

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

AngularJS教程
AngularJS教程

共24课时 | 2.6万人学习

CSS教程
CSS教程

共754课时 | 19.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号