视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
CSS、JS实现浪漫流星雨动画
2020-11-27 16:50:21 责编:小采
文档
本篇文章给大家带来的内容是关于CSS 、JS实现浪漫流星雨动画,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。效果如下:

HTML

由于节点很多,并且我想尽量做得逼真有趣有点,还给节点加了随机位置。所以节点的输出都是用JS控制的,HTML这边只写了几个父元素盒子,加上相应的ID名和类类名,结构相对简单。

CSS

CSS部分的难点就是流星的样式和用圈圈画云层,然后将云层堆叠出立体效果。【推荐阅读:CSS堆叠上下文是什么?有什么作用?】

首先说一下流星的样式:

#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部分以流星举例说明:

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:

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

下载本文
显示全文
专题