首页 > 其他分享 >运动

运动

时间:2022-08-15 20:13:41浏览次数:51  
标签:10 target ele current key var 运动

概述

运动主要是动画的操作,主要是操作某个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,ele,current,key,var,运动
From: https://www.cnblogs.com/bigBossKiss/p/16589476.html