运动

运动

概述:

运动主要是动画的操作,主要是操作某个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>
    <link rel='stylesheet' href=''>
    <style>
        div {
            position: relative;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
    </style>
</head>

<body>
    <!-- 
    运动主要是动画的操作,主要操作某个ducument元素的属性变化(位置变化)
    运动主要的三步骤
    1、使用定时器来定时更改对应的内容
    2、实时获取对应的元素的属性及内容
    3、判断是否达到目标位置(到达后清除定时器)

    匀速运动
    本质:每次变化的值都是同一个

    缓冲运动
    本质:每次变化的值越来越小

 -->
    <button>匀速运动</button>
    <button>匀速运动1</button>
    <div></div>
    <script>
        // 获取div
        var btn = document.querySelectorAll('button')
        var div = document.querySelector('div')
        btn[1].onclick = () => {
            move(div, 50)
        }
        btn[0].onclick = () => {
            move(div, 500)
            // 定时器
            // var step = 10
            // var target = 500
            // var cur = 0
            // var timer = setInterval(()=>{
            //      // 在定时器内控制div位置变化
            //      cur+=step
            //      div.style.left = cur+'px'
            // // 当到达目标位置清除定时器
            // if(cur==target){
            //     // div.style.left =0+'px' 
            //     clearInterval(timer)
            // }
            // },100)
        }

        function move(ele, target) {
            var current = parseInt(getStyle(ele, 'left'))
            var step = target - current > 0 ? 10 : -10
            var timer = setInterval(() => {
                // 在定时器内控制div位置变化
                current += step
                div.style.left = current + 'px'
                // 当到达目标位置清除定时器
                if (current == target) {
                    // div.style.left =0+'px' 
                    clearInterval(timer)
                }
            }, 20)
        }
        // 获取样式的方法
        function getStyle(ele, attr) {
            return window.getComputedStyle ? window.getComputedStyle(ele, null)[attr] : ele.currentStyle[attr]
        }
    </script>
</body>

</html>

三、缓冲运动

概述:缓冲运动的本质就是每次变化的值越来越小

示例:

<!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>
<link rel='stylesheet' href=''>
<style>
    div{
        width: 100px;
        height: 100px;
        background-color: pink;
        position: relative;
    }
</style>
</head>
<body>
<button>从左到右</button>
<button>从右到左</button>
<div></div>
<script>
    // 缓冲运动
    // 获取div和对应的按钮
    var btns = document.querySelectorAll('button')
    var box = document.querySelector('div')
   btns[0].onclick =()=>{
    move(box,500)
    //  // 获取当前位置
    // // 定义步长和对应的目标位置
    // var current = parseInt(getStyle(box,'left'))
    // var step = 10//初始步长
    // var target = 500//目标位置
    // // 定时器
    // var timer = setInterval(()=>{
    //     // 控制步长的变化 离目标位置的距离会越来越小 把步长和这个距离bangding
    //     step = Math.abs((target-current)/20)>1?Math.floor((target-current)/20):Math.ceil((target-current)/20)
    //     // 控制当前位置的变化
    //     current+=step
    //     // 给当前位置赋值
    //     box.style.left = current+'px'
    //     // 到达目标位置清除定时器
    //     if(current==target){
    //         clearInterval(timer)
    //     }

    // },80)
   }
   btns[1].onclick =()=>{
    move(box,0)
    //  // 获取当前位置
    // // 定义步长和对应的目标位置
    // var current = parseInt(getStyle(box,'left'))
    // var step = 10//初始步长
    // var target = 0//目标位置
    // // 定时器
    // var timer = setInterval(()=>{
    //     // 控制步长的变化 离目标位置的距离会越来越小 把步长和这个距离bangding
    //     step = Math.abs((target-current)/20)>1?Math.floor((target-current)/20):Math.ceil((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]
    }
    // 提取
    function move(ele,target){
 var current = parseInt(getStyle(ele,'left'))
    var step = 10//初始步长
    // 定时器
    var timer = setInterval(()=>{
        var tool = target-current>0?1:-1
        // 控制步长的变化 离目标位置的距离会越来越小 把步长和这个距离bangding
        step = (target-current)/20>tool?Math.floor((target-current)/20):Math.ceil((target-current)/20)
        // 控制当前位置的变化
        current+=step
        // 给当前位置赋值
        ele.style.left = current+'px'
        // 到达目标位置清除定时器
        if(current==target){
            clearInterval(timer)
        }

    },80)
    }
</script>
</body>
</html>

四、匀速运动和缓冲运动的封装

//获取样式的方法
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)
}

五、透明度变化

<!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>
<link rel='stylesheet' href=''>
<style>
    div{
        width: 100px;
        height: 100px;
        background-color: purple;
    }
</style>
</head>
<body>
<button>透明度变化-</button>
<button>透明度变化+</button>
<div></div>
<script>
    // 透明度变化
    // 获取按钮及div
    var box = document.querySelector('div')
    var btns = document.querySelectorAll('button')
    btns[0].onclick=()=>{
        opacityChange(box,0.15)
    //     // 获取当前的透明度
    // // 设置步长及对应的目标位置
    // var step
    // var target = 0.5
    // var cur = parseFloat(getStyle(box,'opacity'))
    // // 开启定时器
    // var timer = setInterval(()=>{
    //     // 匀速
    //     // step=target-cur>0?0.1:-0.1
    //     // 缓冲 最小值0.01 
    //     // 当透明度到达目标位置清除定时器
    //     if(Math.abs(target-cur)<=step){
    //         clearInterval(timer)
    //     }
    //     step =(target-cur)*100/10>0?Math.ceil((target-cur)*100/10):Math.floor((target-cur)*100/10)
    //     // 控制透明度的变化
    //     cur+=step/100
    //     box.style.opacity = cur
       
    // },20)
   
    
    }
    btns[1].onclick=()=>{
        opacityChange(box,0.8)
    }
    // 透明度变化
    function opacityChange(box,target){
         // 获取当前的透明度
    // 设置步长及对应的目标位置
    var step
    var cur = parseFloat(getStyle(box,'opacity'))
    // 开启定时器
    var timer = setInterval(()=>{
        // 匀速
        // step=target-cur>0?0.1:-0.1
        // 缓冲 最小值0.01 
        // 当透明度到达目标位置清除定时器
        if(Math.abs(target-cur)<=step){
            clearInterval(timer)
        }
        step =(target-cur)*100/10>0?Math.ceil((target-cur)*100/10)/100:Math.floor((target-cur)*100/10)/100
        // 控制透明度的变化
        cur+=step
        box.style.opacity = cur
       
    },20)
    }
    // 获取样式的方法
    function getStyle(ele,attr){
        return window.getComputedStyle?window.getComputedStyle(ele,null)[attr]:ele.currentStyle[attr]
    }
</script>
</body>
</html>

六、宽度的变化(缓冲)

<!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>
<link rel='stylesheet' href=''>
<style>
    div{
        width: 100px;
        height: 100px;
        background-color: pink;
    }
</style>
</head>
<body>
    <button>宽度的变化缓冲</button>
<div></div>
<script>
    // 获取按钮及div
    var box = document.querySelector('div')
    var btn = document.querySelector('button')
    btn.onclick=()=>{
        // 获取开始的宽度以及步长
    var cur = parseFloat(getStyle(box,'width'))
    var step
    var target = 500
    // 设置目标位置
    var timer =setInterval(()=>{
         // 判断是否到达目标位置
         if(Math.abs(target-cur)<=step)
        clearInterval(timer)
        // 设置步长
        step = (target-cur)/10>0?Math.ceil( (target-cur)/10):Math.floor( (target-cur)/10)
        // 设置当前位置
        cur+=step
        box.style.width = cur+'px'
       
    },20)
    }
 // 获取样式的方法
 function getStyle(ele, attr) {
        return window.getComputedStyle ? window.getComputedStyle(ele, null)[attr] : ele.currentStyle[attr]
    }

</script>
</body>
</html>

七、简易封装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 {
                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)
                    }
                }
                //没有到达设置为false
                if (Math.abs(target[key] - current ) > Math.abs(step)) {
                    flag = false
                }
                //控制当前位置的变化
                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},true,()=>{
                    btn.style.display = 'none'
                })
            }
        }
        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(600, 250) //到某个位置 to到某个位置  set 设置相关样式 then回调  end 表示结束 duration 总时长
        // .rotate(180)
        // .scale(.5)
        .set('background-color', 'purple')
        .set('border-color', 'black')
        .duration('2s')
        // .skew(50, -10)//倾斜
        // .then()//回调
        .set('opacity', 1)
        //     .duration('0.3s')
            // .scale(0.1)//缩放
            // .pop()//删除
        .end();
    </script>
</body>
</html>

 

posted @   木木子夕  阅读(279)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示