This is the 28th day of my participation in the Novembermore Challenge.The final text challenge in 2021

introduce

In this issue, we will use SCSS + SVG to complete a simple and practical loading animation — three-color fusion ball. As the name implies, we will make three color balls, transform and rotate them, then fuse them together, and finally repeat the operation.

Let’s take a look at the results directly:

The body of the

1. Infrastructure

<div id="app">
    <div class="loading">
        <div class="loading-circle"></div>
        <div class="loading-circle"></div>
        <div class="loading-circle"></div>
    </div>
</div>
Copy the code
#app{
    width: 100%;
    height: 100vh;
    background-image: repeating-linear-gradient(90deg, hsla(196.0%.79%.0.06) 0px, hsla(196.0%.79%.0.06) 1px,transparent 1px, transparent 96px),repeating-linear-gradient(0deg, hsla(196.0%.79%.0.06) 0px, hsla(196.0%.79%.0.06) 1px,transparent 1px, transparent 96px),repeating-linear-gradient(0deg, hsla(196.0%.79%.0.09) 0px, hsla(196.0%.79%.0.09) 1px,transparent 1px, transparent 12px),repeating-linear-gradient(90deg, hsla(196.0%.79%.0.09) 0px, hsla(196.0%.79%.0.09) 1px,transparent 1px, transparent 12px),linear-gradient(90deg, rgb(255.255.255),rgb(255.255.255));
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
}
.loading{
    width: 200px;
    height: 200px;
    position: relative;
    .loading-circle{
        width: 60px;
        height: 60px;
        border-radius: 50%;
        position: absolute;
        left: 50%;
        top: 50%;
        margin: -30px 0 0 -30px; }}Copy the code

The structure is very simple: div#app. We are going to fill the screen and use repeating-linear-gradient to draw the grid background. Div. loading then makes a square with three small circles positioned absolutely in the center.

2. Ball animation

$colors:rgb(255.208.0),rgb(139.203.255),rgba(252.96.96.0.945);
$duration:2s;

.loading-circle{
    @for $i from 1 through length($colors) {&:nth-child(#{$i}) {
                background-color:nth($colors.$i);
                animation: # {'circle-move-'+$i} $durationinfinite; }}}@keyframes circle-move-1{0%, 20%, 100% {transform: translate(0.0) scale(1)}
    40% {transform: translate(0, -18px) scale(.5)}
    60% {transform: translate(0, -85px) scale(.5)}
    80% {transform: translate(0, -85px) scale(.5)}
}

@keyframes circle-move-2 {
    0%.20%.100%{transform: translate(0.0) scale(1)}
    40% {transform: translate(-16px.12px) scale(.5)}
    60% {transform: translate(-90px.65px) scale(.5)}
    80% {transform: translate(-90px.65px) scale(.5)}
}

@keyframes circle-move-3 {
    0%.20%.100%{transform: translate(0.0) scale(1)}
    40% {transform: translate(16px.12px) scale(.5)}
    60% {transform: translate(90px.65px) scale(.5)}
    80% {transform: translate(90px.65px) scale(.5)}}Copy the code

To get to the point, we need to define two variables with SCSS. One is the colors of the three balls, using the list array in SCSS. The other variable, colors, represents the colors of the three balls, using the list array in SCSS. The other variable, colors, represents the colors of the three balls, using the list array in SCSS. The other variable is duration, which represents the period of our animation.

NTH (colors,colors, colors, I) is used by SCSS to fetch the values of the array. The subscript of $I is different from that of js, and cannot equal 0. If at sign for starts at zero, then an error will be reported.

As for animation, it is to make his three balls shrink in a certain period of time from the middle offset, to a certain extent and then back to repeat, the details will be directly seen in the code, here will not be too verbose.

3. Change the order

.loading-circle{
    @for $i from 1 through length($colors) {&:nth-child(#{$i}) {
                background-color:nth($colors.$i);
                animation: # {'circle-move-'+$i} $duration infinite,change-z-index #{$duration * length($colors) # {} -$duration * $i} infinite; }}}@keyframes change-z-index{
    0%,100%{ 
        z-index: 3; 33}33.% {z-index: 2;
    }
    6666.% {z-index: 1; }}Copy the code

As you saw just now, our three balls are absolutely positioned, so whenever they come together, the bottom one will cover up the other balls. The method used above is to use z-index to set the priority according to the period, and then can be constantly changed.

4. Rotate animation

.loading{
    animation: rotate $duration infinite;
}
@keyframes rotate{
    0%,60%{
        transform: rotate(0deg); Were 80% and 100%} {transform: rotate(360deg); }}Copy the code

At this point, our interface is not cool enough, and we need to let the three of them rotate when they are separated. The code above is that whenever the ball completes a cycle, we let it rotate once. Of course, this animation is directly added to div.loading, not careless added to the ball.

5. Fusion processing

<svg xmlns="http://www.w3.org/2000/svg">
    <defs>
        <filter id="mix">
            <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
            <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 21-7"/>
        </filter>
    </defs>
</svg>
Copy the code
.loading{
    filter: url(#mix);
}
Copy the code

Our problem is how to get them to merge. Many people would think of using CSS filter contrast+blur, but this would not work, because it would pollute the color we want. So here we write a set of filters in SVG. Here, the filter element of SVG is only used as the content of filter operation, and there is nothing to display itself. Use is also through the CSS filter with URL to introduce use. The above code is to do a fuzzy identification process, this code can be general oh. In this way, we are done

So that’s the end of the animation, the online demo.

conclusion

I do not know if you have learned this case, but when I implement it, I feel that SCSS writing is really easy to use, a few words can accomplish a lot of things, and very elegant and easy to maintain. The SVG filter is very obscure, but it’s really powerful. It feels like there’s still a lot to go, and there’s still a lot more effects to be imagined and explored. What are you waiting for? Let’s explore.