乐趣区

关于前端:使用-CSS-绘制带有动画效果的-React-Logo

筹备工作

本来想着是不是写“用一个 div 绘制 React Logo”,最初想想,就算用一个 div 实现了,那么对于前面可能要增加的成果就会有很大的局限性,于是就放弃了这样的题目。至于 HTML 构造中,div 的应用也不是很多,就上面这样的构造而已。

<div class="react">
    <div class="logo"></div>
</div>

先看一下简略的,参考 react 官网上的 Logo 展现成果。

整个实现的过程也很简略,毕竟这个不是简单的图形,同时在绘制的过程中也并没有齐全 100% 截然不同去克隆,只不过是在形体上看着类似而已。比方以下几点就是比拟随性去解决的:

  • 椭圆局部的旋转角度;
  • 核心圆点大小;
  • 各个椭圆的大小;

开始绘制

React 的 Logo 中那三个椭圆局部大小假如是雷同的,那么就只有绘制了横向的椭圆之后,再通过 ::before::after 去旋转,扭转一下角度就好了。

构思好要害的局部,那么就开始着手写 CSS 代码吧。

.react {
    position: relative;
    width: 250px;
    height: 250px;
    color: rgb(1, 216, 255);
}

通过取色器获取 React Logo 图片上的色彩值,而后限定一个宽高给外围。✏️这里须要留神一点,把色彩值写入到 color 中的次要目标。

🔖在 CSS 中有一个 currentColor 属性值,是能够间接获取到以后所继承的色彩值,而 color 是可继承的,并且个别属性如果没有写色彩值的话,是间接继承 color 的值。所以,当咱们在父级元素上写了 color 值,前面很多中央的色彩值就能够省略了。

接着绘制椭圆局部。

.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 的子元素。

因为应用了 absolute 定位,所以,这个时候能够在页面上看到“一个”椭圆。当初要对伪元素进行旋转的操作了。

.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…

退出移动版