235 lines
5.4 KiB
Vue
235 lines
5.4 KiB
Vue
<!--
|
||
@name: LiveCards
|
||
@author: kahu4
|
||
@date: 2023-11-01 17:04
|
||
@description:LiveCards
|
||
@update: 2023-11-01 17:04
|
||
-->
|
||
<script setup>
|
||
import { computed, onMounted, ref, unref } from "vue";
|
||
import { useSystem } from "@/hooks/useSystem";
|
||
|
||
const liveCardList = [
|
||
{
|
||
id: 1,
|
||
isLive: true,
|
||
title: '买一送一',
|
||
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
|
||
peopleNum: 168
|
||
},
|
||
{
|
||
id: 2,
|
||
isLive: false,
|
||
title: '买一送二',
|
||
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
|
||
peopleNum: 16858
|
||
},
|
||
{
|
||
id: 3,
|
||
isLive: true,
|
||
title: '买一送三',
|
||
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
|
||
peopleNum: 22343
|
||
},
|
||
{
|
||
id: 4,
|
||
isLive: true,
|
||
title: '买一送三',
|
||
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
|
||
peopleNum: 22343
|
||
},
|
||
{
|
||
id: 4,
|
||
isLive: true,
|
||
title: '买一送三',
|
||
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
|
||
peopleNum: 22343
|
||
},
|
||
{
|
||
id: 4,
|
||
isLive: true,
|
||
title: '买一送三',
|
||
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
|
||
peopleNum: 22343
|
||
}
|
||
]
|
||
|
||
const {getSystemInfo} = useSystem();
|
||
|
||
// ============================== 设置card选中相关 ================================
|
||
const current = ref(1) // 当前选中的索引
|
||
const systemInfo = ref({windowWidth: 0}) // 系统信息
|
||
const scrollLeft = ref(0) // 当前滑动到的位置
|
||
const scrollWidth = ref(0) // 滑轨总大小
|
||
// 计算单张宽度
|
||
const cardWidth = computed(() => {
|
||
if (unref(systemInfo).windowWidth <= 0) return 0
|
||
return Math.floor((unref(systemInfo).windowWidth) / 3) - 25
|
||
})
|
||
|
||
/**
|
||
* 滑动
|
||
* @param e
|
||
*/
|
||
function handleScroll(e) {
|
||
scrollLeft.value = e.detail.scrollLeft
|
||
scrollWidth.value = e.detail.scrollWidth
|
||
setCurrent()
|
||
}
|
||
|
||
/**
|
||
* 设置选中card
|
||
* @returns {number}
|
||
*/
|
||
function setCurrent() {
|
||
// 小于单张宽度直接设置1选中第2张
|
||
if (scrollLeft.value <= cardWidth.value) return current.value = 1
|
||
// 否则 current = (当前位置 / 单张宽度)= 当前屏幕左侧顶到图片的索引
|
||
// +1选中后一张
|
||
current.value = Math.floor(scrollLeft.value / cardWidth.value) + 1
|
||
}
|
||
|
||
function clickCard() {
|
||
|
||
}
|
||
|
||
onMounted(async () => {
|
||
systemInfo.value = await getSystemInfo()
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<view class="live-cards">
|
||
<scroll-view
|
||
class="live-cards__inner"
|
||
scroll-x
|
||
@scroll="handleScroll"
|
||
>
|
||
<view class="track">
|
||
<view
|
||
:class="{'card-item':true,'current':index===current}"
|
||
v-for="(item,index) in liveCardList"
|
||
:key="item.id"
|
||
@click="clickCard"
|
||
>
|
||
<image
|
||
class="live-img"
|
||
:src="item.background"
|
||
mode="aspectFill"
|
||
/>
|
||
<view class="mask">
|
||
<view :class="{'status-box':true}">
|
||
<view :class="{status:true,close:item.isLive===false}">
|
||
{{ item.isLive ? '直播中' : '暂未开始' }}
|
||
</view>
|
||
<view class="number">
|
||
{{ item.isLive ? item.peopleNum : 0 }}人
|
||
</view>
|
||
</view>
|
||
<view class="title">
|
||
{{ item.title }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
</view>
|
||
</template>
|
||
|
||
<style
|
||
scoped
|
||
lang="scss"
|
||
>
|
||
.live-cards {
|
||
width: 100%;
|
||
padding: 70rpx 0;
|
||
aspect-ratio: 750/480;
|
||
|
||
&__inner {
|
||
width: 100%;
|
||
height: 100%;
|
||
|
||
.track {
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
|
||
.card-item {
|
||
flex-shrink: 0;
|
||
width: calc(100% / 3);
|
||
height: 80%;
|
||
background: #fff;
|
||
border-radius: 15rpx;
|
||
overflow: hidden;
|
||
position: relative;
|
||
transition: all .3s;
|
||
scale: 1;
|
||
z-index: 1;
|
||
|
||
.live-img {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.mask {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 10;
|
||
width: 100%;
|
||
height: 100%;
|
||
padding: 35rpx 20rpx;
|
||
box-sizing: border-box;
|
||
color: #fff;
|
||
font-size: 18rpx;
|
||
|
||
|
||
.status-box {
|
||
position: absolute;
|
||
display: flex;
|
||
align-items: center;
|
||
top: 18rpx;
|
||
left: 20rpx;
|
||
height: 33rpx;
|
||
line-height: 33rpx;
|
||
border-radius: 33rpx;
|
||
background: rgba(0, 0, 0, 0.6);
|
||
|
||
.status {
|
||
background: #ee6d46;
|
||
border-radius: 33rpx;
|
||
padding: 0 10rpx;
|
||
}
|
||
|
||
.close {
|
||
background: grey;
|
||
}
|
||
|
||
.number {
|
||
padding: 0 1rpx;
|
||
}
|
||
}
|
||
|
||
.title {
|
||
font-size: 28rpx;
|
||
position: absolute;
|
||
width: 100%;
|
||
color: #fff;
|
||
left: 20rpx;
|
||
bottom: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.current {
|
||
scale: 1.2 1.2;
|
||
z-index: 11;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
</style>
|