vue3+ts大屏看板---横向轮播(anime.js)
vue3+ts+anime.js大屏看板--横向轮播
1. 安装和引入anime.js
1. 安装
npm install animejs --save
因为使用ts所以还要同时下载npm i --save-dev @types/animejs
2. 引入
import anime from 'animejs';
* 引入报错:引入时候报错
无法找到模块“animejs”的声明文件。“/Users/zhaomengqi/Desktop/mq2023/vue3-admin/node_modules/animejs/lib/anime.js”隐式拥有 "any" 类型。
尝试使用 `npm i --save-dev @types/animejs` (如果存在),或者添加一个包含 `declare module 'animejs';` 的新声明(.d.ts)文件ts(7016)
根据提示已经下载过,需要在根目录下
创建index.vue.d.ts
文件,添加下边一行代码就可以了
declare module 'animejs'
- anime使用到的一些属性
时间曲线:easing:
easing: ‘linear’//匀速
easing: ‘easeInOutSine’//不匀速
动画方向:direction
direction: ‘horizontal’//水平正方向
direction: ‘reverse’//水平反方向
2. 基于vue3+ts+anime.js实现一个大屏组件轮播效果,如下
1. 写一个需要轮播的模块样式
✏️ 代码(有写注释)
<template>
<div class="es-center-bottom">
<div ref="listRef" class="es-bottom-list" >
<div v-for="item in picList" class="es-bottom-item" >
<img :src="getImgUrl(item.pic)" alt="">
</div>
</div>
</div>
</template>
<script setup lang="ts" name="carousel">
import anime from 'animejs';
const picList = [
{pic:'../../assets/pic/pci1.svg'},
{pic:'../../assets/pic/pci2.svg'},
{pic:'../../assets/pic/pci3.svg'},
{pic:'../../assets/pic/pci4.svg'},
{pic:'../../assets/pic/pci5.svg'},
{pic:'../../assets/pic/pci6.svg'},
{pic:'../../assets/pic/pci7.svg'},
{pic:'../../assets/pic/pci8.svg'},
{pic:'../../assets/pic/pci9.svg'},
]
const getImgUrl = (src: string): string => {
return new URL(`${src}`, import.meta.url).href;
};
</script>
<style scoped lang="scss">
.es-center-bottom {
padding-top: 20px;
position: relative;
width: 500px;
overflow: hidden;
height: 150px;
background-color: #1e108ddf;
.es-bottom-item {
position: absolute;
top: 0;
left: 0;
width: 70px;
height: 80px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #e0e1e7f1;
font-size: 22px;
font-weight: 600;
img{
width: 40px;
}
}
}
</style>
📖 运行效果
2. 加入横向轮播图动画
✏️ 直接上代码(有写注释)
///动画相关代码
const listRef = ref()
let spacing = 10//模块之间的间距
var animation = shallowRef<ReturnType<typeof anime>>(null)
const init = () => {
// 动画中所有模块实例对象集合
const children = listRef.value?.children || []
//如果没有实例作拦截
if (!children.length) return
// 获取列表集合中第一个元素宽,通过宽和元素之间的间距计算出移动距离firstDiff
const firstEl = children[0] as HTMLElement
const firstDiff = firstEl.offsetWidth + spacing
// 默认将list元素向左移动一个item的距离
listRef.value!.style.transform = `translateX(-${firstDiff}px)`
const transList: any = []
let total = 0 //声明总宽
// 设置初始位置
anime.set(children, {
['translateX']: (el: HTMLElement, i: number) => {
//计算得出总宽
const distance = el.offsetWidth + spacing
total += distance
//设置初始运动点为0
const diff = (i + 1) * distance
//收集所有小模块运动x轴点值
transList[i] = { ['x']: diff }
return diff
}
})
// 设置list容器的宽或高
listRef.value!.style['width'] = total + 'px'
// 添加动画
animation.value = anime({
targets: transList,
duration:8000,//一个动画时间
easing: 'linear',
direction: 'horizontal',
['x']: `+=${total}`,
loop: true,//是否循环
update: () => {
anime.set(children, {
['translateX']: (_el: any, i: string | number) => {
return transList[i]['x'] % total
}
})
},
})
}
onMounted(() => {
init()
})
📖 运行效果
3. 添加鼠标移入暂停,移出继续的事件
//鼠标移入事件
const eover = () => {
animation.value.pause()
}
//鼠标移出事件
const eout = () => {
animation.value.play()
}