Home  >  Article  >  Web Front-end  >  CSS and JS realize romantic meteor shower animation

CSS and JS realize romantic meteor shower animation

云罗郡主
云罗郡主forward
2018-11-13 17:30:142471browse

The content of this article is about realizing romantic meteor shower animation with CSS and JS. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you. The effect is as follows:

CSS and JS realize romantic meteor shower animation

HTML

Since there are many nodes, and I want to make it as realistic and interesting as possible, I also added random positions to the nodes. Therefore, the output of nodes is controlled by JS. On the HTML side, only a few parent element boxes are written, plus the corresponding ID names and class names, and the structure is relatively simple.

CSS

The difficult part of the CSS part is the style of the meteor and drawing the clouds with circles, and then stacking the clouds to create a three-dimensional effect. [Recommended reading: What is CSS stacking context? what's the effect?

First let’s talk about the style of the meteor:

#sky  .star {      position:absolute;
     不透明度:0 ;
     z-index:10000 ;
 }
 
 .star :: after {      content:“” ;
     显示:块;
     边界:坚固;     border-width:2px  0  2px  80px ;
     / *流星随长度逐渐缩小* / 
     border-color:透明透明透明rgba(255,255,255,1);     border-radius:2px  0  0  2px ;     transform:rotate(-45deg);     transform-origin:0  0  0 ;
     盒子阴影:0  0  20px  rgba(255,255,255,.3);
 }

First extract the public style and add the positioning attribute;

Then pass the pseudo after the star Add a meteor to the class and draw it with the border properties:

1) Model drawing: The order of border-width is top, right, bottom, left on the four sides. Similarly, the order of border-color is top, right, bottom on the four sides. , left. In this way, after one-to-one correspondence between border-width and border-color, you can see that 2px is the width of the meteor, 80px is the length of the meteor, and the 0-pixel meteor is the tail, thus forming a. Meteor model with head 2px wide, tail 0px, and length 80px;

2) Slightly realistic: by border radius? Add a rounded corner to the head of the meteor to make it look more realistic. Finally, rotate it at an angle through rotateta to make it look like it is falling;

3) Add sparkle: Add box shadow to the meteor. Add a little halo to make it look sparkling;

After the above 3 steps, a shooting star is ready.

Then there is drawing clouds:

Because the cloud code is relatively long, I won’t post it here. The method is nothing more than overlapping and covering each other one by one to complete the shape of a cloud.
After completing a cloud layer, copy one, and then multiple cloud layers use rotate, opacity, left positioning, etc. to create a three-dimensional effect of fading and overlapping;

JS

The JS part is Meteor gives an example:

setInterval(function() {
     const obj = addChild(“#sky”,“div”,2,“star”); //插入流星
    for(let i = 0 ; i <obj.children.length; i ++){         //随机位置
        const top = -50 + Math .random()* 200 + “px”,
            left = 200 + Math .random()* 1200 + “px”,
            scale = 0.3 + Math .random()* 0.5 ;
        const timer = 1000 + Math .random()* 1000 ;
        obj.children [i] .style.top = top;
        obj.children [i] .style.left = left;
        obj.children [i] .style.transform = `scale($ {scale})` ;        
        //添加动画
        requestAnimation({
            ele:obj.children [i],
             attr:[ “top”,“left”,“opacity” ],
             值:[ 150,-150,.8 ],
             time:timer,
             flag:false,
             fn:function() {
                requestAnimation({
                    ELE:obj.children [I],
                     ATTR:“顶”,“左”,“不透明” ],
                     值:[ 150,-150,0 ],
                     时间:定时器,
                     标志:假,
                     FN:() => {
                        obj.parent.removeChild(obj.children [I]); //动画结束删除节点
                    }
                })
            }
        });
    }
},1000);

I use two methods encapsulated by myself here, one is requestAnimation based on requestAnimationFrame, and addChild based on appendChild.

In order to achieve the effect of random star positions, meteors are continuously inserted and deleted through the setInterval of the timer:

First, add 2 meteors to the page each time, but the interval of the timer Less than the animation time of the meteor, this ensures that the number of meteors on the page is not a fixed value, but must be greater than 2. Otherwise, 2 meteors at a time will be a bit deserted;

Then, through the loop (it can also be used as an expression, it can be changed. For -, it is the simplest) to give each meteor newly added to the page a Random position (top, left), random size (scale), random animation execution time (timer);

