准备工做
本来想着是否是写“用一个 div 绘制 React Logo”,最后想一想,就算用一个 div 实现了,那么对于后面可能要添加的效果就会有很大的局限性,因而就放弃了这样的标题。至于 HTML 结构中,div 的使用也不是不少,就下面这样的结构而已。css
<div class="react">
<div class="logo"></div>
</div>
先看一下简单的,参考 react 官网上的 Logo 展现效果。html
整个实现的过程也很简单,毕竟这个不是复杂的图形,同时在绘制的过程当中也并无彻底 100% 如出一辙去克隆,只不过是在形体上看着类似而已。好比如下几点就是比较随性去处理的:react
- 椭圆部分的旋转角度;
- 中心圆点大小;
- 各个椭圆的大小;
开始绘制
React 的 Logo 中那三个椭圆部分大小假设是相同的,那么就只要绘制了横向的椭圆以后,再经过 ::before
和 ::after
去旋转,改变一下角度就行了。segmentfault
构思好关键的部分,那么就开始着手写 CSS 代码吧。动画
.react {
position: relative;
width: 250px;
height: 250px;
color: rgb(1, 216, 255);
}
经过取色器获取 React Logo 图片上的颜色值,而后限定一个宽高给外围。✏️这里须要注意一点,把颜色值写入到 color
中的主要目的。ui
🔖在 CSS 中有一个 currentColor
属性值,是能够直接获取到当前所继承的颜色值,而 color
是可继承的,而且个别属性若是没有写颜色值的话,是直接继承 color
的值。因此,当咱们在父级元素上写了 color
值,后面不少地方的颜色值就能够省略了。spa
接着绘制椭圆部分。3d
.logo,
.logo::after,
.logo::before {
position: absolute;
top: 50%;
left: 0;
width: 250px;
height: 100px;
border: 10px solid;
border-radius: 50%;
box-sizing: border-box;
transform: translateY(-50%);
z-index: 1;
}
注意:这里的高度是目测猜测的高度值,宽度是为了撑满容器,不用 100%
做为宽度值,由于这里还有 ::after
和 ::before
这两个伪元素。若是用了 100%
的话,这两个伪元素宽度就要比横向的要小一些了,由于伪元素是 .logo
的子元素。code
由于使用了 absolute
定位,因此,这个时候能够在页面上看到“一个”椭圆。如今要对伪元素进行旋转的操做了。orm
.logo::after,
.logo::before {
content: '';
left: -12px;
transform: rotate(58deg) translate3d(-50px, -25px, 0);
}
.logo::after {
transform: rotate(-58deg) translate3d(50px, -25px, 0);
}
就能够获得这样的一个图形了。
这里须要注意的是,当咱们旋转的时候,虽然中心圆点是 center center
,但旋转后会有位置的偏移,所以须要再对 X 轴和 Y 轴作偏移调整 translate3d(50px, -25px, 0)
。这里的偏移以及旋转的角度都是目测而已。
完成绘制
有了基本的轮廓,剩下还有中心那个圆点。这个就简单了,直接用 .react
的伪元素画一个圆,而后定位到中间就行了。
.react::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 42px;
height: 42px;
background-color: currentcolor;
border-radius: 50%;
transform: translate3d(-50%, -50%, 0);
z-index: 2;
}
而后就能够获得这个最终的 Logo 图形了。
在这个圆形的时候,能够看到使用了 background-color: currentcolor;
,而在画椭圆使用边框时则是 border: 10px solid;
。由于 background-color
不会继承 color
的颜色值,而 border-color
在未定义的时候,是使用 color
颜色值的。
改变一下
基础款的 React Logo 用 CSS 绘制好了,接着改变一下,把 border
换成 box-shadow
,经过阴影来实现一个线条不均匀的 Logo。
丑不丑呢,好像是挺丑的,但感受是不同了🤣……
实现的方式也简单,就是把边框 border
啥的都去掉,直接用 box-shadow
就行了。
.logo,
.logo::after,
.logo::before {
position: absolute;
top: 50%;
left: 0;
width: 250px;
height: 100px;
/* border: 10px solid; */
border-radius: 50%;
/* box-sizing: border-box; */
transform: translateY(-50%);
box-shadow: 10px -2px 2px 7px;
z-index: 1;
}
.logo::after,
.logo::before {
content: '';
/* left: -12px; */
transform: rotate(58deg) translate3d(-50px, -25px, 0);
box-shadow: 7px -4px 2px 6px;
}
.logo::after {
transform: rotate(-58deg) translate3d(50px, -25px, 0);
box-shadow: -4px -8px 2px 8px;
}
去掉 left: -12px;
是由于边框没了,盒模型的宽度就变化了。
这里须要注意,box-shadow
中并无加上颜色值,缘由在上面介绍过,同理。
动起来
要想动起来,那就是加上一个 animation
动画就行了,效果大概就是这样了。
看着好像是弧形的效果在动,其实只是改变了阴影了位置而已。在动画的过程当中,顺便把阴影的值也修改了一下。
@keyframes runLogoPseudo {
0%, 100% {
box-shadow: 10px -4px 2px 1px;
}
25% {
box-shadow: 10px 4px 2px 1px;
}
50% {
box-shadow: -10px 4px 2px 1px;
}
75% {
box-shadow: -10px -4px 2px 1px;
}
}
@keyframes runLogo {
0%, 100% {
box-shadow: 7px -2px 5px;
}
25% {
box-shadow: 7px 2px 5px;
}
50% {
box-shadow: -7px 2px 5px;
}
75% {
box-shadow: -7px -2px 5px;
}
}
如今能看到的效果,中间的圆形是不会有任何变化的,因此,稍微再加一点动画帧。
@keyframes blink {
0%, 100% {
transform: scale(1) translate3d(-50%, -50%, 0);
box-shadow: 0 0 15px;
opacity: 1;
}
60% {
transform: scale(1.05) translate3d(-50%, -50%, 0);
box-shadow: none;
opacity: .8;
}
}
这样,小圆圈也就有一个相似“呼吸”的感受了,应该有的吧。无所谓了,反正是有动画效果了。
最后关键的部分来了,就是要让动画动起来。
.react::after {
animation: blink 1.5s 0s infinite ease-in-out;
}
靠感受把闪动的效果加在小圆点上。
.logo,
.logo::after,
.logo::before {
/* box-shadow: 10px -2px 2px 7px; */
animation: runLogo 1s 0s infinite linear;
}
.logo::after,
.logo::before {
/* box-shadow: 10px -4px 2px 1px; */
animation-name: runLogoPseudo;
}
.logo::after {
/* box-shadow: -4px -8px 2px 8px; */
animation-direction: alternate;
}
- 首先经过
animation: runLogo 1s 0s infinite linear;
让三个椭圆都有相同的动画效果; - 接着改变伪元素中的动画帧名称
animation-name: runLogoPseudo;
,去选择对应的动画效果; - 最后改变其中一个伪元素的动画方向,让两个倾斜的椭圆运动方向是相反的
animation-direction: alternate;
,造成不一样的视差感受; - 最后的最后,既然这个动画是
infinite
无限运动,那么就去掉box-shadow
的值吧,在@keyframes
中有对应的box-shadow
属性了;
还有吗?
我这边如今是没有了,若是有兴趣的话,能够考虑结合渐变色实现边框,而后滚动起来,也能够结合 mix-blend-mode
混合模式玩一些好玩的。这些就是看具体的创意想法了……
效果预览
https://codepen.io/linxz/pen/...
首发于我的公众号「志语自乐」, https://mp.weixin.qq.com/s/83...