1,效果图

2,源码

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)复制代码

封装方法

// -------------------------------------------动画---- -----------------------------------------------
//运动动画,调用Tween.js
// ele:dom | 班级| id | 标签节点| 类名| id名| 标签名,只支持选择一个节点,类类名以及标签名只能选择页面中第一个
// attr:属性属性名
//值:目标值目标值
//时间:持续时间持续时间
//补间:定时function函数方程
// flag:Boolean判断是按值移动还是按位置移动,默认按位置移动
// fn:callback回调函数
//增加返回值:将内部参数对象返回,可以通过设置返回对象的属性stop为true打断动画
函数 requestAnimation(obj) {// -------------------------------------参数设置--------------------------------------------- //默认属性const参数= {ele:null,attr:null,value:null,time:1000,tween:“linear”,flag:true,stop:false,fn:“”}//合并传入属性Object .assign(parameter,obj); //覆盖重名属性// -------------------------------------动画设置--------- ------------------------------------ //创建运动方程初始参数,方便复用let start = 0 ; //用于保存初始时间戳let target =(typeof parameter.ele === “string”?document .querySelector(parameter.ele):parameter.ele),//目标节点 attr = parameter.attr,//目标属性 beginAttr = parseFloat(getComputedStyle(target)[attr]),// attr起始值 value = parameter.value,//运动目标值 count = value  -  beginAttr,//实际运动值 time = parameter.time,//运动持续时间,tween = parameter.tween,//运动函数flag = parameter.flag,callback = parameter.fn,//回调函数 curVal = 0 ; //运动当前值//判断传入函数是否为数组,多段运动 (function() {if(attr instanceof  Array){beginAttr = [];count = [];对于(让我的 ATTR){常量 VAL = parseFloat(的getComputedStyle(目标)[I]);beginAttr.push(VAL);count.push(value  -  val);}}if(value instanceof  Array){for(let i in value){count [i] = value [i]  -  beginAttr [i];}}})();//运动函数功能 动画(时间戳) {如果(parameter.stop)返回 ; //打断//存储初始时间戳if(!start)start = timestamp;//已运动时间让 t =时间戳 - 开始;//判断多段运动if(beginAttr instanceof  Array){// const len = beginAttr.length //存数组长度,复用//多段运动第1类 - 多属性,同目标,同时间/不同时间if(typeof count === “number”){ //同目标//同时间if(typeof time === “number”){if(t> time)t = time; //判断是否超出目标值//循环attr,分别赋值为(let i in beginAttr){if(flag)curVal = Tween [tween](t,beginAttr [i],count,time); //调用Tween,返回当前属性值,此时计算方法为移动到写入位置else curVal = Tween [tween](t,beginAttr [i],count + beginAttr [i],time); //调用Tween,返回当前属性值,此时计算方法为移动了写入距离if(attr [i] === “opacity”)target.style [attr [i]] = curVal; //给属性赋值else target.style [attr [i]] = curVal + “px” ; //给属性赋值if(t <time)requestAnimationFrame(animate); //判断是否运动完其他回调&& callback(); //调用回调函数}回归 ;}//不同时间if(time instanceof  Array){//循环时间,attr,分别赋值为(让我在 beginAttr中){//错误判断if(!time [i] && time [i]!== 0){throw  new  Error(“输入时间的长度不等于属性的长度”);}//判断是否已经完成动画,完成则跳过此次循环if(parseFloat(getComputedStyle(target)[attr [i]])===(typeof value === “number”?value:value [i]) )继续 ;// t =时间戳 - 开始; //每次循环初始化t if(t> time [i])t = time [i]; //判断是否超出目标值if(flag || attr [i] === “opacity”)curVal = Tween [tween](t,beginAttr [i],count,i); //调用Tween,返回当前属性值,此时计算方法为移动到写入位置else curVal = Tween [tween](t,beginAttr [i],count + beginAttr [i],i); //调用Tween,返回当前属性值,此时计算方法为移动了写入距离if(attr [i] === “opacity”)target.style [attr [i]] = curVal; //给属性赋值else target.style [attr [i]] = curVal + “px” ; //给属性赋值}if(t < Math .max(... time))requestAnimationFrame(animate); //判断函数是否运动完其他回调&& callback(); //如果已经执行完时间最长的动画,则调查回调函数return ;}}//多段运动第2类 - 多属性,不同目标,同时间/不同时间if(count instanceof  Array){//同时间if(typeof time === “number”){if(t> time)t = time; //判断是否超出目标值for(let i in beginAttr){ //循环attr,count,分别赋值//错误判断if(!count [i] && count [i]!== 0){throw  new  Error(“输入值的长度不是等于属性的长度“);}if(flag || attr [i] === “opacity”)curVal = Tween [tween](t,beginAttr [i],count [i],time); //调用Tween,返回当前属性值,此时计算方法为移动到写入位置else curVal = Tween [tween](t,beginAttr [i],count [i] + beginAttr [i],time); //调用Tween,返回当前属性值,此时计算方法为移动了写入距离if(attr [i] === “opacity”)target.style [attr [i]] = curVal; //给属性赋值else target.style [attr [i]] = curVal + “px” ; //给属性赋值}if(t <time)requestAnimationFrame(animate); //判断函数是否运动完其他回调&& callback(); //如果已经执行完时间最长的动画,则调查回调函数return ;}//不同时间if(time instanceof  Array){for(let i in beginAttr){//错误判断if(!time [i] && time [i]!== 0){throw  new  Error(“输入时间的长度)不等于属性的长度“);}//判断是否已经完成动画,完成则跳过此次循环if(parseFloat(getComputedStyle(target)[attr [i]])===(typeof value === “number”?value:value [i]) )继续 ;if(t> time [i])t = time [i]; //判断是否超出目标值//错误判断if(!count [i] && count [i]!== 0){throw  new  Error(“输入值的长度不等于属性的长度”);}if(flag || attr [i] === “opacity”)curVal = Tween [tween](t,beginAttr [i],count [i],time [i]); //调用Tween,返回当前属性值,此时计算方法为移动到写入位置其他 curVal = Tween [tween](t,beginAttr [i],count [i] + beginAttr [i],time [i]) ; //调用Tween,返回当前属性值,此时计算方法为移动了写入距离if(attr [i] === “opacity”)target.style [attr [i]] = curVal;否则 target.style [attr [i]] = curVal + “px” ;}if(t < Math .max(... time))requestAnimationFrame(animate);else callback && callback();回归 ;}}}//单运动模式if(t> time)t = time;if(flag || attr === “opacity”)curVal = Tween [tween](t,beginAttr,count,time); //调用Tween,返回当前属性值,此时计算方法为移动到写入位置else curVal = Tween [tween](t,beginAttr [i],count + beginAttr,time); //调用Tween,返回当前属性值,此时计算方法为移动了写入距离if(attr === “opacity”)target.style [attr] = curVal;否则 target.style [attr] = curVal + “px” ;if(t <time)requestAnimationFrame(animate);else callback && callback();}requestAnimationFrame(动画);返回参数; //返回对象,供打断或其他用途
}
//Tween.js
/ ** t:时间已过时间* b:开始起始值* c:计算总的运动值* d:持续时间持续时间**曲线方程** http://www.cnblogs.com/bluedream2009/archive/2010/06/19/1760909.html* * /让 Tween = {linear:function(t,b,c,d) { //匀速返回 c * t / d + b;},easeIn:function(t,b,c,d) { //加速曲线return c *(t / = d)* t + b;},easeOut:function(t,b,c,d) { //减速曲线return -c *(t / = d)*(t  - 2)+ b;},easeBoth:function(t,b,c,d) { //加速减速曲线if((t / = d / 2)< 1){return c / 2 * t * t + b;}return -c / 2 *(( -  t)*(t  - 2) - 1)+ b;},easeInStrong:function(t,b,c,d) { //加加速曲线return c *(t / = d)* t * t * t + b;},easeOutStrong:function(t,b,c,d) { //减减曲线返回 -c *((t = t / d  - 1)* t * t * t  - 1)+ b;},easeBothStrong:function(t,b,c,d) { //加速减减速线如果((t / = d / 2)< 1){return c / 2 * t * t * t * t + b;}return -c / 2 *((t  -  = 2)* t * t * t  - 2)+ b;},elasticIn:function(t,b,c,d,a,p) { //正弦衰减曲线(弹动渐入)if(t === 0){return b;}if((t / = d)== 1){return b + c;}if(!p){p = d * 0.3 ;}if(!a || a < Math .abs(c)){a = c;var s = p / 4 ;} else {var s = p /(2 * Math .PI)* Math .asin(c / a);}返回 - (A * 数学 .pow(2,10 *(T - = 1))* 数学 .sin((T * d - S)*(2 * 数学 .PI)/ P))+ B;},elasticOut:function(t,b,c,d,a,p) { //正弦增强曲线(弹动渐出)if(t === 0){return b;}if((t / = d)== 1){return b + c;}if(!p){p = d * 0.3 ;}if(!a || a < Math .abs(c)){a = c;var s = p / 4 ;} else {var s = p /(2 * Math .PI)* Math .asin(c / a);}返回 a * Math .pow(2,-10 * t)* Math .sin((t * d  -  s)*(2 * Math .PI)/ p)+ c + b;},elasticBoth:function(t,b,c,d,a,p) {if(t === 0){return b;}if((t / = d / 2)== 2){return b + c;}if(!p){p = d *(0.3 * 1.5);}if(!a || a < Math .abs(c)){a = c;var s = p / 4 ;} else {var s = p /(2 * Math .PI)* Math .asin(c / a);}如果(T < 1){返回 -0.5 *(A * 数学 .pow(2,10 *(T - = 1))*数学 .sin((T * d - S)*(2 * 数学 .PI)/ p))+ b;}返回 a * Math .pow(2,-10 *(t  -  = 1))*Math .sin((t * d  -  s)*(2 * Math .PI)/ p)* 0.5 + c + b;},backIn:function(t,b,c,d,s) { //回退加速(回退渐入)if(typeof s == 'undefined'){s = 1.70158 ;}return c *(t / = d)* t *((s + 1)* t  -  s)+ b;},backOut:function(t,b,c,d,s) {if(typeof s == 'undefined'){s = 3.70158 ; //回缩的距离}return c *((t = t / d  - 1)* t *((s + 1)* t + s)+ 1)+ b;},backBoth:function(t,b,c,d,s) {if(typeof s == 'undefined'){s = 1.70158 ;}if((t / = d / 2)< 1){return c / 2 *(t * t *(((s * =(1.525))+ 1)* t  -  s))+ b;}return c / 2 *((t  -  = 2)* t *(((s * =(1.525))+ 1)* t + s)+ 2)+ b;},bounceIn:function(t,b,c,d) { //弹球渐出)返回 c  -  Tween [ 'bounceOut' ](d  -  t,0,c,d)+ b;},bounceOut:function(t,b,c,d) {if((t / = d)<(1 / 2.75)){return c *(7.5625 * t * t)+ b;} else  if(t <(2 / 2.75)){return c *(7.5625 *(t  -  =(1.5 / 2.75))* t + 0.75)+ b;} else  if(t <(2.5 / 2.75)){return c *(7.5625 *(t  -  =(2.25 / 2.75))* t + 0.9375)+ b;}return c *(7.5625 *(t  -  =(2.625 / 2.75))* t + 0.984375)+ b;},bounceBoth:函数(T,B,C,d) {如果(T <d / 2){返回吐温[ 'bounceIn' ](T * 2,0,C,d)* 0.5 + B;}return Tween [ 'bounceOut' ](t * 2 -  d,0,c,d)* 0.5 + c * 0.5 + b;}
}// ------------------------------------------- DOM操作--- ------------------------------------------------
//添加节点
// ele:父节点,支持输入变量,id值,类值,标签值。除变量外,其余值必须为字符串
//节点:添加的标签名,值为字符串
// n:节点添加个数
// className:节点绑定的类名,值为字符串,多个类名用空格隔开
//布尔:是否选中所有目标父节点。可选参数,不输入则判定为false,则只匹配选中的第一个节点
函数 addChild(ele,node,n,className,boolean) {//获取节点let parent = null ;if(typeof ele!== “string”)parent = ele;else  if(ele [ 0 ] === “#”)parent = document .getElementById(ele.slice(1));else  if(ele [ 0 ] === “。”){if(boolean === false)parent = document .getElementsByClassName(ele.slice(1))[ 0 ];else parent = document .getElementsByClassName(ele.slice(1));} else {if(boolean === false)parent = docuemnt.getElementsByTagName(ele)[ 0 ];else parent = document .getElementsByTagNameNS(ele);}//声明用于存储父节点及子节点的对象const obj = {“parent”:parent,“children”:[]};//添加节点if(boolean){for(let i = 0 ; i <parent.length; i ++){//创建容器碎片const fragment = document .createDocumentFragment();//保存子节点,用于返回值obj.children [i] = [];for(let j = 0 ; j <n; j ++){const target = document .createElement(node);target.className = className;fragment.appendChild(目标);//添加子节点到数组,用于返回值obj.children [i] [j] =目标;}父[I] .appendChild(片段)}} else {//创建碎片容器const fragment = document .createDocumentFragment();for(let i = 0 ; i <n; i ++){const target = document .createElement(node);target.className = className;fragment.appendChild(目标);//添加子节点,用于返回值obj.children [i] =目标;}//将碎片容器一次性添加到父节点parent.appendChild(片段);}//返回参数,供动画函数调用return obj;
}复制代码

