上述案例主要使用定时器,和绝对定位产生动画
<script setup>
import { ref, onMounted, watch } from 'vue'
// ----------------------- 01 js 动画介绍---------------------
// 1、匀速运动
// 2、缓动运动(常见)
// 3、透明度运动
// 4、多物体运动
// 5、多值动画// 6、自己的动画框架
// css3属性的transition 和 animation 可以实现运动// ------------------------ 02 简单运动 ------------------------
// 简单动画存在问题:1、处理边界 2、定时器的管理
const dom = ref(null)
let num = ref(0)
let timer = null
const play = () => {// 先关闭定时器,再开启定时器,防止定时器累加,导致物体加快clearInterval(timer)// 让物体运动起来(定时器)timer = setInterval(() => {// num.value++// dom.value.style.left = num.value + 'px'if (dom.value.offsetLeft === 500) {// clearInterval(timer)dom.value.style.left = 0 + 'px'// return} else {dom.value.style.left = dom.value.offsetLeft + 5 + 'px'}// 使用return或者else 都可以// dom.value.style.left = dom.value.offsetLeft + 5 + 'px'}, 30);
}
const Pause = () => {clearInterval(timer)
}// ----------------------- 03 侧边栏效果------------------
const boxDom = ref(null)
let isShow = ref(true)
const pull = () => {if (isShow.value) {isShow.value = false} else {isShow.value = true}boxDom.value.style.left = 0
}
const hide = () => {if (!isShow.value) {isShow.value = true} else {isShow.value = false}boxDom.value.style.left = -200 + 'px'
}// 缓动动画 0 ~ 200 公式:加速度 = (结束值 - 起始值) / 缓动系数 加速度由慢到快
const boxDom1 = ref(null)
window.onload = () => {let target = 0let target1 = -200boxDom1.value.onmouseover = () => { showAimation(boxDom1.value, target) }boxDom1.value.onmouseout = () => { showAimation(boxDom1.value, target1) }// ----------------- 04 透明度动画 --------------------// 鼠标移入移出boxDom3.value.onmouseover = () => {opacityAnimation(boxDom3.value, 100)}boxDom3.value.onmouseout = () => {opacityAnimation(boxDom3.value, 30)}
}// 缓动动画 0 ~ 200 公式:加速度 = (结束值 - 起始值) / 缓动系数 加速度由慢到快
let timer1 = null
const showAimation = (dom, end) => {clearInterval(timer1)timer1 = setInterval(() => {let speed = (end - dom.offsetLeft) / 10 // 如果速度大于0,向上取整,否则向下取整 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed) // 判断是否到达目标点 if (dom.offsetLeft === end) {clearInterval(timer1)return}dom.style.left = dom.offsetLeft + speed + 'px'}, 30);
}// 04 透明度动画
const boxDom3 = ref(null)
let alpha = 30
let speed = 0
let timer2 = nullconst opacityAnimation = (dom, endAlpha) => {clearInterval(timer2)timer2 = setInterval(() => {// 求透明度的变化速度speed = endAlpha > alpha ? 5 : -5// 边界的处理if (alpha === endAlpha) {clearInterval(timer2)return}// 改变当前的alpha的值alpha += speed// 改变当前的透明度dom.style.opacity = alpha / 100dom.style.filter = 'alpha(opacity=' + alpha + ')'}, 30);
}// 上下跳动循环播放
const circle = ref(null)
let timer3 = null
const circlePlay = () => {clearInterval(timer3)let direction = 1; // 初始方向:1 表示向下,-1 表示向上timer3 = setInterval(() => {if (circle.value.offsetTop > 100) {console.log(circle.value.offsetTop, '--circle.value.offsetTop--');direction = -1; // 到达底部,改变方向为向上} else if (circle.value.offsetTop <= 50) {direction = 1; // 到达顶部,改变方向为向下}// 根据方向调整移动方式circle.value.style.top = circle.value.offsetTop + (1 * direction) + 'px';}, 30);
}const circlePause = () => {clearInterval(timer3)
}onMounted(() => {
})
</script><template><div class="main"><div class="card-body"><!-- 02 简单运动 --><button id="btn" @click="play">Play</button><button id="btn" @click="Pause">Pause</button><div class="info" ref="dom">dom简单运动</div></div><!-- 03 侧边栏效果 --><div id="box" ref="boxDom">box侧边栏效果 过渡动画<span @click="pull" v-if="isShow">拉开</span><span @click="hide" v-if="!isShow">收起</span></div><!-- 03 侧边栏效果 缓动动画 --><div id="box1" ref="boxDom1">box1侧边栏效果 缓动动画<span>拉开</span></div><div><div style="display: flex;"><button id="btn" @click="circlePlay">Play</button><button id="btn" @click="circlePause">Pause</button></div><!-- 上下循环跳动效果 --><div id="box2">box2上下循环跳动效果<span ref="circle">跳</span></div></div><!-- 04 透明度动画 --><div id="box3" ref="boxDom3">box3透明度动画</div></div></template><style scoped lang="less">
.main {display: flex;flex-direction: column;#btn {width: 80px;height: 40px;border: 1px solid #000;background-color: #829fff;}.card-body {position: relative;height: 240px;.info {position: absolute;left: 0;top: 40px;width: 200px;height: 200px;background-color: pink;}}// 03 侧边栏效果 过渡效果#box {position: relative;left: -200px;transition: all 0.3s; // 过渡效果width: 200px;height: 200px;background-color: rgb(255, 244, 150);span {position: absolute;right: -40px;top: 50%;transform: translateY(-50%);width: 40px;height: 60px;text-align: center;line-height: 60px;background-color: black;color: floralwhite;cursor: pointer;}}// 03 侧边栏效果 缓动动画#box1 {position: relative;left: -200px;width: 200px;height: 200px;background-color: rgb(150, 192, 255);span {position: absolute;right: -40px;top: 50%;transform: translateY(-50%);width: 40px;height: 60px;text-align: center;line-height: 60px;background-color: black;color: floralwhite;cursor: pointer;}}// 上下跳动动画#box2 {position: relative;width: 200px;height: 200px;background-color: rgb(150, 192, 255);span {position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);width: 50px;height: 50px;border-radius: 50%;text-align: center;line-height: 50px;background-color: black;color: floralwhite;cursor: pointer;}}// 04 透明度动画#box3 {width: 200px;height: 200px;background-color: red;color: #fff;opacity: 0.3;// 支持ie8以下浏览器filter: alpha(opacity=30);}
}
</style>