canvas绘制星座(黄道十二宫)

2022-08-01,,

canvas绘制黄道十二宫星座

    • 效果图
    • 对照图
    • 准备工作
    • 开始撸代码
    • 白嫖作者的代码

效果图

对照图

准备工作

以下所有片段代码为手敲,难免会有语法错误,请不要复制,文末会发布全部代码
先准备一张"宇宙星空图",设为背景

	<style>
		* {
			margin:0;
			padding:0;
		}
		body {
			background: url(./bg.jpg)
		}
	</style>
	<body>
		<canvas id=""constellation>
			你的浏览器不支持canvas,请升级你的浏览器
		</canvas>
	<body>

开始撸代码

观察对照图,可以看出所有的星座都是“点”与“点”的连线,(绘制小的圆形,达到点的效果)
猜想:直接画几个圆然后连线不就可以了?

 function draw() {
        var canvas = document.getElementById('constellation');
        var w = window.innerWidth;
        var h = window.innerHeight;
        canvas.width = w;
        canvas.height = h;
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        
       // 直接绘制圆点
       ctx.beginPath()
       ctx.arc(100,100,4,0,Math.PI*2,true)
       ctx.arc(400,100,4,0,Math.PI*2,true)
       ctx.arc(100,400,4,0,Math.PI*2,true)
       ctx.fill(); //填充
      
       ctx.beginPath()
       ctx.arc(500,100,4,0,Math.PI*2,true)
       ctx.arc(800,100,4,0,Math.PI*2,true)
       ctx.arc(500,400,4,0,Math.PI*2,true)
       ctx.stroke();//连线
    }

效果
在一个beginPath()中,使用填充方法(ctx.fill)会默认调用闭合方法(ctx.closePath),
连线方式能实现“点”与“点”的连线,但是“点”是空心的,并没有达到想要的效果(实心点)

猜想
单独绘制每个点,使用填充方法,
然后共同绘制,使用连线方法

function draw() {
        var canvas = document.getElementById('constellation');
        var w = window.innerWidth;
        var h = window.innerHeight;
        canvas.width = w;
        canvas.height = h;
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        
       // 单独绘制圆点
       ctx.beginPath()
       ctx.arc(100,100,4,0,Math.PI*2,true)
       ctx.fill(); //填充
       ctx.beginPath()
       ctx.arc(400,100,4,0,Math.PI*2,true)
       ctx.fill(); //填充
       ctx.beginPath()
       ctx.arc(100,400,4,0,Math.PI*2,true)
       ctx.fill(); //填充
       
       // 共同绘制 
       ctx.beginPath()
       ctx.arc(500,100,4,0,Math.PI*2,true)
       ctx.arc(800,100,4,0,Math.PI*2,true)
       ctx.arc(500,400,4,0,Math.PI*2,true)
       ctx.stroke();//连线
    }

效果
可以看到左边的点已经满足,
将“共同绘制的点”坐标,和“单独绘制的点”坐标重合,
不就能模拟出“点”与“点”的连线了吗(坐标重合图)

改进
将“共同绘制的点”,改为“共同绘制的线”

 		// 共同绘制
 		ctx.beginPath()
 		// 这里参数,X轴,Y轴,半径,开始弧度,结束弧度,顺时针/逆时针,
 		// 参数太多了吧,而且我只需要线,不需要圆点
        // ctx.arc(100,100,4,0,Math.PI*2,true)
       	// ctx.arc(400,100,4,0,Math.PI*2,true)
        // ctx.arc(100,400,4,0,Math.PI*2,true)
        // 更改为绘制线
        // 这里需要一个起始点,我使用的方法是1号点的坐标,因为是同一个点,所以对页面无影响
        // 这么写是为了后面的方法调用更方便
        ctx.moveTo(100,100);//起始点
        ctx.lineTo(100,100)
        ctx.lineTo(400,100)
        ctx.lineTo(100,400)
        ctx.stroke();

样式
主体“点线连接”已经实现,那么接下来让它变好看,body添加背景图片,绘制的点、线添加颜色

