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>天秤座 (9月23日 ~ 10月23日)</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 libraStars = [{name: "氐宿四",x: 0.43,y: 0.3,magnitude: 2.7,color: "#FFFFC3"},{name: "氐宿一",x: 0.53,y: 0.45,magnitude: 3.9,color: "#42A5F5"},{name: "氐宿三",x: 0.35,y: 0.4,magnitude: 2.6,color: "#FFA726"},{name: "氐宿增一",x: 0.5,y: 0.62,magnitude: 4.6,color: "#FFF59D"},{name: "折威七",x: 0.53,y: 0.66,magnitude: 4.4,color: "#64B5F6"},{name: "氐宿二",x: 0.38,y: 0.51,magnitude: 4.0,color: "#FFCCBC"},{name: "氐宿五",x: 0.365,y: 0.575,magnitude: 4.3,color: "#FFCC80"},{name: "氐宿增五",x: 0.35,y: 0.64,magnitude: 4.8,color: "#E6EE9C"}];// 天秤座星座连线const starConnections = [// 秤杆[0 ,1],[1, 2],[2, 0],// 秤盘[1, 3],[3, 4],[2,5],[5,6],[6,7]];// 初始化随机星星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});}// 添加星座星星libraStars.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 < libraStars.length && endIndex < libraStars.length) {const start = stars[stars.length - libraStars.length + startIndex];const end = stars[stars.length - libraStars.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();}});}// 绘制星座星星libraStars.forEach((star, index) => {const starObj = stars[stars.length - libraStars.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 libraStars = [{name: "氐宿四",x: 0.43,y: 0.3,magnitude: 2.7,color: "#FFFFC3"
}, {name: "氐宿一",x: 0.53,y: 0.45,magnitude: 3.9,color: "#42A5F5"
}, {name: "氐宿三",x: 0.35,y: 0.4,magnitude: 2.6,color: "#FFA726"
}, {name: "氐宿增一",x: 0.5,y: 0.62,magnitude: 4.6,color: "#FFF59D"
}, {name: "折威七",x: 0.53,y: 0.66,magnitude: 4.4,color: "#64B5F6"
}, {name: "氐宿二",x: 0.38,y: 0.51,magnitude: 4.0,color: "#FFCCBC"
}, {name: "氐宿五",x: 0.365,y: 0.575,magnitude: 4.3,color: "#FFCC80"
}, {name: "氐宿增五",x: 0.35,y: 0.64,magnitude: 4.8,color: "#E6EE9C"
}];// 天秤座星座连线
const starConnections = [// 秤杆[0, 1],[1, 2],[2, 0],// 秤盘[1, 3],[3, 4],[2, 5],[5, 6],[6, 7]
];
结语
本文主要讲解了如何通过Canvas绘制天秤座星座图,后续会继续使用Canvas绘制其余星座。对于文章中错误的地方或者有任何问题,欢迎在评论区留言分享!