“我报名参加金石计划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公分
有了上面的资料,我们可以根据墨线法绘制国旗,如下图:
二、具体实现
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;
}
这样大五角星的三角形就绘制好了,如下图
- 接下来便是通过伪类::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);
}
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);
}
这样就绘制出了四颗小五角星,如下:
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);
}
最后五星红旗就绘制完成了,直接改变宽度就可以生成任意大小的国旗 完整代码
jym国庆都去哪儿玩啊,还是在家躺着,亦或者学习、上分?投票了:
- 🛌 躺
- 🤹 耍
- 📚︎ 学习
- 🎮 上分