运动
运动
概述:
运动主要是动画的操作,主要是操作某个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>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律