运动
概述
运动主要是动画的操作,主要是操作某个document元素的属性变化(位置变化)
运动主要的三步骤
-
使用定时器来定时更改对应的内容
-
实时获取对应的元素的属性及相关内容
-
判断是否到达目标位置(到达后清除定时器)
匀速运动
概述:匀速运动的本质就是每次变化值都是同一个
示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div{ position: relative; width: 100px; height: 100px; background-color: red; } </style> </head> <body> <button>匀速运动</button> <div></div> <script> //获取div var btn = document.querySelector('button') var div = document.querySelector('div') btn.onclick = ()=>{ //使用定时器 var step = 10 var target = 500 var current = 0 var timer = setInterval(() => { //在定时器内控制div的位置变化 current += step //当前位置变化 div.style.left = current + 'px' //设置位置 //当到达目标位置清除定时器 if(current == target){ clearInterval(timer) } }, 20); } </script> </body> </html>
缓冲运动
概述: 缓冲运动的本质就是每次变化的值越来越小
示例
//缓冲运动 //获取div和对应的按钮 var btns = document.querySelectorAll('button') var box = document.querySelector('div') btns[0].onclick = ()=>{ //获取当前位置 var current = parseInt(getStyle(box,'left')) //定义步长和对应的目标位置 var step = 10 //初始步长 var target = 500 //目标位置 //定时器 var timer = setInterval(() => { //控制步长的变化 离目标会越来越小 把步长和这个距离绑定 step = (target - current)/20 > 0 ? Math.ceil((target - current)/20) : Math.floor((target - current)/20) //控制当前位置的变化 current += step //给当前位置赋值 box.style.left = current + 'px' //到达目标位置清除定时器 if(current == target){ clearInterval(timer) } }, 80); }
匀速移动和缓冲移动的封装
//获取样式的方法 function getStyle(ele, attr) { return window.getComputedStyle ? window.getComputedStyle(ele, null)[attr] : ele.currentStyle[attr] } //缓冲动画为true 不传就是匀速 function move(ele, target, isBuffer) { //获取当前位置 var current = parseInt(getStyle(ele, 'left')) //定义步长和对应的目标位置 var step = target - current > 0 ? 10 : -10 //定时器 var timer = setInterval(() => { if (isBuffer) { //控制步长的变化 离目标会越来越小 把步长和这个距离绑定 step = (target - current) / 20 > 0 ? Math.ceil((target - current) / 20) : Math.floor((target - current) / 20) } //控制当前位置的变化 current += step //给当前位置赋值 ele.style.left = current + 'px' //到达目标位置清除定时器 if (current == target) { clearInterval(timer) } }, 20) }
透明度变化
//透明度变化 function opacityAction(box,target){ //获取当前的透明度 //设置步长及对应的目标位置 var step var current = parseFloat(getStyle(box, 'opacity')) //开启定时器 var timer = setInterval(() => { // step = target-current>0?0.1:-0.1 //当透明度到达目标位置清除定时器 if(Math.abs(target-current) <= step){ clearInterval(timer) } // 最小值 0.01 step = (target-current)*100/10 > 0 ? Math.ceil((target-current)*100/10)/100 : Math.floor((target-current)*100/10)/100 //控制透明度的变化 current += step box.style.opacity = current }, 20); }
宽度变化
//获取按钮及div var box = document.querySelector('div') var btn = document.querySelector('button') btn.onclick = ()=>{ //获取开始的宽度 以及步长 var current = parseFloat(getStyle(box,'width')) var step var target = 500 //设置目标位置 var timer = setInterval(() => { //判断是否到达目标位置 if(Math.abs(target-current) <= step){ clearInterval(timer) } //设置步长 // step = target - current > 0 ? 10 : -10 step = (target-current )/10 > 0 ? Math.ceil((target-current)/10) : Math.floor((target-current)/10) //设置当前的位置 current += step box.style.width = current + 'px' }, 20); } //获取样式的方法 function getStyle(ele, attr) { return window.getComputedStyle ? window.getComputedStyle(ele, null)[attr] : ele.currentStyle[attr] }
简易封装move.js
//获取样式的方法 function getStyle(ele, attr) { return window.getComputedStyle ? window.getComputedStyle(ele, null)[attr] : ele.currentStyle[attr] } //缓冲动画为true 不传就是匀速 function move(ele, target, isBuffer = false) { clearInterval(ele.timer) //清除之前的定时器影响 //针对于px为单位的 width,height,left,top //opacity不需要px //zIndex不需要动画 //获取target对象里面的所有的key ele.timer = setInterval(() => { var flag = true for (let key in target) { //获取当前位置 var current = parseFloat(getStyle(ele, key)) ? parseFloat(getStyle(ele, key)) : 0 //定义步长和对应的目标位置 if(key == 'opacity'){ var step = target[key] - current > 0 ? 0.01 : -0.01 }else{ var step = target[key] - current > 0 ? 10 : -10 } //定时器 if (key == 'zIndex') { //层级 ele.style[key] = target[key] //直接设置 } else { //没有到达设置为false if (Math.abs(target[key] - current ) > step) { flag = false } if (isBuffer) { //如果是缓冲的 if (key == 'opacity') { //透明度 // 最小值 0.01 step = (target[key] - current) * 100 / 10 > 0 ? Math.ceil((target[key] - current) * 100 / 10) / 100 : Math.floor((target[key] - current) * 100 / 10) / 100 } else { //其他的 //控制步长的变化 离目标会越来越小 把步长和这个距离绑定 step = (target[key] - current) / 10 > 0 ? Math.ceil((target[key] - current) / 10) : Math.floor((target[key] - current) / 10) } } //控制当前位置的变化 current += step //给当前位置赋值 if (key != 'opacity') { ele.style[key] = current + 'px' } else { ele.style[key] = current } } } if (flag) { clearInterval(ele.timer) } }, 20) }
链式动画
链式动画 等一个完成以后再进行某个操作 (通过回调函数来实现)
//获取样式的方法 function getStyle(ele, attr) { return window.getComputedStyle ? window.getComputedStyle(ele, null)[attr] : ele.currentStyle[attr] } //缓冲动画为true 不传就是匀速 function move(ele, target, isBuffer = true,callback) { clearInterval(ele.timer) //清除之前的定时器影响 //针对于px为单位的 width,height,left,top //opacity不需要px //zIndex不需要动画 //获取target对象里面的所有的key ele.timer = setInterval(() => { var flag = true for (let key in target) { //获取当前位置 var current = parseFloat(getStyle(ele, key)) ? parseFloat(getStyle(ele, key)) : 0 //定义步长和对应的目标位置 if(key == 'opacity'){ var step = target[key] - current > 0 ? 0.01 : -0.01 }else{ var step = target[key] - current > 0 ? 10 : -10 } //定时器 if (key == 'zIndex') { //层级 ele.style[key] = target[key] //直接设置 } else { //没有到达设置为false if (Math.abs(target[key] - current ) > step) { flag = false } if (isBuffer) { //如果是缓冲的 if (key == 'opacity') { //透明度 // 最小值 0.01 step = (target[key] - current) * 100 / 10 > 0 ? Math.ceil((target[key] - current) * 100 / 10) / 100 : Math.floor((target[key] - current) * 100 / 10) / 100 } else { //其他的 //控制步长的变化 离目标会越来越小 把步长和这个距离绑定 step = (target[key] - current) / 10 > 0 ? Math.ceil((target[key] - current) / 10) : Math.floor((target[key] - current) / 10) } } //控制当前位置的变化 current += step //给当前位置赋值 if (key != 'opacity') { ele.style[key] = current + 'px' } else { ele.style[key] = current } } } if (flag) { clearInterval(ele.timer) //如果你的回调是一个函数就执行 if(callback instanceof Function){ callback() } } }, 20) }
回到顶部的实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div{ height: 1500px; } button{ display: none; position: fixed; bottom: 50px; right: 30px; } </style> </head> <body> <div></div> <button>回到顶部</button> <script src="./move.plus.js"></script> <script> //滚动栏 监听滚动栏滚动 var btn = document.querySelector('button') window.onscroll = function(){ if(window.scrollY >= 500){ btn.style.display = 'block' move(btn,{opacity:1}) }else{ move(btn,{opacity:0}) } } btn.onclick = function(){ //将对应的滚动栏 以缓冲动画运动到对应的位置0 var target = 0 var current = window.scrollY var step = (target - current)/10 > 0 ? Math.ceil((target - current)/10) : Math.floor((target - current)/10) var timer = setInterval(() => { current += step window.scrollTo(0,current) if(current == target){ clearInterval(timer) } }, 20); } </script> </body> </html>
第三方 move.js
主要使用
to 从当前位置到达某个位置(x,y)
set 设置相关样式 (样式名,样式值)
end 结束当前动画
duration 运动的时长(默认时长为0.5s)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .box{ width: 100px; height: 100px; } </style> </head> <body> <div class="box"></div> <script src="./move.min.js"></script> <script> move('.box') .to(500, 200) //到某个位置 to到某个位置 set 设置相关样式 then回调 end 表示结束 duration 总时长 // .rotate(180) // .scale(.5) .set('background-color', '#888') .set('border-color', 'black') .duration('2s') // .skew(50, -10) // .then()//回调 // .set('opacity', 0) // .duration('0.3s') // .scale(0.1) // .pop() .end(); </script> </body> </html>
标签:10,target,16,ele,current,key,var,运动,day From: https://www.cnblogs.com/jxooooolxe/p/16629978.html