上述案例主要使用定时器,和绝对定位产生动画
<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 = 0
let target1 = -200
boxDom1.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 = null
const 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 / 100
dom.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>