欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-28 13:40:49
canvas绘制黄道十二宫星座效果图对照图准备工作开始撸代码白嫖作者的代码效果图对照图准备工作(以下所有片段代码为手敲,难免会有语法错误,请不要复制,文末会发布全部代码)先把准备一张"宇宙星空图",设为背景

效果图

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

对照图

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),
连线方式能实现“点”与“点”的连线,但是“点”是空心的,并没有达到想要的效果(实心点)
canvas绘制星座(黄道十二宫)
canvas绘制星座(黄道十二宫)
猜想
单独绘制每个点,使用填充方法,
然后共同绘制,使用连线方法

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();//连线
    }

效果
可以看到左边的点已经满足,
将“共同绘制的点”坐标,和“单独绘制的点”坐标重合,
不就能模拟出“点”与“点”的连线了吗(坐标重合图)
canvas绘制星座(黄道十二宫)
canvas绘制星座(黄道十二宫)
改进
将“共同绘制的点”,改为“共同绘制的线”

 		// 共同绘制
 		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();
    }

效果
canvas绘制星座(黄道十二宫)
提取公共方法
因为要绘制黄道十二宫,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(); //连线
    }

白羊座效果图
canvas绘制星座(黄道十二宫)
重复的计算坐标
接下来就是其他星座的坐标计算了,我是通过肉眼观察的,计算的大概位置,并不准确
(计算了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