这里把方法抽取成JS文件,文件2是同时运动,对传入的属性,以及边界除了进行了改动,使代码更加完善。
/**
* 动画的函数 ./MyJSAnimation/myJsAnimation.js
* dom 当前对象
* attr 当前元素对象的属性
* endtarget 末尾位置
* -------------------- 多物体运动, 链式运动 ----------------
*/
let speed1 = 0
export function startAnimation(dom, attr, endTarget, fn) {
// 注意:针对于多物体运动,定时器的返回值要绑定当前的对象中。offsetWidth获取的是包括border的宽度,所以这里使用getComputed获取width
clearInterval(dom.timer)
dom.timer = setInterval(() => {
let cur = 0
// 0 获取样式属性
// 透明度变化处理
if (attr === 'opacity') {
// 求透明度的变化速度,注意!小数需要取整
cur = Math.round(parseFloat(getStyle(dom, attr)) * 100)
} else {
// 获取dom宽度或高度等
cur = parseInt(getStyle(dom, attr))
}
// 1、求速度
speed1 = (endTarget - cur) / 20
speed1 = endTarget > cur ? Math.ceil(speed1) : Math.floor(speed1)
// 2、临界处理
if (endTarget === cur) {
clearInterval(dom.timer)
if (fn) {
fn()
}
return
}
// 3、运动起来
if (attr === 'opacity') {
dom.style[attr] = `alpha(opacity=${cur + speed1})`
dom.style[attr] = (cur + speed1) / 100
} else {
dom.style[attr] = cur + speed1 + 'px'
}
}, 30)
// dom 是对象, attr 是什么属性
// 获取元素属性的方法
function getStyle(dom, attr) {
if (dom.currentStyle) {
// 针对IE浏览器
return dom.currentStyle[attr]
} else {
// 针对 Firefox浏览器
return getComputedStyle(dom, null)[attr]
}
}
}
/**
* 动画的函数 ./MyJSAnimation/myJsAnimation2
* dom 当前对象
* JSON 传入元素对象的属性 {"width": 300, "opacity": 50}
*
* -------------------- 多物体运动,同时运动 ---传入JSON-------------
*/
let speed1 = 0
export function startAnimation2(dom, JSON, fn) {
// 注意:针对于多物体运动,定时器的返回值要绑定当前的对象中。offsetWidth获取的是包括border的宽度,所以这里使用getComputed获取width
clearInterval(dom.timer)
dom.timer = setInterval(() => {
let cur = 0
let flag = true // 标杆 如果true,证明所有的属性都到达终点值
// 0 获取样式属性
for (let attr in JSON) {
if (attr === 'opacity') {
// 求透明度的变化速度,注意!小数需要取整
cur = Math.round(parseFloat(getStyle(dom, attr)) * 100)
} else {
// 获取dom宽度或高度等
cur = parseInt(getStyle(dom, attr))
}
// 1、求速度
speed1 = (JSON[attr] - cur) / 20
speed1 =JSON[attr] > cur ? Math.ceil(speed1) : Math.floor(speed1)
// 2、临界处理
if (JSON[attr] !== cur) {
flag = false
}
// 3、运动起来
if (attr === 'opacity') {
dom.style[attr] = `alpha(opacity=${cur + speed1})`
dom.style[attr] = (cur + speed1) / 100
} else {
dom.style[attr] = cur + speed1 + 'px'
}
}
if (flag) {
clearInterval(dom.timer)
if (fn) {
fn()
}
return
}
}, 30)
// dom 是对象, attr 是什么属性
// 获取元素属性的方法
function getStyle(dom, attr) {
if (dom.currentStyle) {
// 针对IE浏览器
return dom.currentStyle[attr]
} else {
// 针对 Firefox浏览器
return getComputedStyle(dom, null)[attr]
}
}
}
index.vue
<script setup>
import { ref, onMounted, watch } from 'vue'
import { startAnimation } from './MyJSAnimation/myJsAnimation.js'
import { startAnimation2 } from './MyJSAnimation/myJsAnimation2.js'
// ----------------------- 01 js 动画介绍---------------------
// 1、匀速运动
// 2、缓动运动(常见)
// 3、透明度运动
// 4、多物体运动
// 5、多值动画
// 6、自己的动画框架
// css3属性的transition 和 animation 可以实现运动
const boxDom6 = ref(null)
const boxDom7 = ref(null)
window.onload = () => {
// ----------------- 06 链式运动 --------------------
// 鼠标移入移出
boxDom6.value.onmouseover = () => {
startAnimation(boxDom6.value, 'height', 300, () => {
startAnimation(boxDom6.value, 'width', 500, () => {
startAnimation(boxDom6.value, 'opacity', 100, () => {
})
})
})
}
// ----------------- 07 同时运动 --------------------
// 鼠标移入移出
boxDom7.value.onmouseover = () => {
startAnimation2(boxDom7.value,{ 'opacity': 30, 'width': 500,} )
}
boxDom7.value.onmouseout = () => {
startAnimation2(boxDom7.value,{ 'opacity': 100, 'width': 200,} )
}
}
onMounted(() => {
})
</script>
<template>
<div class="main">
<!-- 06 链式运动 -->
<div id="box6" ref="boxDom6">
链式运动
</div>
<!-- 07 同时运动 -->
<div id="box7" ref="boxDom7">
同时运动
</div>
</div>
</template>
<style scoped lang="less">
.main {
display: flex;
flex-direction: column;
// 06 链式运动
#box6 {
width: 300px;
height: 100px;
background-color: red;
margin: 20px 0;
opacity: 0.3;
color: #fff;
}
// 07 同时运动
#box7 {
width: 300px;
height: 100px;
background-color: blue;
margin: 20px 0;
opacity: 1;
color: #fff;
}
}
</style>