Finally, in the loop, give each newly added to the page Meteor adds animation and deletes the node after executing the animation through the callback function. What should be noted here is that the animation is divided into two stages (appearance and disappearance, mainly opacity control). In addition, in my processing here, each meteor moves the same distance of 300px. I think this distance can also be controlled by random numbers, but I was lazy and didn't do it.

Attached code:

HTML:

< body > 
    < div  class = “container” > 
        < div  id = “mask” > </ div > 
        < div  id = “sky” > </ div > 
        < div  id = “moon” > </ div > 
        < div  id = “stars” > </ div > 
        < div  class = “cloud cloud-1” ></ div > 
        <div  class = “cloud cloud-2” > </ div > 
        < div  class = “cloud cloud-3” > </ div > 
    </ div > 
</ body >

css:

/*  -  -  -  -  -  - 重启 -  -  -  -  -  -  */
 
 * {
     保证金:0 ;
     填充:0 ;
 }
 
 html,
  body {      width:100% ;
     最小宽度:1000px ;
     身高:100% ;
     最小高度:400px ;
     溢出:隐藏;
 }
 / * ------------画布------------ * / 
 .container {      position:relative;
     身高:100% ;
 }
 / *遮罩层* /
 
 #mask {      position:absolute;
     宽度:100% ;
     身高:100% ;     background:rgba(0,0,0,.8);
     z-index:900 ;
 }
 / *天空背景* /
 
 #sky {      width:100% ;
     身高:100% ;     background:线性渐变(rgba(0,150,255,1),rgba(0,150,255,.8),rgba(0,150,255,.5));
 }
 / *月亮* /
 
 #moon {      position:absolute;
     上:50px ;
     右:200px ;
     宽度:120px ;
     身高:120px ;
     背景:rgba(251,255,25,0.938);     border-radius:50% ;     box-shadow:0  0  20px  rgba(251,255,25,0.5);
     z-index:9999 ;
 }
 / *闪烁星星* /
 
 .blink {      position:absolute;     background:rgb(255,255,255);     border-radius:50% ;     box-shadow:0  0  5px  rgb(255,255,255);
     不透明度:0 ;
     z-index:10000 ;
 }
 / *流星* /
 
 .star {      position:absolute;
     不透明度:0 ;
     z-index:10000 ;
 }
 
 .star :: after {      content:“” ;
     显示:块;
     边界:坚固;     border-width:2px  0  2px  80px ;
     / *流星随长度逐渐缩小* / 
     border-color:透明透明透明rgba(255,255,255,1);     border-radius:2px  0  0  2px ;     transform:rotate(-45deg);     transform-origin:0  0  0 ;
     盒子阴影:0  0  20px  rgba(255,255,255,.3);
 }
 / *云* /
 
 .cloud {      position:absolute;
     宽度:100% ;
     身高:100px ;
 }
 
 .cloud-1 {
      bottom: - 100px ;
     z-index:1000 ;
     不透明度:1 ;
     变换:规模(1.5);
     -webkit-transform:scale(1.5);
     -moz-transform:scale(1.5);
     -ms-transform:scale(1.5);
     -o-transform:scale(1.5);
 }
 
 .cloud-2 {
      left: - 100px ;
     底部: - 50px ;
     z-index:999 ;
     不透明度:。5 ;
     变换:旋转(7deg);
     -webkit-transform:rotate(7deg);
     -moz-transform:rotate(7deg);
     -ms-transform:rotate(7deg);
     -o-transform:rotate(7deg);
 }
 
 .cloud-3 {
      left:120px ;
     底部: - 50px ;
     z-index:999 ;
     不透明度:。1 ;     transform:rotate(-10deg);
     -webkit-transform:rotate(-10deg);
     -moz-transform:rotate(-10deg);
     -ms-transform:rotate(-10deg);
     -o-transform:rotate(-10deg);
 }
 
 .circle {      position:absolute;     border-radius:50% ;
     背景:#fff ;
 }
 
 .circle-1 {      width:100px ;
     身高:100px ;
     上: - 50px ;
     左:10px ;
 }
 
 .circle-2 {      width:150px ;
     身高:150px ;
     上: - 50px ;
     左:30px ;
 }
 
 .circle-3 {      width:300px ;
     身高:300px ;
     上: - 100px ;
     左:80px ;
 }
 
 .circle-4 {      width:200px ;
     身高:200px ;
     上: - 60px ;
     左:300px ;
 }
 
 .circle-5 {      width:80px ;
     身高:80px ;
     上: - 30px ;
     左:450px ;
 }
 
 .circle-6 {      width:200px ;
     身高:200px ;
     上: - 50px ;
     左:500px ;
 }
 
 .circle-7 {      width:100px ;
     身高:100px ;
     上: - 10px ;
     左:650px ;
 }
 
 .circle-8 {      width:50px ;
     身高:50px ;
     上:30px ;
     左:730px ;
 }
 
 .circle-9 {      width:100px ;
     身高:100px ;
     上:30px ;
     左:750px ;
 }
 
 .circle-10 {      width:150px ;
     身高:150px ;
     上:10px ;
     左:800px ;
 }
 
 .circle-11 {      width:150px ;
     身高:150px ;
     上: - 30px ;
     左:850px ;
 }
 
 .circle-12 {      width:250px ;
     身高:250px ;
     上: - 50px ;
     左:900px ;
 }
 
 .circle-13 {      width:200px ;
     身高:200px ;
     上: - 40px ;
     左:1000px ;
 }
 
 .circle-14 {      width:300px ;
     身高:300px ;
     上: - 70px ;
     左:1100px ;

JS:

//流星动画 
setInterval(function() {
     const obj = addChild(“#sky”,“div”,2,“star”);    for(let i = 0 ; i <obj.children.length; i ++){
         const top = -50 + Math .random()* 200 + “px”,
            left = 200 + Math .random()* 1200 + “px”,            scale = 0.3 + Math .random()* 0.5 ;
        const timer = 1000 + Math .random()* 1000 ;
        obj.children [i] .style.top = top;
        obj.children [i] .style.left = left;
        obj.children [i] .style.transform = `scale($ {scale})` ;
        requestAnimation({
            ele:obj.children [i],
             attr:[ “top”,“left”,“opacity” ],
             值:[ 150,-150,.8 ],             time:timer,
             flag:false,
             fn:function() {
                requestAnimation({
                    ELE:obj.children [I],
                     ATTR:“顶”,“左”,“不透明” ],
                     值:[ 150,-150,0 ],
                     时间:定时器,
                     标志:假,
                     FN:() => {
                        obj.parent.removeChild(obj.children [I]);
                    }
                })
            }
        });
    }
},1000);
//闪烁星星动画 
setInterval(function() {
     const obj = addChild(“#stars”,“div”,2,“blink”);    for(let i = 0 ; i <obj.children.length; i ++){
         const top = -50 + Math .random()* 500 + “px”,
            left = 200 + Math .random()* 1200 + “px”,            round = 1 + Math .random()* 2 + “px” ;
        const timer = 1000 + Math .random()* 4000 ;
        obj.children [i] .style.top = top;
        obj.children [i] .style.left = left;
        obj.children [i] .style.width = round;
        obj.children [i] .style.height = round;
        requestAnimation({
            ele:obj.children [i],
             attr:“opacity”,
             值:.5,             time:timer,
             flag:false,
             fn:function() {
                requestAnimation({
                    ele:obj.children [i],
                     attr:“opacity”,
                     value:0,                     time:timer,
                     flag:false,
                     fn:function() {
                        obj.parent.removeChild(obj.children [I]);
                    }
                });
            }
        });
    }
},1000);
//月亮移动
requestAnimation({
    ele:“#moon”,
     attr:“right”,
     值:1200,
     时间:10000000,
});
//添加云
const clouds = addChild(“。cloud”,“div”,14,“circle”,true);for(let i = 0 ; i <clouds.children.length; i ++){     for(let j = 0 ; j <clouds.children [i] .length;){
        clouds.children [i] [j] .classList.add(`circle- $ {++ j} `);
    }
}
//云动画let flag = 1 ;
的setInterval(
    功能() {
         const clouds = document .querySelectorAll(“。cloud”);
        const left = Math .random()* 5 ;
        bottom = Math .random()* 5 ;        let timer = 0 ;        for(let i = 0 ; i <clouds.length; i ++){
            requestAnimation({
                ele:clouds [i],
                 attr:[ “left”,“bottom” ],
                 value:flag%2?[-left,-bottom]:[left,bottom],                 time:timer + = 500,
                 flag:false,
                 fn:function() {
                    requestAnimation({
                        ele:clouds [i],
                         attr:[ “left”,“bottom” ],
                         value:flag%2?[left,bottom]:[ -  left,-bottom],                         time:timer,
                         flag:false
                    })
                }
            });
        }
        标志++;
    },2000)

The above is the implementation of CSS and JS A full introduction to the romantic meteor shower animation. If you want to know more about CSS tutorial, please pay attention to the PHP Chinese website.


The above is the detailed content of CSS and JS realize romantic meteor shower animation. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete