学习Js-day16

Javascript之运动

在开启定时器setInterval()/setTimeout()和清楚定时器clearInterval()/clearTimeout()来控制运动,其中setInterval()方法可以让物体动起来,而clearInterval()方法可以让运动停止;在定时器过程中不断更改需要改变的值。

1.定时器(异步的,多次)

let id = setInterval(function(){},毫秒值)
clearInterval(id)

2.延时器(异步的,只执行一次)

setTimeout(function(){},延迟的毫秒值)

3.DOM操作

获取样式

//获取样式的方法
function getStyle(ele, attr) {
    return window.getComputedStyle ? window.getComputedStyle(ele, null)[attr] : ele.currentStyle[attr]
}

设置样式

element.style.样式名 = 样式值

4.offset家族

offsetParent 偏移的父元素(从里往外找 先加了定位就是谁 找不到就找body)
 
offsetWidth 宽度 offsetHeight 高度
 
offsetLeft 离左边的距离 offsetTop 离上面的距离

5.区间的判断

(target - current) <= step //区间判断

6.计算公式

Math.round(Math.random() * (max-min) + min) //随机整数

一,匀速运动

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

原理:从头到尾一直保持一个速度,即每次运动相同的距离,也称为平滑运动。
分析:①实现匀速运动效果,我们先设置元素样式,然后通过 document.getElementById(id)获取到对应的id节点元素。
②关闭上一次定时器
③定义speed速度(可以随意定义运动的速度值)
④设置运动和停止分开

<!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 = 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)
}

 

posted @ 2022-08-15 21:34  可爱就要得到  阅读(46)  评论(0)    收藏  举报