<template>
<view class="swiper-box">
<image class="fix-height-with-me" mode="widthFix" :src="props.items[0]" />
<swiper
class="swiper"
:previousMargin="state.margin"
:nextMargin="state.margin"
:current="state.current"
@change="onChange"
circular
>
<swiper-item v-for="(item, i) in props.items" :key="i" class="item">
<view
class="img"
:class="{
active: i === state.current,
left: i < state.current,
right: i > state.current
}"
:style="{
backgroundImage: `url(${item})`
}"
>
<view class="mask"></view>
</view>
</swiper-item>
</swiper>
</view>
</template>
<script setup lang="ts">
import Taro from '@tarojs/taro'
import { reactive, onMounted } from 'vue'
const props = defineProps<{
// 图片地址列表
items: string[]
// 当前激活的
current?: number
}>()
const state = reactive({
current: props?.current ?? 1,
margin: '30px'
})
const onChange = ({ detail }) => {
state.current = detail.current
}
const getSwiperItemHeight = () => {
const q = Taro.createSelectorQuery()
q.select('.fix-height-with-me').boundingClientRect()
q.exec((res) => {
// 计算出卡片距离两边宽度的一半作为缩进
state.margin = `${(375 - res[0].width) / 2 + 10}px`
})
}
onMounted(() => {
getSwiperItemHeight()
})
</script>
<style lang="scss">
.swiper-box {
position: relative;
height: auto;
width: 100%;
.fix-height-with-me {
position: relative;
top: 0;
left: 0;
width: 200px;
z-index: 10;
opacity: 0;
}
.swiper {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 20;
.item {
display: flex;
justify-content: center;
}
.img {
position: relative;
width: 200px;
height: 300px;
border-radius: 16px;
background-size: cover;
overflow: hidden;
.mask {
position: absolute;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.5;
transition: opacity 0.3s;
}
&.active {
.mask {
opacity: 0;
}
}
}
}
}
</style>
效果:
Comments | NOTHING