高效开发大屏可视化项目第二弹:入场动画和无缝滚动
点击小卡片参与粉丝专属福利
这是一个基于Vue 3、Echarts、高德地图和Pinia开发的大屏可视化项目,提供了如下功能
大屏适配图表组件(Echarts)封装高德地图组件封装拖拽布局入场动画无缝滚动源码地址:https://github.com/vangleer/es-big-screen
在线示例:https://vangleer.github.io/es-big-screen/#/screen
前言 上一篇文章分享了大屏适配、图表组件(Echarts)封装、拖拽布局以及地图组件等功能的封装
高效开发大屏可视化项目:公共组件封装指南
今天主要分享大屏入场动画和无缝滚动相关功能的实现
入场动画 最终效果展示
主要使用了CSS动画
Header 动画src/views/screen/components/Header.vue 一个简单的淡入动画
.es-screen-header{
animation:fade3s;
}
@keyframesfade{
from{
opacity:0;
}
to{
opacity:1;
}
}
Left 左侧动画src/views/screen/components/left/index.vue
.es-screen-left-item{
/*...*/
&:nth-child(1){
height:550px;
animation-duration:.8s;//新增
}
&:nth-child(2){
animation-duration:1.5s;//新增
}
}
@keyframesslide{
0%{
transform:translateX(-100%);
}
80%{
transform:translateX(20px);
}
100%{
transform:translateX(0);
}
}
左侧定义一个滑入动画,从左侧-100%进入到20px最后回到0原来的位置,这样定义会有一个弹的效果
Right 右侧动画src/views/screen/components/right/index.vue
.es-screen-right-item{
/*...*/
animation-name:slide;
&:nth-child(1){
animation-duration:0.5s;//新增
}
&:nth-child(2){
animation-duration:1s;//新增
}
&:nth-child(3){
animation-duration:1.5s;//新增
}
}
@keyframesslide{
0%{
transform:translateX(100%);
}
80%{
transform:translateX(-20px);
}
100%{
transform:translateX(0);
}
}
与左侧类似,只是方向变了
Center 中间地图入场动画src/views/screen/components/center/index.vue
.es-center{
animation:slideAndFade1.5s;//新增
}
@keyframesslideAndFade{
0%{
transform:translateY(218px);
opacity:0;
}
100%{
transform:translateX(0);
opacity:1;
}
}
从下往上移动,移动的同时淡入显示
无缝滚动封装 无缝滚动在大屏可视化项目中非常常见,本小节使用animejs实现了一个支持横纵无缝滚动的自定义钩子
先安装一下 animejs 的依赖
yarn add animejs
直接上代码
import{onMounted,shallowRef,Ref}from'vue'
importanimefrom'animejs/lib/anime.es.js'
exporttypeOptionsType={
direction?:'horizontal'|'vertical'
gap?:number
duration?:number
}
exportfunctionuseSeamlessScroll(listRef:RefHTMLElement|null,options:OptionsType={}){
const{
direction='horizontal',
gap=10,
duration=10000
}=options
constanimation=shallowRefReturnTypetypeofanime(null)
functioninit(){
constisHorizontal=direction==='horizontal'
consttranslateKey=isHorizontal?'translateX':'translateY'
consttransKey=isHorizontal?'x':'y'
//items
constchildren=listRef.value?.children||[]
if(!children.length)return
//第一个元素
constfirstEl=children[0]asHTMLElement
constfirstDiff=(isHorizontal?firstEl.offsetWidth:firstEl.offsetHeight)+gap
//默认将list元素向左或向上移动一个item的距离
listRef.value!.style.transform=`${translateKey}(-${firstDiff}px)`
consttransList:any=[]
lettotal=0//总宽/高
//设置初始位置
anime.set(children,{
[translateKey]:(el:HTMLElement,i)={
constdistance=(isHorizontal?el.offsetWidth:el.offsetHeight)+gap
total+=distance
transList[i]={[transKey]:total-distance}
}
})
//设置list容器的宽或高
listRef.value!.style[isHorizontal?'width':'height']=total+'px'
//添加动画
animation.value=anime({
targets:transList,
duration,
easing:'linear',
direction:isHorizontal?undefined:'reverse',
[transKey]:`+=${total}`,
loop:true,
update:()={
anime.set(children,{
[translateKey]:(el,i)={
returntransList[i][transKey]%total
}
})
}
})
}
//暂停
functionpause(){
animation.value!.pause()
}
//停止
functionplay(){
animation.value!.play()
}
onMounted(()={
init()
})
return{
listRef,
pause,
play,
animation
}
}
useSeamlessScroll 接受两个参数:listRef 和 options。listRef 是一个 Ref 对象,用于引用滚动列表的 DOM 元素。options 是一个配置对象,可以设置滚动的方向、间隙和持续时间。
步骤解析:
根据传入的滚动方向,确定 translateKey 和 transKey,translateKey 表示 CSS 中的移动方向,transKey 表示animejs中的x/y轴方向。
获取滚动列表的子元素,并计算第一个元素的偏移量。因为默认从从第二个元素开始,这样初始移动是才不会出现空白
初始化滚动列表的位置,将其向左(横向滚动)或向上(纵向滚动)移动一个元素的距离。
遍历子元素,计算每个元素的偏移量,并将其设置为初始位置。
根据滚动方向,设置滚动列表容器的宽度或高度。
使用 animejs 库实现无缝滚动效果,在动画更新时,根据计算出的偏移量更新子元素的位置
使用 useSeamlessScrolltemplate
divclass="es-center-bottom"
divref="listRef"class="es-bottom-list"
divv-for="itemin10"class="es-bottom-item"
{{item}}
/div
/div
/div
/template
scriptsetuplang='ts'
import{ref}from'vue'
import{useSeamlessScroll}from'@/utils/useSeamlessScroll'
constlistRef=ref()
useSeamlessScroll(listRef)
/script
stylelang='scss'scoped
.es-center-bottom{
position:relative;
width:100%;
overflow:hidden;
height:150px;
.es-bottom-item{
position:absolute;
top:
left:
width:170px;
height:150px;
display:flex;
flex-direction:column;
justify-content:center;
align-items:center;
background-color:var(--es-block-bg);
font-size:22px;
font-weight:
.es-item-text{
margin-top:16px;
}
}
}
/style
可以看到用了两层包裹列表,最外面一层的作用是防止溢出,第二层才是偏移的列表元素
08.gif抽离成组件简化使用方式 新建 src/components/SeamlessScroll.vue
template
divclass="es-seamless-scroll"
divref="listRef"class="es-seamless-scroll-list"
slot/
/div
/div
/template
scriptsetuplang='ts'
import{useSeamlessScroll,OptionsType}from'@/utils/useSeamlessScroll'
import{PropType,ref}from'vue'
constprops=defineProps({
width:{
type:[String,Number]
},
height:{
type:[String,Number]
},
option:{
type:ObjectasPropTypeOptionsType,
default:()=({})
}
})
constlistRef=ref()
useSeamlessScroll(listRef,props.option)
/script
stylelang='scss'scoped
.es-seamless-scroll{
overflow:hidden;
width:100%;
height:100%;
}
/style
使用组件
template
SeamlessScrollclass="es-center-bottom"
divv-for="itemin10"class="es-bottom-item"
{{item}}
/div
/SeamlessScroll
/template
scriptsetuplang='ts'
importSeamlessScrollfrom'@/components/SeamlessScroll.vue'
/script
stylelang='scss'scoped
.es-center-bottom{
position:relative;
width:100%;
overflow:hidden;
height:150px;
.es-bottom-item{
position:absolute;
top:
left:
width:170px;
height:150px;
display:flex;
flex-direction:column;
justify-content:center;
align-items:center;
background-color:var(--es-block-bg);
font-size:22px;
font-weight:
.es-item-text{
margin-top:16px;
}
}
}
/style
效果和直接使用钩子一样,不过组件使用起来还是要简单一点
组件默认是横向滚动,如果想纵向滚动传入direction为vertical即可template
SeamlessScrollclass="es-list":option="{direction:'vertical'}"
divv-for="itemin15"class="es-item"{{'热销商品的占比'+item}}/div
/SeamlessScroll
/template
scriptsetuplang='ts'
importSeamlessScrollfrom'@/components/SeamlessScroll.vue'
/script
stylelang='scss'scoped
.es-list{
position:relative;
width:100%;
height:100%;
overflow:hidden;
.es-item{
position:absolute;
height:20px;
}
}
/style
09.gif最后 本文介绍了入场动画和无缝滚动方面的实现,你可以根据示例代码进行实践和定制
如果你对该项目模板感兴趣,可以通过源码地址和在线示例链接来获取更多信息,并进行进一步的学习和应用
如果文章对你有帮助的话欢迎「关注+点赞+收藏」
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线