1、运动中的边界处理(让其在一个指定区域内运动)
当元素的offsetLeft值超出一定距离或达到一个我们想要设置的边界值时,停止计时器。
var timer; timer = setInterval(function(){//计时器 if(obox.offsetLeft>=200){//判断的条件 clearInterval(timer); }else{[ obox.style.left = obox.offsetLeft+10+"px";//每30毫秒我们走的步长 } },30)//以毫秒为单位,设置多少毫秒计时器走一次。
tip:为什么是30毫秒呢?
因为电影播放每秒24帧,人眼就识别不出卡顿了,但是对于电脑来说,处理速度相对较快,需要每秒30帧以上才会显得流畅,如果计算机的性能不是很好,你写了30毫秒,DOM也不定能真的30毫秒执行一次。
2、重力回弹运动
加速效果:增加重力值,随着定时器的执行,重力增大
回弹效果:当抵达目标位置时,将速度改为负值
回弹减速:将速度改变为负值的同时,除以2减半
var oball = document.getElementById("ball"); var speed = 5; //步长 var g = 1; //重力 var index = 0; //计时器的计数器 var timer = null; //计时器 var maxTop = 300 - oball.offsetHeight; timer = setInterval(function(){ index++; if(index%5 == 0){ speed += g; } if(maxTop-oball.offsetTop<speed){ // clearInterval(timer); speed = -Math.round(speed*0.7); oball.style.top = maxTop + "px"; if(Math.abs(speed) <= 1){ clearInterval(timer); } console.log(speed); }else{ oball.style.top = oball.offsetTop + speed + "px" } },30) // 判断最后剩下的距离<步长的时候 // 停! // 手动到终点 //打车
3、抛物线运动
var oball = document.getElementById("ball"); var speed = 5; //Y轴步长 var g = 1; //Y轴的重力 var index = 0; //计时器的计数器 var timer = null; //计时器 var maxTop = 300 - oball.offsetHeight; //Y轴的最大值 var left = 20; //x轴的步长 var maxLeft = 1000 - oball.offsetWidth; //X轴的最大值 timer = setInterval(function(){ //计时器的计数器 index++; //每五次增加重力 if(index%5 == 0){ speed += g; } //判断最后一步的距离,不足一步了,打车差点到终点的时候,下车结束行程 if(maxTop-oball.offsetTop < speed){ //让小球在Y轴回弹,同时每次回弹损耗0.3 speed = -Math.round(speed*0.7); //强制到终点 oball.style.top = maxTop + "px"; //当速度不足1,清除没用的计时器 if(Math.abs(speed) <= 1){ clearInterval(timer); } }else{ //正常设置运动元素的位置 oball.style.left = oball.offsetLeft + left + "px"; oball.style.top = oball.offsetTop + speed + "px"; } //让小球在X轴的右边回弹 if(maxLeft - oball.offsetLeft < left){ left = -left; } //让小球在X轴的左边回弹 if(oball.offsetLeft < 0){ left = -left; } },30) // 判断最后剩下的距离<步长的时候 // 停! // 手动到终点 //打车
4.透明度的变换
其实就是获取样式的透明度,然后改变数值
var obox = document.getElementById("box") var speed = 10; var iNow = 20; var timer = null; obox.onmouseover = function(){ clearInterval(timer); timer = setInterval(function(){ if(iNow == 100){ clearInterval(timer) }else{ iNow += speed obox.style.opacity = iNow /100; } },30) } obox.onmouseout = function(){ clearInterval(timer); timer = setInterval(function(){ if(iNow == 20){ clearInterval(timer); }else{ iNow -= speed obox.style.opacity = iNow /100; } },30) }
5、缓冲运动
var oBtn = document.getElementById("btn"); var oBox = document.getElementById("box"); oBtn.onclick = function(){ move(500); } var timer = null; function move(target){ // 1. 关闭开启定时器; clearInterval(timer); timer = setInterval(function(){ //2.计算速度; var speed = (target - oBox.offsetLeft) / 10; // if(speed > 0){ // speed = Math.ceil(speed); // }else{ // speed = Math.floor(speed); // } // 速度取整判断; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);//三目运算,代码更简介、明朗。 //console.log(speed,oBox.offsetLeft); // 3. 终止运动; if(target == oBox.offsetLeft){ clearInterval(timer); }else{ oBox.style.left = oBox.offsetLeft + speed + "px"; } }, 30); }
6、平时我们在页面上所看到的鼠标滑动实现悬浮的一个效果
css和html解构: <style> #div1{ 60px; height: 100px; position: absolute; right: 0; bottom: 0; background: #b7b7b7; } body{ height: 3000px; } input{ position: fixed; right: 0; top: 0; } </style> <body> <div id='div1'></div> <input type="text" id='txt1'> </body> js解构: <script> window.onscroll=function(){ var oDiv=document.getElementById('div1'); var scrollTop=document.documentElement.scrollTop||document.body.scrollTop; move(Math.round((document.documentElement.clientHeight-oDiv.offsetHeight)/2+scrollTop)) } var timer=null; function move(target){ var oDiv=document.getElementById('div1'); clearInterval(timer); timer=setInterval(function(){ var speed=(target-oDiv.offsetTop)/10; speed=speed>0?Math.ceil(speed):Math.floor(speed); if(oDiv.offsetTop==target){ clearInterval(timer) }else{ document.title=target; document.getElementById('txt1').value=oDiv.offsetTop oDiv.style.top=oDiv.offsetTop+speed+'px'; } },30) }
7.多元素缓冲运动函数封装(写的一个运动函数的封装)
function move(ele,json,callback){ clearInterval(ele.t); ele.t = setInterval(() => { var onoff = true; for(var i in json){ var iNow = parseInt(getStyle(ele,i)); var speed = (json[i] - iNow)/6; speed = speed<0 ? Math.floor(speed) : Math.ceil(speed); if(iNow != json[i]){ onoff = false; } ele.style[i] = iNow + speed + "px"; } if(onoff){ clearInterval(ele.t); callback && callback(); } }, 30); }
8、圆周运动
var center = 200; var speed = 10; var target = 360; var r = 200; var iNow = 0; var t; document.onclick = function (){ clearInterval(t); setInterval(function(){ if(iNow == target){ clearInterval(t); }else { iNow += speed; var div = document.createElement("div"); div.className = "box"; document.body.appendChild(div); div.style.left = Math.cos( Math.PI/180*iNow ) * r + center + "px"; div.style.top = Math.sin( Math.PI/180*iNow ) * r + center + "px"; } },30) }
8-1案例(利用上面7的封装函数和圆周运动,实现一个烟花的效果,会用到另外一个获取随机数和随机颜色的封装代码一起放在连同css、html、js和整个html都放在下面,供大家到自己编辑器上查看效果)
tip:因为DOM运动,多为视觉上的效果,因为我刚接触博客园,视频改成的gif图也不懂怎么放上去,希望多谅解,下面烟花的效果html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> .box{ 80%;height: 600px;background-color: #000000;border: 5px solid red;position: relative;margin: 30px auto;overflow: hidden;} .fire{ 10px;height: 10px;position: absolute;bottom:0;} .small-fire{ 10px;height: 10px;border-radius: 50%;position: absolute;} </style> </head> <body> <div class="box"></div> </body> <!-- <script src="../move.js"></script> --> <script type="text/javascript"> // ooa: // 1创建主题烟花,设置样式 // 2开始运动,结束运动 // 3结束运动的时候创建小烟花,立即运动,结束运动 var obox = document.querySelector(".box"); obox.onclick = function (eve){ var e = eve || window.event; new Fire({x:e.offsetX,y:e.offsetY,parent:this}) } function Fire(op){ // 获取元素 this.x = op.x; this.y = op.y; this.div = op.parent; // 创建主题烟花,设置样式 this.init(); } Fire.prototype.init = function(){ // 创建烟花,设置样式 this.ele = document.createElement("div"); this.ele.className = "fire"; this.ele.style.left = this.x+"px"; this.ele.style.background = randomColor(); this.div.appendChild(this.ele); // 开始运动,结束运动 this.animate(); } Fire.prototype.animate = function(){ // 开始运动,结束运动 move(this.ele,{top:this.y},function(){ this.ele.remove() this.createSmallFire(); }.bind(this)) // 运动结束的时候矿建小烟花,立即运动,结束运动 } Fire.prototype.createSmallFire = function(){ // 运动结束的时候矿建小烟花,立即运动,结束运动 var num = random(10,20); var r = random(100,200); for(var i=0;i<num;i++){ let odiv = document.createElement("div"); odiv.className = "small-fire"; odiv.style.background = randomColor(); odiv.style.left = this.x+"px"; odiv.style.top = this.y+"px"; this.div.appendChild(odiv); var l = parseInt(Math.cos( Math.PI/180 * (360/num * i)) * r) + this.x; var t = parseInt(Math.sin( Math.PI/180 * (360/num * i)) * r) + this.y; move(odiv,{ left:l, top:t },function(){ odiv.remove() }) } // 2.利用三角函数,计算出一个圆上面平均分布的点的坐标 // 注意三角函数的方法接收的是弧度:别忘记角度转弧度 } // 范围随机数 function random(max,min){ return Math.round(Math.random()*(max-min)+min); } // 随机颜色 function randomColor(){ return "rgb("+random(0,255)+","+random(0,255)+","+random(0,255)+")"; } //多属性、多元素、回调函数运动的封装 function move(ele,json,callback){ clearInterval(ele.t); ele.t = setInterval(() => { var onoff = true; for(var i in json){ var iNow = parseInt(getStyle(ele,i)); var speed = (json[i] - iNow)/6; speed = speed<0 ? Math.floor(speed) : Math.ceil(speed); if(iNow != json[i]){ onoff = false; } ele.style[i] = iNow + speed + "px"; } if(onoff){ clearInterval(ele.t); callback && callback(); } }, 30); } // 获取样式操作非行内的兼容 function getStyle(ele,attr){ //获取样式的操作非行内 var a = ""; if(ele.currentStyle){ //兼容ie a = ele.currentStyle[attr]; }else{ a = getComputedStyle(ele,false)[attr]; //不兼容ie;但兼容正常浏览器; } return a; } </script> </html>