I am participating in the Mid-Autumn Festival Creative Submission contest, please see: Mid-Autumn Festival Creative Submission Contest for details

preface

I have seen a lot of holiday “programmer romance”, this Mid-Autumn festival is coming, I also come to enjoy. No Canvas, just a simple HTML+CSS+JS three-piece set, well without further ado, let’s directly look at the final animation effect.

(good good don’t scold, soil to the extreme is tide! PS: The flaw in the tail of the rocket in the GIF is a rendering problem with ScreenToGif.

As shown in the picture, there are six elements in the animation: moon, plane, star, rocket, couplet and sea level. We just need to animate them separately, simply lay them out and go!

Element to realize

  • The moon 🌕

What moon? It’s just a div. After setting the width and height, change the border-radius: 50% and set the background to Linear-gradient () to create a circle with a gradient background. To make the circle look more like a light object (the moon itself does not shine), we can set a box-shadow so that the moon looks like the sun.

.moon {
    width: 30vw;
    height: 30vw;
    border-radius: 50%;
    background: linear-gradient(#f1c40f.#f39c12);
    box-shadow: 0px 0px 50px 5px #f39c12;
    position: absolute;
    right: 30%;
    top: 10%;
    animation: moon 5s forwards;
}
Copy the code
  • The plane ✈ ️

Why do you want to put a plane, because the Mid-Autumn Festival is the day of reunion, this plane is carrying home people, carrying a thick feeling of homesickness. Yes, NOT only did I draw a plane, but if you look closely, the passengers in the plane are also my work.

This plane is not a div splice, but uses a CSS3 attribute mask-Image. It can “carve out” the shape we want from a specific stock image, and can customize the background color or background image. I found a transparent vector image of an airplane on the Internet and used this property to make the airplane. For more information about mask-image use scenarios, you can check out my previous article to explore the magic of mask-image — Win10 calendar searchlight effect can be done!

.airplane {
    width: 100px;
    height: 100px;
    background-color: # 000;
    -webkit-mask-image: url(./image/airplane.png);
    -webkit-mask-size: 100px 100px;
    position: absolute;
    right: 10%;
    top: 20%;
    animation: fly 5s ease-in-out forwards;
    z-index: 5;
}
Copy the code
  • The stars ⭐

Since I am too bad to use pure CSS to draw pentagons, I still use mask-image to fix the shape of pentagons. As for the twinkle of stars, I only need to periodically modify opacity. The stars in the sky participate in the Beidou ah! There are so many stars that their positions, sizes, and twinkle states will not be exactly the same. This is where the random function math.random () is introduced to generate random positions, sizes, and flicker states. To prevent stars from falling into the sea, you need to set up an area for them.

The math.random () method is something I feel I need to make a note of to impress myself.

Math.random() [0,1) does not contain 1 math.floor (math.random () * (max-min)) + min [min, Max) integer does not contain Max math.floor (math.random () * (max-min + 1)) + min [min, Max] An integer containing Max

(It occurred to me that I could create a meteor shower. Watching a meteor shower on earth with your partner isn’t more fun than coding? But now that I’ve written it, forget it. Meteor shower says it’s not coming.)

.star {
    position: absolute;
    background-color: #f1c40f;
    width: 20px;
    height: 20px;
    animation: star 3s linear infinite;
    box-shadow: 0px 0px 20px 5px rgb(255 255 255 / 30%);
    -webkit-mask-image: url(./image/star.png);
    -webkit-mask-size: 20px 20px;
}
Copy the code
window.onload = function(){
    let starWrap = document.querySelector('.star-wrap')
    for(let i=0; i<50; i++){let star = document.createElement('div')
        let {posX,posY,size,delay} = createRandom()
        star.className = "star"
        star.style.left = posX
        star.style.top = posY
        star.style.width = star.style.height = size
        star.style.webkitMaskSize = `${size} ${size}`
        star.style.animationDelay = delay
        star.style.animationDuration = delay
        starWrap.appendChild(star)
    }
}

function createRandom(){
    let posX,posY,size,min = 0,max = 90
    // generate a random number for [10,90]
    posX = Math.floor(Math.random()*(max-min+1)+min)+The '%';
    posY = Math.floor(Math.random()*(max-min+1)+min)+The '%';
    size = Math.floor(Math.random()*(30-5+1) +5) +'px'
    delay = Math.floor(Math.random()*(10-1) +1) +'s'
    return {posX,posY,size,delay}
}
Copy the code
  • Rocket and sea 🚀🌊

When it comes to Mid-Autumn Festival, I think of Chang ‘e. When it comes to Chang ‘e, I think of chang ‘e N lunar exploration project. But I couldn’t find the right material for our launch vehicle on the Internet, so I used a free material image. “Moon born on the Sea” is the main theme of this animation, so a free sea level material is used at the bottom of the page. This is just the rocket taking off, speeding up, getting smaller, and I’ll leave it to the end.

  • Couplet 🧧

It wasn’t there at first, but then I felt like the sides were in space, so I added this. Balloon material online to find, mainly rely on the balloon couplets to fly up, as for the bottom of the moon cake, I forced to add [Mid-Autumn festival elements]. After setting the width and height of the background color, use the. Content ::before pseudo-element to set the yellow border inside the couplet. I’m putting the text inside the content of the pseudo element, but it can be outside as well. As for the vertical display of text, I used a very stupid method, that is, when the size of the text exceeds the width of the couplet, it will automatically row down to form the effect of vertical arrangement. There is also a writing mode attribute on the Internet.

conclusion

At this point, all the elements are written. All you need to do is add the animation.

Xiao Chen wishes everyone who saw this and did not see this, happy Mid-Autumn Festival, happy family! 🤞

The complete code

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>The Mid-Autumn festival</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            width: 100vw;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            background: rgb(37.37.37);
            overflow: hidden;
        }

        .moon {
            width: 30vw;
            height: 30vw;
            border-radius: 50%;
            background: linear-gradient(#f1c40f.#f39c12);
            box-shadow: 0px 0px 50px 5px #f39c12;
            position: absolute;
            right: 30%;
            top: 10%;
            animation: moon 5s forwards;
        }

        @keyframes moon {
            from {
                transform: translate3d(0.100%.0); }}.airplane {
            width: 100px;
            height: 100px;
            background-color: # 000;
            -webkit-mask-image: url(./image/airplane.png);
            -webkit-mask-size: 100px 100px;
            position: absolute;
            right: 10%;
            top: 20%;
            animation: fly 5s ease-in-out forwards;
            z-index: 5;
        }

        @keyframes fly {
            to {
                transform: translate3d(-30vw.0.0); }}.star-wrap {
            width: 100%;
            height: 60%;
            position: absolute;
            top: 0;
            z-index: -1;
        }

        .star {
            position: absolute;
            background-color: #f1c40f;
            width: 20px;
            height: 20px;
            animation: star 3s linear infinite;
            box-shadow: 0px 0px 20px 5px rgb(255 255 255 / 30%);
            -webkit-mask-image: url(./image/star.png);
            -webkit-mask-size: 20px 20px;
        }

        @keyframes star {
            from {
                opacity: 0;
            }
            50% {
                opacity: 1;
            }
            to {
                opacity: 0; }}.rocket {
            width: 100px;
            height: 200px;
            background: url(/image/rocket.png);
            background-size: 100%;
            position: absolute;
            bottom: 0;
            right: 30%;
            animation: rocket 5s ease-in forwards;
            z-index: 9;
        }

        @keyframes rocket {
            to {
                transform: translate3d(0, -80vh.0) scale(.2); }}.sea {
            width: 100%;
            height: 50%;
            position: absolute;
            bottom: 0;
            background: url(/image/sea.png) no-repeat;
            background-size: 100%;
            z-index: 0;
        }

        .couplet-wrap {
            width: 90%;
            height: 90vh;
            background-color: transparent;
            z-index: 10;
            display: flex;
            justify-content: space-between;        
            animation: couplet 2s ease 5s backwards;    
        }

        @keyframes couplet {
            from {
                transform: translate3d(0.120%.0);
            }
            to {
                transform: translate3d(0.0.0); }}.couplet {
            width: 150px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        .balloon {
            width: 100%;
            height: 120px;
            background: url(/image/balloon.png) no-repeat center;
            background-size: contain;
        }

        .content {
            background-color: #c0392b;
            flex: 1;
            width: 100%;
            position: relative;
        }

        .content::before {
            content: "Moon on the Sea.";
            position: absolute;
            width: 80%;
            height: 90%;
            border: 5px solid #f1c40f;
            left: 50%;
            top: 50%;
            transform: translate3d(-50%, -50%.0);
            text-align: center;
            font: 70px '宋体';
            line-height: 90px;
            color: rgb(44.44.44);
        }


        #content2::before {
            content: "All the world is here.";
        }

        .content::after {
            content: "";
            position: absolute;
            top: 100%;
            left: 50%;
            width: 5px;
            height: 50px;
            background-color: #c0392b;
            border-left: 2px dashed #f1c40f;
            border-right: 2px dashed #f1c40f;
            box-sizing: border-box;
        }

        .mooncake {
            width: 100%;
            height: 80px;
            margin-top: 30px;
            background: url(/image/mooncake.png) no-repeat center;
            background-size: contain;
            z-index: 10;
        }
    </style>
</head>
<body>
    <! -- Picture resources to find it yourself ~ >
    <div class="moon"></div>
    <div class="airplane"></div>
    <div class="star-wrap"></div>
    <div class="rocket"></div>
    <div class="sea"></div>
    <div class="couplet-wrap">
        <div class="couplet">
            <div class="balloon"></div>
            <div class="content"></div>
            <div class="mooncake"></div>
        </div>
        <div class="couplet">
            <div class="balloon"></div>
            <div class="content" id="content2"></div>
            <div class="mooncake"></div>
        </div>
    </div>

    <script>
        window.onload = function(){
            let starWrap = document.querySelector('.star-wrap')
            for(let i=0; i<50; i++){let star = document.createElement('div')
                let {posX,posY,size,delay} = createRandom()
                star.className = "star"
                star.style.left = posX
                star.style.top = posY
                star.style.width = star.style.height = size
                star.style.webkitMaskSize = `${size} ${size}`
                star.style.animationDelay = delay
                star.style.animationDuration = delay
                starWrap.appendChild(star)
            }
        }

        function createRandom(){
            let posX,posY,size,min = 0,max = 90
            // generate a random number for [10,90]
            posX = Math.floor(Math.random()*(max-min+1)+min)+The '%';
            posY = Math.floor(Math.random()*(max-min+1)+min)+The '%';
            size = Math.floor(Math.random()*(30-5+1) +5) +'px'
            delay = Math.floor(Math.random()*(10-1) +1) +'s'
            return {posX,posY,size,delay}
        }
    </script>
</body>
</html>
Copy the code