function draw() {
        var canvas = document.getElementById('constellation');
        var w = window.innerWidth;
        var h = window.innerHeight;
        canvas.width = w;
        canvas.height = h;
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        // 设置连线颜色,填充颜色
        ctx.font = "40px sans-serif"//文字字体
        ctx.strokeStyle = '#bedff8' //连线颜色
        ctx.fillStyle = '#96d0fc' //坐标点颜色
        ctx.shadowBlur = 10; //设置坐标点阴影的模糊级别
        ctx.shadowColor = "#fff" //设置模糊颜色
          // 单独绘制圆点
        ctx.beginPath()
        ctx.arc(100,100,4,0,Math.PI*2,true)
        ctx.fill(); //填充
        ctx.beginPath()
        ctx.arc(400,100,4,0,Math.PI*2,true)
        ctx.fill(); //填充
        ctx.beginPath()
        ctx.arc(100,400,4,0,Math.PI*2,true)
        ctx.fill(); //填充
        
        // 单独绘制线
        ctx.beginPath()
        ctx.moveTo(100,100);//起始点
        ctx.lineTo(100,100)
        ctx.lineTo(400,100)
        ctx.lineTo(100,400)
        ctx.stroke();
    }

效果

提取公共方法
因为要绘制黄道十二宫,12个图形,并且点的坐标很多,所以很有必要提取公共部分,写成方法调用
这里使用的是变量传参的方式,先绘制一个白羊座看看效果

 const coordinatePoint = {
        Aries:{
            name:"Aries",//星座名称
            offsetX: 100,//X轴偏移量,用于定位
            offsetY: 0,//y轴偏移量,用于定位
            point:[//坐标点集合,
                {x:0,y:220},
                {x:120,y:250},
                {x:170,y:280},
                {x:180,y:300},
            ],
        } ,
     }
     
 function draw() {
        var canvas = document.getElementById('constellation');
        var w = window.innerWidth;
        var h = window.innerHeight;
        canvas.width = w;
        canvas.height = h;
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        // 设置连线颜色,填充颜色
        ctx.font = "40px sans-serif"//文字字体
        ctx.strokeStyle = '#bedff8' //连线颜色
        ctx.fillStyle = '#96d0fc' //坐标点颜色
        ctx.shadowBlur = 10; //设置坐标点阴影的模糊级别
        ctx.shadowColor = "#fff" //设置模糊颜色
        Constellation(ctx, coordinatePoint.Aries) //白羊座
    }
    draw()
  // 绘制图形
 function Constellation(ctx, coordinate) {
        // 绘制文字
        ctx.fillText(coordinate.name, coordinate.offsetX, coordinate.offsetY+400);
        // 绘制点
        for (let i of coordinate.point) {
            ctx.beginPath()
            ctx.arc(coordinate.offsetX + i.x, coordinate.offsetY + i.y, 4, 0, Math.PI * 2, true)
            ctx.fill(); //填充
        }

        // 绘制线
        ctx.beginPath()
        // 绘制线必须有起点,这里直接使用的【0】的坐标
        ctx.moveTo(coordinate.offsetX + coordinate.point[0].x,coordinate.offsetY + coordinate.point[0].Y)
        // 在下面的循环中,一样绘制了【0】的坐标,由于坐标重合,页面无变化
        // 在星座图形中,有多个分叉的连线,也是使用的重复坐标
        for (let i of coordinate.point) {
            ctx.lineTo(coordinate.offsetX + i.x, coordinate.offsetY + i.y)
        }
        ctx.stroke(); //连线
    }

白羊座效果图

重复的计算坐标
接下来就是其他星座的坐标计算了,我是通过肉眼观察的,计算的大概位置,并不准确
(计算了2个小时,眼睛已经瞎了)

白嫖作者的代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>constellation星座</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            background: url(./bg.jpg);
        }
    </style>
</head>

<body>
    <canvas id="constellation">
        你的浏览器不支持canvas,请升级你的浏览器
    </canvas>
