纯 SVG + CSS 实现月相动态变化

📅 2019年09月14日 / 🎨 开发日志 / 👓 1572


中秋佳节,宜 Coding。

文末有 在线 DEMO 和源码。

前言

中秋节赏月,不免多关注了些月亮相关的信息,然后引发了思考。不过并不是「举头望明月,低头思故乡」,而是——怎么把月相变化 Coding 出来(??? 黑人问号.jpg

关于「月相」的科普,一图胜千言:

月相规律
(网络图侵删)

图片可能一开始看不太明白,可以看下 视频教程(Bilibili) 能够有更直观的理解。

在开始之前想一下用什么方案来实现(桌面不考虑,只考虑浏览器端)。

CSS 是不太可能了,因为要画曲线。

因为之前做项目接触过一点点 SVG 所以第一反应就想到了这个强大的小东西,然后查了一下 SVG 文档,画直线、圆弧、贝赛尔曲线完全不在话下,还要什么自行车?当然还有其他方案如使用 Canvas + Javascript 绘图,这个应该也可以,但是对于我的需求而言过于复杂了,还是 SVG 最合适。

开始「画」月亮

SVG 静态图形

SVG 的教程网上一堆,当然最推荐还是 Mozilla 官方的 SVG 教程

画月亮关键代码:

<svg width="100%" height="100%" viewBox="-0 0 500 500" xmlns="http://www.w3.org/2000/svg">
    <path stroke="#ff0909" fill="white"
    d="M 250 0 A 200 250 0 1, 1 250 500 A 250 250 0 1, 0 250 0 z"/>
</svg>
关键在于 path 元素里面的 d 属性,这个属性很强大,具体用法 看这

从上面的 svg 代码我们可以预览到图像:

svg预览

我们把 d 属性值改为 M 250 0 A 100 250 0 1, 1 250 500 A 250 250 0 1, 0 250 0 z 再次预览:

svg预览2

根据这个规律,我们只要知道怎么使用 path,动态改变其中的 d 属性的值,就能实现图形的动态变化。

SVG 动画

SVG 的强大不止于画静态矢量图,搭配 CSS Animation 食用味道更佳 实现 SVG 动画就无敌了。

也只贴 CSS 关键部分:

.path {
    animation: moonAniSimple 20s ease-in-out infinite;
}

@keyframes moonAniSimple {
    /* 新月 */
    0% {
        d: path("M 250 0 A 250 250 0 1, 1 250 500   A 250 250 0 1, 0 250 0 z");
    }
    /* 上弦月 */
    25% {
        d: path("M 250 0 A 0 250 0 1, 1 250 500     A 250 250 0 1, 0 250 0 z");
    }
    /* 下略... */
}

CSS 动画部分和正常用没太多区别,唯一区别在于它要改变 path 上的 d 属性必须要这么写:d: path(VALUE)

源码

其他的没啥可说了。

Talk is cheap, watch the code.

这个小项目已被收录在个人 实验室 中。

参考

(完)

留言(0)