手把手教你用CSS绘制五星红旗,喜迎国庆🎉🎉🎉

2,271 阅读7分钟

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第5篇文章,点击查看活动详情

离国庆就几天了,马路两旁的五星红旗已经随处可见了,今天我们就用CSS来画一个五星红旗。废话不多说,直接开整 🚩🚩🚩

一、需求分析

首先我们要明白国旗的一些基本知识

旗帜图案

1、五星红旗制作标准是:先将旗面划分为4个等分长方形,再将左上方长方形划分长宽15×10个方格。大五角星的中心位于该长方形上5下5、左5右10之处。大五角星外接圆的直径为6单位长度。

2、四颗小五角星的中心点,第一颗位于上2下8、左10右5,第二颗位于上4下6、左12右3,第三颗位于上7下3、左12右3,第四颗位于上9下1、左10右5之处。

3、每颗小五角星外接圆的直径均为2单位长度。四颗小五角星均有一角尖正对大五角星的中心点。

4、根据《中华人民共和国国旗法》第四条规定,制作国旗的企业由省、自治区和直辖市的人民政府指定。国旗的长宽之比为3:2。

尺寸规格

根据1949年9月28日中国人民政治协商会议第一届全体会议主席团公布的《国旗制法说明》,中华人民共和国国旗之通用尺度定为如下五种,各界酌情选用:

甲、长288公分,高192公分。

乙、长240公分,高160公分。

丙、长192公分,高128公分。

丁、长144公分,高96公分。

戊、长96公分,高64公分

有了上面的资料,我们可以根据墨线法绘制国旗,如下图:

v2-6550c655c607a10a0f59b6bff5e031e4_r.png

二、具体实现

1. 绘制一个3:2红色背景的旗面,并定义宽高,背景和五角星颜色

<div class="flag">
  <div class="star-five-big"></div>
  <div class="star-five-small one"></div>
  <div class="star-five-small two"></div>
  <div class="star-five-small three"></div>
  <div class="star-five-small four"></div>
</div>
:root {
  --width: 300px;
  --height: calc(var(--width) * 2 / 3);
  --bg-color: #F40002;
  --star-color: #FAF408;
}
.flag {
  position: relative;
  margin: 0 auto;
  width: var(--width);
  height: var(--height);
  background: var(--bg-color);
}

2. 绘制大五角星⭐︎

  • 绘制的思想是首先绘制三角形🛆BGE,然后通过旋转三角形🛆BGE正72°和-72°就可以绘制出一个五角星(圆是360°,ABCDE五个点五等分,所以旋转角度是360°/5 = 72°)

五星红旗制作标准是:先将旗面划分为4个等分长方形,再将左上方长方形划分长宽15×10个方格。大五角星的中心位于该长方形上5下5、左5右10之处。大五角星外接圆的直径为6单位长度

  • 首先按照墨线法标准,我们将左上角区域划分为10*15的格子,每个格子为一个grid,那么大五角星外切圈的半径就是3*grid
:root {
  --width: 300px;
  --height: calc(var(--width) * 2 / 3);
  --bg-color: #F40002;
  --star-color: #FAF408;
  --grid: calc(var(--width) / 2 / 15); // 一个方格
  --radius: calc(var(--grid) * 3); // 大五角星外切圈半径
}
  • 根据正五角星的数学特性,∠OEL=18°,∠GEL=36°,OE为外切圆半径就是radius,那么根据数学公式:
    sin18° = OL / OE => OL = sin18° * OE
    cos18° = EL / OE => EL = cos18° * OE
    tan36° = GL / EL => GL = tan36° * EL

根据js计算可以得出

sin18° = Math.sin(18 * Math.PI / 180) = 0.3090169943749474
cos18° = Math.cos(18 * Math.PI / 180) = 0.9510565162951535
tan36° = Math.tan(36 * Math.PI / 180) = 0.7265425280053608

所以的得出OL,EL,aL的长度,这样就可以绘制出三角形🛆BaE
🛆BaE距离顶部和左边的距离计算方法:
大五角星外切圈圆心 (5 * grid, 5 * grid) => (5 * grid - EL, 5 * grid - OL)

.star-five-big {
  position: absolute;
  top: calc(5 * var(--grid) - var(--OL));
  left: calc(5 * var(--grid) - var(--EL));
  width: 0;
  height: 0;
  border-color: var(--star-color) transparent transparent;
  border-width: var(--GL) var(--EL);
  border-style: solid;
}

这样大五角星的三角形就绘制好了,如下图

image.png

  • 接下来便是通过伪类::before和::after旋转三角形正72°和-72°就可以得到五角星了
.star-five-big {
  position: absolute;
  top: calc(5 * var(--grid) - var(--OL));
  left: calc(5 * var(--grid) - var(--EL));
  width: 0;
  height: 0;
  border-color: var(--star-color) transparent transparent;
  border-width: var(--GL) var(--EL);
  border-style: solid;
}

.star-five-big::before {
  position: absolute;
  top: calc(var(--GL) * -1);
  left: calc(var(--EL) * -1);
  content: '';
  display: block;
  width: 0;
  height: 0;
  border-color: var(--star-color) transparent transparent;
  border-width: var(--GL) var(--EL);
  border-style: solid; 
  transform: rotate(72deg);
  transform-origin: var(--EL)  var(--OL); 
}