</body>
<script type="text/javascript">
    const coordinatePoint = {
        Aries:{
            name:"Aries",
            offsetX: 100,
            offsetY: 0,
            point:[
                {x:0,y:220},
                {x:120,y:250},
                {x:170,y:280},
                {x:180,y:300},
            ],
        } ,
         Taurus:{
            name:"Taurus",
            offsetX: 400,
            offsetY: 0,
            point:[
                {x:180,y:300},
                {x:178,y:285},
                {x:120,y:235},
                {x:90,y:205},
                {x:75,y:195},
                {x:60,y:185},
                {x:-10,y:115},
                {x:60,y:185},
                {x:75,y:195},
                {x:90,y:205},
                {x:95,y:185},
                {x:85,y:180},
                {x:85,y:165},
                {x:70,y:130},
                {x:30,y:70},
            ],
         },
         Gemini:{
            name:"Gemini",
            offsetX: 700,
            offsetY: 0,
            point:[
                {x:160,y:300},
                {x:170,y:270},
                {x:50,y:230},
                {x:0,y:210},
                {x:-5,y:185},
                {x:15,y:140},
                {x:30,y:140},
                {x:55,y:145},
                {x:150,y:185},
                {x:190,y:195},
                {x:210,y:190},
                {x:190,y:195},
                {x:170,y:270},
            ],
         },
         Cancer:{
            name:"Cancer",
            offsetX:1000,
            offsetY: 0,
            point:[
                {x:70,y:270},
                {x:65,y:210},
                {x:150,y:240},
                {x:65,y:210},
                {x:50,y:190},
                {x:15,y:150},
            ],
         },
         Leo:{
            name:"Leo",
            offsetX: 1300,
            offsetY: 0,
            point:[
                {x:80,y:50},
                {x:60,y:55},
                {x:55,y:100},
                {x:70,y:120},
                {x:100,y:115},
                {x:130,y:135},
                {x:40,y:235},
                {x:10,y:285},
                {x:10,y:200},
                {x:70,y:120},
            ],
         },
         virgo:{
            name:"virgo",
            offsetX: 1600,
            offsetY: 0,
            point:[
                {x:80,y:50},
                {x:85,y:90},
                {x:75,y:120},
                {x:40,y:130},
                {x:-10,y:120},
                {x:40,y:130},
                {x:45,y:190},
                {x:10,y:220},
                {x:-20,y:280},
                {x:10,y:220},
                {x:45,y:190},
                {x:100,y:210},
                {x:80,y:260},
                {x:60,y:255},
                {x:45,y:305},
                {x:60,y:255},
                {x:80,y:260},
                {x:100,y:210},
                {x:80,y:175},
                {x:75,y:120},
            ],
         },
         Libra: {
            name:"Libra",
            offsetX: 100,
            offsetY: 400,
            point:[
                {x:30,y:220},
                {x:60,y:210},
                {x:70,y:200},
                {x:90,y:160},
                {x:130,y:200},
                {x:120,y:260},
                {x:80,y:280},
                {x:78,y:300},
                {x:80,y:280},
                {x:120,y:260},
                {x:90,y:160},
            ],
         },
         Scorpio: {
            name:"Scorpio",
            offsetX: 400,
            offsetY: 400,
            point:[
                {x:30,y:220},
                {x:10,y:240},
                {x:0,y:250},
                {x:20,y:270},
                {x:60,y:275},
                {x:90,y:265},
                {x:100,y:240},
                {x:110,y:210},
                {x:150,y:160},
                {x:160,y:150},
                {x:180,y:140},
                {x:220,y:120},
                {x:210,y:100},
                {x:220,y:120},
                {x:225,y:140},
                {x:225,y:160},
            ],
         },
         Sagittarius: {
            name:"Sagittarius",
            offsetX: 700,
            offsetY: 400,
            point:[
                {x:100,y:250},
                {x:70,y:270},
                {x:105,y:280},
                {x:70,y:270},
                {x:45,y:230},
                {x:20,y:180},
                {x:25,y:165},
                {x:55,y:130},
                {x:105,y:150},
                {x:130,y:140},
                {x:110,y:100},
                {x:95,y:95},
                {x:65,y:75},
                {x:95,y:95},
                {x:110,y:100},
                {x:125,y:85},
                {x:110,y:100},
                {x:130,y:140},
                {x:145,y:140},
                {x:145,y:140},
                {x:180,y:130},
                {x:195,y:80},
                {x:180,y:130},
                {x:190,y:160},
                {x:220,y:170},
                {x:225,y:160},
                {x:265,y:130},
                {x:225,y:160},
                {x:220,y:170},
                {x:190,y:160},
                {x:190,y:190},
                {x:200,y:200},
                {x:190,y:190},
                {x:190,y:160},
                {x:180,y:130},
                {x:145,y:140},
                {x:120,y:170},
                {x:105,y:150},
            ],
         },
         Gapricorn:{
            name:"Gapricorn",
            offsetX:1000,
            offsetY: 400,
            point:[
                {x:30,y:290},
                {x:35,y:270},
                {x:50,y:250},
                {x:70,y:220},
                {x:100,y:120},
                {x:150,y:220},
                {x:155,y:240},
                {x:130,y:250},
                {x:90,y:275},
                {x:55,y:280},
                {x:30,y:290},
            ],
         },
         Aquarius:{
            name:"Aquarius",
            offsetX:1300,
            offsetY: 400,
            point:[
                {x:150,y:280},
                {x:110,y:250},
                {x:100,y:240},
                {x:60,y:245},
                {x:55,y:280},
                {x:0,y:200},
                {x:5,y:185},
                {x:20,y:170},
                {x:15,y:140},
                {x:70,y:160},
                {x:120,y:150},
                {x:70,y:160},
                {x:15,y:140},
                {x:80,y:90},
                {x:150,y:30},
            ],},
         Pisces:{
            name:"Pisces",
            offsetX:1600,
            offsetY: 400,
            point:[
                {x:-40,y:300},
                {x:-20,y:320},
                {x:0,y:295},
                {x:60,y:295},
                {x:100,y:295},
                {x:150,y:310},
                {x:110,y:260},
                {x:80,y:230},
                {x:65,y:200},
                {x:40,y:130},
                {x:30,y:100},
                {x:15,y:80},
                {x:20,y:50},
                {x:40,y:35},
                {x:70,y:55},
                {x:75,y:80},
                {x:60,y:105},
                {x:30,y:100},
            ],
         },
    }

    function draw() {
        var canvas = document.getElementById('constellation');
        var w = window.innerWidth;
        var h = window.innerHeight;
        canvas.width = w;
        canvas.height = h;
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        // 设置连线颜色,填充颜色
        ctx.font = "40px sans-serif"//文字字体
        ctx.strokeStyle = '#bedff8' //连线颜色
        ctx.fillStyle = '#96d0fc' //坐标点颜色
        ctx.shadowBlur = 10; //设置坐标点阴影的模糊级别
        ctx.shadowColor = "#fff" //设置模糊颜色
        Constellation(ctx, coordinatePoint.Aries) //白羊座
        Constellation(ctx, coordinatePoint.Taurus) //金牛座
        Constellation(ctx, coordinatePoint.Gemini) //双子座
        Constellation(ctx, coordinatePoint.Cancer) //巨蟹座
        Constellation(ctx, coordinatePoint.Leo) //狮子座
        Constellation(ctx, coordinatePoint.virgo) //处女座
        Constellation(ctx, coordinatePoint.Libra) //天秤座
        Constellation(ctx, coordinatePoint.Scorpio) //天蝎座
        Constellation(ctx, coordinatePoint.Sagittarius) //射手座
        Constellation(ctx, coordinatePoint.Gapricorn) //摩羯座
        Constellation(ctx, coordinatePoint.Aquarius) //水瓶座
        Constellation(ctx, coordinatePoint.Pisces) //双鱼座
    }
    draw()
    //绘制图形
    function Constellation(ctx, coordinate) {
        // 绘制文字
        ctx.fillText(coordinate.name, coordinate.offsetX, coordinate.offsetY+400);
        // 绘制点
        for (let i of coordinate.point) {
            ctx.beginPath()
            ctx.arc(coordinate.offsetX + i.x, coordinate.offsetY + i.y, 4, 0, Math.PI * 2, true)
            ctx.fill(); //填充
        }

        // 绘制线
        ctx.beginPath()
        // 绘制线必须有起点,这里直接使用的【0】的坐标
        ctx.moveTo(coordinate.offsetX + coordinate.point[0].x,coordinate.offsetY + coordinate.point[0].Y)
        // 在下面的循环中,一样绘制了【0】的坐标,由于坐标重合,页面无变化
        // 在星座图形中,有多个分叉的连线,也是使用的重复坐标
        for (let i of coordinate.point) {
            ctx.lineTo(coordinate.offsetX + i.x, coordinate.offsetY + i.y)
        }
        ctx.stroke(); //连线
    }
</script>

</html>

刚接触1天的canvas,然后制作的demo,希望各位大佬提出改进的建议。

本文地址:https://blog.csdn.net/sixsixsix_6000/article/details/107505695

《canvas绘制星座(黄道十二宫).doc》

下载本文的Word格式文档,以方便收藏与打印。