3,案例解析

HTML

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

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,这个距离我觉得也可以通过随机数控制,但我犯了个懒,就没有做。

4,小问题

目前我发现的问题有2个:

一是DOM操作本身的问题页面不停的添加与删除节点,造成不停地。回流与重绘,很耗性能;

二是requestAnimationFrame本身的问题因为定时器不断在添加节点,而requestAnimationFrame的特性- 当离开当前页面去浏览其他页面时,动画会暂停。这就造成了一个问题,节点一直在加,但动画全在停那没有执行那么下次再回到这个页面的时候,就吊杆!!!动画就炸了,你会看到画面一卡,很多小蝌蚪集体出动去找妈妈。

5,结语

这个小案例虽然从难度上来看很简单,但是它可拓展性很高 - 比如表个白啊,寄个相思,耍个浪漫啊等等,用纯CSS也可以实现。

这里推荐一下我的前端学习交流群:784783012,里面都是学习前端的,如果你想制作酷炫的网页,想学习编程。自己整理了一份2018最全面前端学习资料,从最基础的HTML+CSS+JS【炫酷特效,游戏,插件封装,设计模式】到移动端HTML5的项目实战的学习资料都有整理,送给每一位前端小伙伴,有想学习web前端的,或是转行,或是大学生,还有工作中想提升自己能力的,正在学习的小伙伴欢迎加入学习。