.star-five-big::after {
  position: absolute;
  top: calc(var(--GL) * -1);
  left: calc(var(--EL) * -1);
  content: '';
  display: block;
  width: 0;
  height: 0;
  border-color: var(--star-color) transparent transparent;
  border-width: var(--GL) var(--EL);
  border-style: solid;
  transform: rotate(-72deg);
  transform-origin: var(--EL) var(--OL); 
}

image.png

3. 绘制小五角星⭐︎

四颗小五角星的中心点,第一颗位于上2下8、左10右5,第二颗位于上4下6、左12右3,第三颗位于上7下3、左12右3,第四颗位于上9下1、左10右5之处

⭐︎有了大五角星,小五角星是大五角星的三分之一,只要算出小五角星绝对定位的top和left距离就可以了,根据四个小五角星外切圆圆心和基点位置,可以得出四个小五角星的位置

⭐︎第一颗:(10 * grid, 2 * grid) => (10 * grid - EL / 3, 2 * grid - OL / 3)
⭐︎第二颗:(12 * grid, 4 * grid) => (12 * grid - EL / 3, 4 * grid - OL / 3)
⭐︎第三颗:(12 * grid, 7 * grid) => (12 * grid - EL / 3, 7 * grid - OL / 3)
⭐︎第四颗:(10 * grid, 9 * grid) => (10 * grid - EL / 3, 9 * grid - OL / 3)

.star-five-small {
  position: absolute;
  width: 0;
  height: 0;
  border-color: var(--star-color) transparent transparent;
  border-width: calc(var(--GL) / 3) calc(var(--EL) / 3);
  border-style: solid;
  transform-origin: calc(var(--EL) / 3) calc(var(--OL) / 3);
}

.star-five-small::before {
  position: absolute;
  top: calc(var(--GL) * -1 / 3);
  left: calc(var(--EL) * -1 / 3);
  content: '';
  display: block;
  width: 0;
  height: 0;
  border-color: var(--star-color) transparent transparent;
  border-width: calc(var(--GL) / 3) calc(var(--EL) / 3);
  border-style: solid;
  transform: rotate(72deg);
  transform-origin: calc(var(--EL) / 3) calc(var(--OL) / 3); 
}

.star-five-small::after {
  position: absolute;
  top: calc(var(--GL) * -1 / 3);
  left: calc(var(--EL) * -1 / 3);
  content: '';
  display: block;
  width: 0;
  height: 0;
  border-color: var(--star-color) transparent transparent;
  border-width: calc(var(--GL) / 3) calc(var(--EL) / 3);
  border-style: solid;
  transform: rotate(-72deg);
  transform-origin: calc(var(--EL) / 3) calc(var(--OL) / 3);
}

.one {
  top: calc(2 * var(--grid) - var(--OL) / 3);
  left: calc(10 * var(--grid) - var(--EL) / 3);
}

.two {
  top: calc(4 * var(--grid) - var(--OL) / 3);
  left: calc(12 * var(--grid) - var(--EL) / 3);
}

.three {
  top: calc(7 * var(--grid) - var(--OL) / 3);
  left: calc(12 * var(--grid) - var(--EL) / 3);  
}

.four {
  top: calc(9 * var(--grid) - var(--OL) / 3);
  left: calc(10 * var(--grid) - var(--EL) / 3); 
} 

这样就绘制出了四颗小五角星,如下:

image.png

4. 旋转小五角星⭐︎

上面的四颗小五角星还没旋转角度,我们要计算出每个小五角星的旋转角度,首先算出大五角星外切圆圆心和每个小五角星外切圆圆心的角度,如下:
⭐︎第一颗:Math.atan(3 / 5) * 180 / Math.PI ≈ 30.96°
⭐︎第二颗:Math.atan(1 / 7) * 180 / Math.PI ≈ 8.13°
⭐︎第三颗:Math.atan(2 / 7) * 180 / Math.PI ≈ 15.94°
⭐︎第四颗:Math.atan(4 / 5) * 180 / Math.PI ≈ 38.66°

最后还要加减18°(18°为五角星外部角的一半值),得到-48.96°,-26.13°,-2.06,20.66这几个数据。

.one {
  top: calc(2 * var(--grid) - var(--OL) / 3);
  left: calc(10 * var(--grid) - var(--EL) / 3);
  transform: rotate(-48.96deg);
}

.two {
  top: calc(4 * var(--grid) - var(--OL) / 3);
  left: calc(12 * var(--grid) - var(--EL) / 3);
  transform: rotate(-26.13deg);
}

.three {
  top: calc(7 * var(--grid) - var(--OL) / 3);
  left: calc(12 * var(--grid) - var(--EL) / 3);
  transform:rotate(-2.06deg);  
}

.four {
  top: calc(9 * var(--grid) - var(--OL) / 3);
  left: calc(10 * var(--grid) - var(--EL) / 3);
  transform:rotate(20.66deg);  
} 

image.png 最后五星红旗就绘制完成了,直接改变宽度就可以生成任意大小的国旗 完整代码

jym国庆都去哪儿玩啊,还是在家躺着,亦或者学习、上分?投票了:

  1. 🛌 躺
  2. 🤹‍ 耍
  3. 📚︎ 学习
  4. 🎮 上分