Files
2023-11-14 17:21:03 +08:00

235 lines
5.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
@name: LiveCards
@author: kahu4
@date: 2023-11-01 17:04
@descriptionLiveCards
@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>