这个效果的实现参考了swiper官网上的事例,事例如下:
https://www.swiper.com.cn/demo/progress-effect.html
https://www.swiper.com.cn/demo/140-centered-auto.html
使用了swiper的切换效果Effects中的coverflowEffect属性配置
<template>
<div class="carousel-card-page">
<swiper :options="options" class="swiper-container" ref="swiper">
<swiperSlide v-for="(info, index) in cardInfos" :key="index">
<vInfoCard :info="info" class="swiper-item"></vInfoCard> <!--笔者自定义的组件,下面贴出了简单的组件定义代码-->
</swiperSlide>
</swiper>
</div>
</template>
<script>
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
import { imgUrl } from '../../config/env'
import vInfoCard from '../vInfoCard/vInfoCard'
export default {
name: 'carouselCard',
components: { swiper, swiperSlide, vInfoCard },
data () {
return {
options: {
slidesPerView: 'auto',
loop: false,
centeredSlides: true,
watchSlidesProgress: true,
// spaceBetween: 0,
effect: 'coverflow',
coverflowEffect: {
rotate: 0,
stretch: 480,
depth: 390,
modifier: 1,
slideShadows: false
},
on: {
setTranslate: function () {
let slides = this.slides
for (let i = 0; i < slides.length; i++) {
let slide = slides.eq(i)
let progress = slides[i].progress
slide[0].style.opacity = (1 - Math.abs(progress) / 6)
slide[0].style.transform = 'scale(' + (1 - Math.abs(progress) / 8) + ')'
}
},
setTransition: function (transition) {
let slides = this.slides
for (let i = 0; i < slides.length; i++) {
let slide = slides.eq(i)
slide[0].style.transform = transition
}
}
}
},
cardInfos: [
{
name: 'COFFE',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE1',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE2',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE3',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE4',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE5',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE6',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE7',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE8',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE9',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE10',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE11',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
},
{
name: 'COFFE12',
boothId: 'B-304',
logoUrl: 'static/img/icon_pic.png'
}
]
}
},
mounted () {
}
}
</script>
<style lang="scss">
.carousel-card-page {
width: 100%;
height: 100%;
overflow: hidden;
.swiper-container {
width: 100%;
height: 100%;
.swiper-slide {
width: 706px;
height: 100%;
.swiper-item {
width: 706px;
height: 100%;
background: #FFFFFF;
}
}
}
}
</style>
vInfoCard组件:
<template>
<div class="shop-info-card always">
<div class="content">
<div class="box">
<img class="img" :src="info.logoUrl"/>
<div class="right">
<div class="title">{{info.name}}</div>
<div class="label">
<span v-if="info.boothId || info.position"><img src="../../assets/img/mainHot/icon_maps.png"/>{{info.boothId}}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.shop-info-card {
background-color: rgba(255, 255, 255, 0.9);
height: 100%;
border-radius: 8px;
transition: transform .5s;
.content {
width: 100%;
height: 100%;
display: flex;
.box {
flex: 1;
margin: 24px;
overflow: hidden;
position: relative;
.img {
float: left;
width: 182px;
height: 182px;
}
.right {
left: 202px;
height: 100%;
position: absolute;
display: flex;
flex-direction: column;
.title {
font-size: 24px;
font-weight: bold;
line-height: 34px;
color: #4A4A4A;
}
.label {
margin: 5px 0 0 0;
max-height: 50px;
span {
font-size: 18px;
margin: 0 25px 0 0;
white-space: nowrap;
overflow: hidden;
color: #9B9B9B;
img {
width: 18px;
height: 18px;
margin: 0 6px -3px 0;
}
}
}
}
}
}
}
</style>