Canvas实例篇:十二星座之天蝎座
- 前言
- 效果预览
- 代码实现
- 代码说明
- 星座特定星
- 结语
前言
星座总给人浪漫而神秘的感觉,如何用代码还原星空中的浪漫?本文将通过 Canvas 技术,讲述如何实现一个可交互的天蝎座星空图,包含星星闪烁、星座连线、动态效果控制等功能。
效果预览
代码实现
<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>天蝎座星空图</title><style>body,html {margin: 0;padding: 0;width: 100%;height: 100%;overflow: hidden;background-color: #000;}canvas {display: block;position: absolute;top: 0;left: 0;}.constellation-info {position: absolute;bottom: 20px;left: 20px;color: #fff;font-family: Arial, sans-serif;background: rgba(0, 0, 0, 0.5);padding: 10px;border-radius: 5px;}.controls {position: absolute;top: 20px;right: 20px;color: white;font-family: Arial, sans-serif;}button {background: rgba(255, 255, 255, 0.1);color: white;border: 1px solid rgba(255, 255, 255, 0.3);padding: 5px 10px;margin: 5px;cursor: pointer;border-radius: 3px;}button:hover {background: rgba(255, 255, 255, 0.2);}</style></head><body><canvas id="starCanvas"></canvas><div class="constellation-info"><h3>天蝎座 (10月24日 ~ 11月12日)</h3><p>黄道十二宫之一</p><p>象征神秘与力量的星座</p></div><div class="controls"><button id="toggleLines">显示/隐藏连线</button><button id="toggleNames">显示/隐藏星名</button><button id="toggleAnimation">暂停/继续动画</button></div><script>// 获取Canvas元素和绘图上下文const canvas = document.getElementById('starCanvas');const ctx = canvas.getContext('2d');// 设置Canvas尺寸为窗口大小function resizeCanvas() {canvas.width = window.innerWidth;canvas.height = window.innerHeight;}resizeCanvas();window.addEventListener('resize', resizeCanvas);// 存储星星的数组const stars = [];// 天蝎座主星数据const scorpioStars = [{name: "心宿二",x: 0.54,y: 0.41,magnitude: 5.0,color: "#FF5252"},{name: "心宿一",x: 0.6,y: 0.3,magnitude: 2.9,color: "#FFA726"},{name: "心宿三",x: 0.58,y: 0.24,magnitude: 2.8,color: "#FFA726"},{name: "房宿四",x: 0.65,y: 0.4,magnitude: 2.8,color: "#64B5F6"},{name: "房宿三",x: 0.67,y: 0.44,magnitude: 2.9,color: "#FFF59D"}, {name: "尾宿二",x: 0.5,y: 0.7,magnitude: 3.3,color: "#FFCC80"}, {name: "尾宿七",x: 0.4,y: 0.8,magnitude: 2.6,color: "#FFCCBC"}, {name: "尾宿六",x: 0.35,y: 0.85,magnitude: 3.8,color: "#FFCCBC"}, {name: "尾宿四",x: 0.3,y: 0.8,magnitude: 3.4,color: "#FFCCBC"}, {name: "尾宿三",x: 0.28,y: 0.7,magnitude: 2.7,color: "#42A5F5"}, {name: "尾宿五",x: 0.3,y: 0.64,magnitude: 3.0,color: "#FFFFC3"},{name: "尾宿八",x: 0.25,y: 0.66,magnitude: 1.8,color: "#FF5252"},];// 天蝎座星座连线const starConnections = [// 头部[0, 1],[1, 2],[1, 3],[3, 4],// 身体[0, 5],[5, 6],[6, 7],[7, 8],[8, 9],// 尾钩[9, 10],[9, 11]];// 初始化随机星星function initStars(count) {for (let i = 0; i < count; i++) {stars.push({x: Math.random(),y: Math.random(),size: Math.random() * 2,brightness: Math.random(),twinkleSpeed: Math.random() * 0.01});}// 添加星座星星scorpioStars.forEach(star => {stars.push({x: star.x,y: star.y,size: star.magnitude,brightness: 1,isConstellation: true,name: star.name,color: star.color});});}// 绘制星空function drawStars() {// 清空画布ctx.fillStyle = '#000a1a';ctx.fillRect(0, 0, canvas.width, canvas.height);// 绘制背景星星stars.forEach(star => {if (!star.isConstellation) {// 让星星闪烁const twinkle = Math.sin(Date.now() * star.twinkleSpeed) * 0.5 + 0.5;const alpha = star.brightness * twinkle;ctx.fillStyle = `rgba(255, 255, 255, ${alpha})`;ctx.beginPath();ctx.arc(star.x * canvas.width,star.y * canvas.height,star.size,0,Math.PI * 2);ctx.fill();}});// 绘制星座连线if (showLines) {ctx.strokeStyle = 'rgb(255, 255, 255)';ctx.lineWidth = 3;starConnections.forEach(connection => {const startIndex = connection[0];const endIndex = connection[1];// 确保索引有效if (startIndex < scorpioStars.length && endIndex < scorpioStars.length) {const start = stars[stars.length - scorpioStars.length + startIndex];const end = stars[stars.length - scorpioStars.length + endIndex];ctx.beginPath();// 判断画布if (canvas.width > canvas.height) {ctx.moveTo(start.x * canvas.width, start.y * canvas.height);ctx.lineTo(end.x * canvas.width, end.y * canvas.height);} else {ctx.moveTo(start.y * canvas.width, (start.x + 0.1) * canvas.height);ctx.lineTo(end.y * canvas.width, (end.x + 0.1) * canvas.height);}ctx.stroke();}});}// 绘制星座星星scorpioStars.forEach((star, index) => {const starObj = stars[stars.length - scorpioStars.length + index];ctx.fillStyle = starObj.color;ctx.beginPath();// 判断画布if (canvas.width > canvas.height) {ctx.arc(starObj.x * canvas.width,starObj.y * canvas.height,starObj.size + 0.5,0,Math.PI * 2);} else {ctx.arc(starObj.y * canvas.width,(starObj.x + 0.1) * canvas.height,starObj.size + 0.5,0,Math.PI * 2);}ctx.fill();// 添加星名if (showNames) {ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';ctx.font = '12px Arial';if (canvas.width > canvas.height) {ctx.fillText(starObj.name,starObj.x * canvas.width + 8,starObj.y * canvas.height - 8);} else {ctx.fillText(starObj.name,starObj.y * canvas.width + 8,(starObj.x + 0.1) * canvas.height + 8);}}});}// 动画循环function animate() {if (animationRunning) {requestAnimationFrame(animate);}drawStars();}// 控制变量let showLines = true;let showNames = true;let animationRunning = true;// 初始化initStars(2000);animate();// 添加按钮事件document.getElementById('toggleLines').addEventListener('click', () => {showLines = !showLines;});document.getElementById('toggleNames').addEventListener('click', () => {showNames = !showNames;});document.getElementById('toggleAnimation').addEventListener('click', () => {animationRunning = !animationRunning;if (animationRunning) {animate();}});</script></body>
</html>
代码说明
星座特定星
// 天蝎座主星数据
const scorpioStars = [{name: "心宿二",x: 0.54,y: 0.41,magnitude: 5.0,color: "#FF5252"},{name: "心宿一",x: 0.6,y: 0.3,magnitude: 2.9,color: "#FFA726"},{name: "心宿三",x: 0.58,y: 0.24,magnitude: 2.8,color: "#FFA726"},{name: "房宿四",x: 0.65,y: 0.4,magnitude: 2.8,color: "#64B5F6"},{name: "房宿三",x: 0.67,y: 0.44,magnitude: 2.9,color: "#FFF59D"}, {name: "尾宿二",x: 0.5,y: 0.7,magnitude: 3.3,color: "#FFCC80"}, {name: "尾宿七",x: 0.4,y: 0.8,magnitude: 2.6,color: "#FFCCBC"}, {name: "尾宿六",x: 0.35,y: 0.85,magnitude: 3.8,color: "#FFCCBC"}, {name: "尾宿四",x: 0.3,y: 0.8,magnitude: 3.4,color: "#FFCCBC"}, {name: "尾宿三",x: 0.28,y: 0.7,magnitude: 2.7,color: "#42A5F5"}, {name: "尾宿五",x: 0.3,y: 0.64,magnitude: 3.0,color: "#FFFFC3"},{name: "尾宿八",x: 0.25,y: 0.66,magnitude: 1.8,color: "#FF5252"},
];// 天蝎座星座连线
const starConnections = [// 头部[0, 1],[1, 2],[1, 3],[3, 4],// 身体[0, 5],[5, 6],[6, 7],[7, 8],[8, 9],// 尾钩[9, 10],[9, 11]
];
结语
本文主要讲解了如何通过Canvas绘制天蝎座星座图,后续会继续使用Canvas绘制其余星座。对于文章中错误的地方或者有任何问题,欢迎在评论区留言分享!