动态效果视频:轮播图 动态效果-优快云直播
思路:
使用swiper 轮播图,每页轮播图展示6个圆圈,分别给每一个小圆圈设置一个距离顶部的距离,也就是给每个小圆圈一个类名 class0~class5,这里是便于后面移动
在我们切换到下一页的时候,后面的小圆圈会补位 就会变成如下图所示的样子
如果想要达到一开始的半月状的样子,就需要进行给每一个小圆圈替换class,改变每一个小圆圈的距离顶部的位置来达到原先的样子不变 也就是class1的小圆圈的类名需要变成class0,class2的类名需要变成class1 依次类推。但是最后一个class6没有设置距离顶部的高度,因此他会直接从margin-top:0 到class5距离顶部的距离,看起来会很突兀,因此class6需要一开始设置和class5相同的高度进来动画效果就会很连贯,同理,轮播图向左边移动的时候需要给class-1 设置与class0相同的高度,接着 在每一个class切换的时候加上样式
代码:
<template>
<div class="swiper">
<swiper
:modules="modules"
:slides-per-view="6"
:allowTouchMove="false"
:space-between="50"
:pagination="{ clickable: true }"
@slideChange="onSlideChange">
@swiper="onSwiper"
<swiper-slide v-for="(item, index) in list" :virtual-index="index">
<div class="box">
<div
:class="'circle circle' + (index % 6)"
@mouseenter="onmouseenter(index)"
@mouseleave="onmouseleave(index)">
<p style="font-size: 20px">{
{ item.name }}</p>
<p>{
{ item.title }}</p>
</div>
</div>
</swiper-slide>
</swiper>
</div>
</template>
<script setup>
import { Swiper, SwiperSlide } from 'swiper/vue'
// 引入 swiper 所需模块
import { Autoplay, Pagination, Navigation, Scrollbar, A11y, Virtual } from 'swiper/modules'
// Import Swiper styles
import 'swiper/css'
import 'swiper/css/navigation'
import 'swiper/css/pagination'
import 'swiper/css/scrollbar'
import { ref } from 'vue'
// 在 modules 加入要使用的模块
const modules = ref([Autoplay, Pagination, Navigation, Scrollbar, A11y, Virtual])
const list = ref([
{ name: 23, title: '土豆泥' },
{ name: 50, title: '西瓜瓤' },
{ name: 50, title: '方便面' },
{ name: 50, title: '脆桃子' },
{ name: 20, title: '车厘子' },
{ name: 11, title: '菠萝蜜' },
{ name: 22, title: '梨子膏' },
{ name: 32, title: '芒果干' }
])
const swiperVal = ref(null)
const eventIndex = ref(0)
// 初始化 swiper
const onSwiper = (swiper) => {
swiperVal.value = swiper
}
let circleBox = document.getElementsByClassName('circle')
// swiper切换事件
const onSlideChange = (event) => {
let circle = Array.from(circleBox)
circle.forEach((item, index) => {
// 移除class 属性
item.removeAttribute('class')
// 给当前元素添加class 通过当前点击到的swiperIndex下标以及index属性进行计算
item.classList.add('circle' + (index - event.realIndex))
// 添加共有属性
item.classList.add('circle')
item.style.transition = 'all 0.6s ease-in-out'
})
eventIndex.value = event.realIndex
}
const onmouseenter = (index) => {
circleBox[index].style.animation = 'box-shadows 1s infinite'
}
const onmouseleave = (index) => {
circleBox[index].style.animation = 'none'
}
</script>
<style lang="scss">
.swiper {
width: 1000px;
height: 500px;
border: 1px solid black;
background-image: url('https://copyright.bdstatic.com/vcg/creative/03a6047ae731c04122ff73e4e94712fe.jpg@h_1280');
}
.box {
width: 200px;
height: 100%;
margin: 0 auto;
}
.circle {
width: 120px;
height: 120px;
border-radius: 50%;
border: 3px solid #fff;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.circle-1 {
margin-top: 320px;
}
.circle0 {
margin-top: 320px;
}
.circle1 {
margin-top: 200px;
}
.circle2 {
margin-top: 100px;
}
.circle3 {
margin-top: 100px;
}
.circle4 {
margin-top: 200px;
}
.circle5 {
margin-top: 300px;
}
.circle6 {
margin-top: 300px;
}
@keyframes box-shadows {
0% {
box-shadow: 0 0 0 0px rgba(255, 255, 255, 0.5);
}
100% {
box-shadow: 0 0 0 20px rgba(255, 255, 255, 0);
}
}
</style>