Writing in the front

In a technology-related group, a student attending the youth training camp of a big factory showed his next idea, which involved the use of a Loading animation component in part. For my junior student, the component screenshots he showed have reached the standard for an ordinary Loading, but I, a social layman who has no chance to participate in the work, could not resist writing a more similar effect after seeing it. Although a job has been a period of time, but in the actual work is also very little use CSS to do this kind of wheels, are mostly from the component, so from began planning to write last night, to found the wrong idea, adjust to the idea finally finished the total spent nearly two hours, think I configure a Gitlab also only then five hours, learn skills is not jing is very ashamed, I also spent ten minutes looking through official SCSS documents.

The final effect display is completed

The renderings are GIF renderings from an MP4 recording, so they look a bit frame-free, but the effect is very smooth (FFMPEG is still not proficient).

Look at the code

WindowsLoading (codepen.io)

The development process

Demand analysis

Although the animation effect is very simple, but before the development of the actual development should be clear about what to do, I spent two hours in development, more than half of which were spent on the wrong idea of implementation, not only difficult to achieve, and no effect was achieved, very painful. However, after observing the dynamic effect of Window loading for many times, it took less than half an hour to adjust my thinking. In the animation, it is nothing more than the process of five white balls rotating around the center of a circle, and at the beginning, it is a completely transparent process to opaque process. The rotation is divided into three stages: the first stage is 180 degrees, then the second stage is based on the first stage of rapid rotation 360 degrees, and the third stage is based on the second stage of rotation 180 degrees, and when the rotation is almost complete, slowly become transparent color disappear. However, for convenience, simply remove the second stage, the first stage directly to the third stage, with an infinite loop, the effect is still ok 😆. The animation mentioned above actually matches several CSS properties:

  • Transform: rotate rotation
  • Opacity transparency

In the implementation process, a fixed center of the circle is needed to facilitate the adjustment of the initial position of the ball and the subsequent angular rotation of the axis, so it also needs to use:

  • Transform-origin Indicates the transform center

Transform is an attribute provided by CSS3 to implement shape and position changes. It can be used with transition or animation to create an animation effect.

Code design

Technology selection

Due to the need to produce batch elements, and to batch elements to quickly bind the corresponding CSS style, so HTML and CSS to select the corresponding pre-processing language, convenient for us to quickly build (lazy). The technical options are as follows:

  • Pug
  • Scss

Part of the relation

First we need to build the basic document structure. In the above analysis, the ball rotates around a center, so we need to build a center first

#app // app is the container where the whole world isCopy the code

Then we need to draw the ball, but to note here, as the HTML rendering mechanism problem, our ball no matter through what way, calculate the dot relative to the ball itself. When the loading is in the ball in the upper left corner, so we need a container for we will all ball overall coordinate do an offset, achieve the purpose of on the center of the circle, Easy to add animation can also ensure absolute game. The ball itself should also be noted that if the ball itself wants to set the absolute position relative to the center of the circle, then using position: Absolute, the corresponding left and top can be set to directly simulate the coordinate system xy points. However, setting the ball in this way is not convenient to add subsequent displacement animation. So we split the ball at one level and let the innermost layer wait for the additional animation. When drawing balls, it should be noted that we need exactly five balls, which correspond to the 0 degree, 30 degree, 45 degree, 60 degree and 90 degree angles in the coordinate system. Their subsequent coordinate positions should be almost on the edge of the standard circle. The density of five balls after adding width is also the most appropriate. Here we will use the puG loop:

#app
    .loading
        .wrapper
            for i in Array(5)
                .item
                    .ball 
Copy the code

Scss part

Next, I started to attach styles. Since the ball was white, I first had to make the background black to highlight the white. I chose a neutral black

body {
    background-color: # 333;
}
Copy the code

Then let Loading come to the center of the picture

#app {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
Copy the code

Then adjust the deviation position of the ball, I set the size of the ball to 10px

#app {
    .loading {
        $size: 10px;
        .wrapper {
            $offset# {: -$size/2};
            position: absolute;
            left: $offset;
            top: $offset; }}}Copy the code

Then just draw the ball, using the SCSS @for from Through keyword to create the loop. Due to my poor mathematics, I did not know how to directly calculate the XY coordinates of the five points with the formula in the loop, so I simply chose to directly map the coordinates after calculation in advance in the form of map. It should be noted that to use the SCSS map, the corresponding functional modules should be added using @use.

@use "sass:map";
#app {
    .loading {
        $size: 10px;
        $xyMaps: (
            1: (
                "x": 0px."y": 50px
            ),
            2: (
                "x": 19px."y": 44px
            ),
            3: (
                "x": 35.3 px.."y": 35.3 px.
            ),
            4: (
                "x": 44px."y": 19px
            ),
            5: (
                "x": 50px."y": 0px));.wrapper {
            .ball {
                border: $size/2 solid #fff;
                border-radius: 50%;
                background-color: #fff;
                transform-origin# {: -$offsetX# {} -$offsetY};
            }
            @for $i from 1 through 5 {
                .item:nth-child(#{$i}) {
                    $item: map.get($xyMaps.$i);
                    $offsetX: map.get($item."x");
                    $offsetY: map.get($item."y");
                    position: absolute;
                    left: $offsetX;
                    top: $offsetY;
                    .ball { // Add animation later}
                }
            }
        }
    }
}
Copy the code

Now you can see the general pattern coming out

All that’s left is to write the animation and attach it.

Animation is defined as follows

@keyframes rotate180 {
    0% {
        transform: rotate(0deg);
        opacity: 0; 10%} {opacity: 0.5; 25%} {opacity: 1;
        transform: rotate(180deg); 50%} {transform: rotate(180deg); 70%} {opacity: 1; 71%} {opacity: 0.5; 73%} {opacity: 0; 75%} {transform: rotate(360deg); 100%} {transform: rotate(360deg);
        opacity: 0; }}Copy the code

The definition of animation is very violent, which is to calculate the actions that should be done at each point in time. And then you just attach it

.ball {
    opacity: 0;
    animation: rotate180 2.5 s# {($i - 1) * 0.05}s ease infinite;
}
Copy the code

Here we are 🎉🎉

Write in the last

Writing this animation itself is not complicated, but it requires a little patience and understanding ability. Last night, I started to write when my head was bleeding after eating hot pot, so I almost wanted to give up because of the wrong idea in the middle, but FINALLY I finished writing patiently, which is very congratulatory.

reference

  • Sass: Maps (sass-lang.com)
  • Iteration – relation (pugjs.org)