点击:加入

转载于:https://juejin.im/post/5c01438ef265da61553a8f5d

CSS 、JS实现浪漫流星雨动画相关推荐

  1. html涟漪动画效果,CSS+JS实现水滴涟漪动画按钮效果的示例代码

    代码如下所示: Document .btn{ display: block; width: 300px; height: 100px; margin: 50px; outline: 0; overfl ...

  2. HTML+CSS+JS实现 ❤️夜晚云层动画特效❤️

    效果演示: 基于css3 keyframes 属性制作乌云密布云层动画,夜晚云层飘过动画特效.可用于网页动态云层背景特效.利用animation 和png云图片制作完成. 代码目录: 主要代码实现: ...

  3. HTML+CSS+JS实现 ❤️照相机快门图片动画特效❤️

    效果演示: 代码目录: 主要代码实现: 部分CSS样式: html {height: 100%;overflow: hidden; }body {min-height: 100%; }.contain ...

  4. HTML+CSS+JS实现燃烧的火焰火花动画特效

  5. HTML+CSS+JS实现 ❤️流星天体动画场景特效❤️

  6. HTML+CSS+JS实现 ❤️圆圈波纹动画特效❤️

  7. HTML+CSS+JS实现 ❤️制作loading动画效果❤️

  8. 使用HTML+CSS+JS模拟比赛晋级的动画功能

    使用HTML+CSS+JS模拟比赛晋级的动画功能 1.需求描述 2.代码实现 3.效果演示 系统:Win10 Chrome:106.0.5249.119 演示视频:[英雄联盟]S12全球总决赛冠军预测 ...

  9. 有趣的HTML实例(十四) 窗边风景动画(css+js)

    不要憎恨你的敌人,那会影响你的判断力. --<教父> 目录 一.前言 二.往期作品回顾 三.作品介绍 四.本期代码介绍 五.效果显示 六.编码实现 index.html style.css ...

最新文章

  1. 树莓派:人在太空,刚下火箭,诚招小于19岁的代码开发者
  2. 更改SQL 2005登录时的默认数据库
  3. 每一个C#开发者必须知道的13件事情
  4. 9277用计算机,关于计算机常用进制以及进制之间的转换笔记
  5. django开发商城(提供初始数据,商城首页及购物车)
  6. VirtualBox创建虚拟电脑、执行Genymotion模拟器报错
  7. btoa java,java的btoa、atob
  8. 基于随机森林的姿态识别算法
  9. Ubuntu20.04 安装在U盘上
  10. java缓存技术memcached实例
  11. Oracle 10g安装图解教程
  12. 高教版《金融学》预习笔记
  13. Python3之入门小程序
  14. Microsoft Edge 嗯...无法访问此页面解决办法
  15. 读懂 互联网巨头 【中台之战】 以及 中台 发展思维
  16. Speedoffice(Word)怎样设置页眉页脚高度
  17. echarts网络拓扑图动态流程图
  18. python之首字母大写
  19. ivue-admin Table单元格内换行问题
  20. 百度网盘真实地址解析(告别下载百度网盘)

热门文章

  1. Leo谈交朋友与找工作
  2. 母婴用品店收银系统都有哪些优势
  3. 无线路由桥接(WDS)设置
  4. 操作系统---(35)缺页中断与缺页中断处理过程
  5. HTTP长连接、短连接究竟是什么?
  6. 最小费用最大流问题与算法实现(Bellman-Ford、SPFA、Dijkstra)
  7. html网页制作期末大作业成品_新疆旅游网页设计作品_dreamweaver作业静态HTML网页设计模板_新疆旅游景点网页作业制作
  8. MySQL主从复制详细讲解
  9. vue-baidu-map 个性化地图
  10. 数据科学正在装饰在线教yu领域