首頁 > web前端 > css教學 > CSS 、JS實現浪漫流星雨動畫

CSS 、JS實現浪漫流星雨動畫

云罗郡主
發布: 2018-11-13 17:30:14
轉載
2728 人瀏覽過

這篇文章帶給大家的內容是關於CSS 、JS實現浪漫流星雨動畫,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。效果如下:

CSS 、JS實現浪漫流星雨動畫

HTML

由於節點很多,並且我想盡量做得逼真有趣有點,還給節點加了隨機位置。所以節點的輸出都是用JS控制的,HTML這邊只寫了幾個父元素盒子,加上對應的ID名和類別類名,結構相對簡單。

CSS

CSS部分的困難就是流星的樣式和用圈圈畫雲層,然後將雲層堆疊出立體效果。 【推薦閱讀:CSS堆疊上下文是什麼?有什麼作用?

先說流星的樣式:

1

2

3

4

5

6

7

8

9

10

11

12

#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);

 }

登入後複製

先提取了公共樣式,加入定位屬性;

然後在星後通過後偽類別添加流星,以邊界特性畫:

1)模型繪製:border-width的順序為四邊top,right,bottom,left,同理border-color的順序也為四邊top,right,bottom ,left。這樣將border-width與border-color一一對應後,就能看出2px的是流星的寬度,80px是流星的長度,而0像素流星就是尾巴的這樣就形成了一個。頭部2px的寬,尾部0像素,長度80px的流星模型 ;

2)稍微逼真:通過邊界半徑?給流星的頭部增加個圓角,讓它看起來更逼真最後透過roteta旋轉一個角度,讓它看起來像是往下掉;

3)增加閃光:透過箱陰影給流星增加一點光暈,讓它看起來有閃光的效果;

透過以上3步,一個流星就畫好了。

然後是畫雲:

因為雲的程式碼比較長,這裡就不貼出來了方法無非是透過一個一個的圓,相互疊加覆蓋,完成一個雲朵的形狀。
完成一個雲層之後,copy一個,然後多個雲層通過rotate,opacity,left定位等,做出一個漸隱疊加的立體效果;

JS

JS部分以流星舉例說明:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

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);

登入後複製

這裡邊用到了我自己封裝的兩個方法,一個是基於requestAnimationFrame的requestAnimation,以及基於appendChild的addChild。

為了達成星星位置隨機的效果,透過計時器的setInterval的不停插入與刪除流星:

首先,每次加入2個流星到頁面,但是計時器的間隔時間小於流星的動畫時間,這樣就能保證頁面中的流星的數量不是固定值,但肯定是大於2的。不然一次2個流星略顯冷清;

然後,透過對循環(也可以用為式,換的,都行。對於-的最簡單)給每個新添加到頁面中的流星一個隨機的位置(頂部,左側),隨機的大小(規模),隨機的動畫執行時間(計時器);

最後,在用於循環中,給每個新添加到頁面中的流星加上動畫,並透過回呼函數在執行動畫後刪除節點。這裡要注意的是,要動畫分成兩個階段(出現與消失,主要是opacity控制)。另外我這裡的處理,每個流星都移動相同的距離300px,這個距離我覺得也可以用隨機數控制,但我犯了個懶,就沒有做。

附上程式碼:

HTML:

1

2

3

4

5

6

7

8

9

10

11

< 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:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

/*  -  -  -  -  -  - 重启 -  -  -  -  -  -  */

  

 * {

     保证金: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:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

//流星动画

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)

登入後複製

以上就是對CSS 、JS實現浪漫流星雨動畫的完整介紹,如果您想了解更多有關CSS教程,請關注PHP中文網。


以上是CSS 、JS實現浪漫流星雨動畫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板