用纯 CSS 绘制一朵美丽的雪花

前端阳光

共 8588字,需浏览 18分钟

 ·

2021-03-27 08:06

问:如果用css 实现转动的雪花效果

一、动态效果预览

复制跳转下方连接可以去查看动态效果

https://codepen.io/comehope/pen/LYEeRBb

二、源代码下载

https://github.com/comehope/front-end-daily-challenges

三、代码解读

定义 DOM 结构、页面背景和容器尺寸

最外层容器是一个名为 .snowflake<figure> 元素,内含 6 个 <div> 元素,分别代表雪花的6个花瓣,每个 <div> 中又包含 5 个 <span> 元素,每个 <span> 代表雪花上的冰凌。

<figure class="snowflake">
    <div>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
    <div>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
    <div>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
    <div>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
    <div>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
    <div>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
</figure>

页面背景取黑色,雪花取白色,并为容器画出黄色的轮廓作为辅助线,雪花图案将绘制在这个黄色虚线框内:

body {
    margin0;
    height100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: black;
    overflow: hidden;
}

.snowflake {
    font-size100px;
    color: snow;
    width4em;
    height4em;
    outline1px dashed yellow;
}

效果如下图:

绘制出6个花瓣

先绘制出1个花瓣中间的竖线:

div {
    width0.1em;
    height2em;
    background-color: currentColor;
    border-radius0.05em;
}

知识点:currentColor的值即表示color的值

效果如下图:

发现6个花瓣的竖线重叠在一起了,把它们合并到一起,看起来就像只有1条竖线:

div {

position: absolute;
}

效果如下图:

分别旋转每个花瓣,一共6个花瓣,所以各花瓣的旋转角度均相差60度:

div {
    transform-origin: bottom;
    transformrotate(calc((var(--n)  - 1)* 60deg));
}

div:nth-child(1) {--n1;}
div:nth-child(2) {--n2;}
div:nth-child(3) {--n3;}
div:nth-child(4) {--n4;}
div:nth-child(5) {--n5;}
div:nth-child(6) {--n6;}

知识点:原来原生css也可以定义变量 效果如下图:

绘制花瓣上的冰凌

接下来修饰花瓣,绘制花瓣上的冰凌。

先来出顶端的圆点,用 <div>里的第1个 <span> 元素实现:

div {
    display: flex;
    flex-direction: column;
    align-items: center;
}

div span:nth-child(1) {
    width0.2em;
    height0.2em;
    background-color: currentColor;
    border-radius50%;
}

效果如下图:

然后增加离圆点最近的折线,用第 2 个 <span> 元素画出,这是用一个正方形4条边框中的2条实现的:

div span:nth-child(2) {
    width0.5em;
    height0.5em;
    border0.1em solid;
    border-width0.1em;
    border-style: none solid solid none;
    border-radius0.05em;
}

效果如下图:

把折线旋转45度,让它的尖部和竖线重合:

div span:nth-child(2) {
    transformrotate(45deg);
}

效果如下图:

增加第2条折线,和上面的代码类似,只是正方形的边长从 0.5em 缩短到 0.4em 了:

div span:nth-child(3) {
    width0.4em;
    height0.4em;
    border0.1em solid;
    border-width0.1em;
    border-style: none solid solid none;
    border-radius0.05em;
    transformrotate(45deg);
}

效果如下图:

再增加第3条折线:

div span:nth-child(4) {
    width0.3em;
    height0.3em;
    border0.1em solid;
    border-width0.1em;
    border-style: none solid solid none;
    border-radius0.05em;
    transformrotate(45deg);
}

效果如下图:

再增加第4条折线:

div span:nth-child(4) {
    width0.3em;
    height0.3em;
    border0.1em solid;
    border-width0.1em;
    border-style: none solid solid none;
    border-radius0.05em;
    transformrotate(45deg);
}

效果如下图:

你已经发现上面 4 条折线的代码有很多重复的,坚决不能忍,来重构吧,把这 4 段代码合并起来:

div span:nth-child(2),
div span:nth-child(3),
div span:nth-child(4),
div span:nth-child(5) {
    widthvar(--side-length);
    heightvar(--side-length);
    border0.1em solid;
    border-width0.1em;
    border-style: none solid solid none;
    border-radius0.05em;
    transformrotate(45deg);
}

div span:nth-child(2) {--side-length0.5em;}
div span:nth-child(3) {--side-length0.4em;}
div span:nth-child(4) {--side-length0.3em;}
div span:nth-child(5) {--side-length0.3em;}

最后,让第1条折线离中心稍远点,这样还能让雪花中心更加漂亮:

div span:nth-child(2) {
    margin-top: -0.2em;
}

效果如下图:

增加动画效果

动画效果很简单,就是转啊转地,让这片雪花用10秒时间转一圈:

.snowflake {
    animation: round 10s linear infinite;
}

@keyframes round {
    to {
        transformrotate(1turn);
    }
}

知识点:1turn表示一圈

效果如下图:

(动图太大看不了,可以去文章开头的效果展示提供的网址看哈)

最后,删除掉辅助助线:

.snowflake {
    /* outline: 1px dashed yellow; */
}

效果如下图:

(动图太大看不了,可以去文章开头的效果展示提供的网址看哈)

大功告成!

四、参考

  • flex 布局,《CSS3 艺术》第1.8.1节
  • 边框属性 border,《CSS3 艺术》第3.1节
  • 变量 var() 和 表达式 calc(),《CSS3 艺术》第7.1节
  • 变换旋转函数 rotate(),《CSS3 艺术》第8.1.2节
  • 变换原点 transform-origin,《CSS3 艺术》第8.2节
  • 动画 animation,《CSS3 艺术》第10章

原文出处:https://segmentfault.com/a/1190000021497721

CSS真是神秘~

针对这个题目,你的解决方案又是什么呢?

不妨在下面的留言给出,学习共勉下~

码字不易,走过路过来个赞可否👍先谢谢了!

ε=ε=ε=┏(゜ロ゜;)┛

最后

有疑问的同学 欢迎 评论区讨论,也欢迎大家加入我的前端技术交流群 来讨论。搜索《前端阳光》公众号,回复加群吧!



浏览 44
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报