新增 h5视频使用card效果

This commit is contained in:
moux1024 2025-09-24 15:24:47 +08:00
parent 0ec9fc39b8
commit 7e49b48d0f
2 changed files with 25 additions and 18 deletions

View File

@ -276,7 +276,7 @@ export function HomePage2() {
</LazyLoad>
{/* 动态锚点:来源于服务端 homeTab 配置title 作为锚点与标题 */}
{homeTabs.map((tab) => (
<div key={tab.title} data-test={JSON.stringify(tab)} data-alt={`anchor-${tab.title.toLowerCase()}`} ref={(el) => (sectionRefs.current as any)[tab.title.toLowerCase()] = el}>
<div key={tab.title} data-alt={`anchor-${tab.title.toLowerCase()}`} ref={(el) => (sectionRefs.current as any)[tab.title.toLowerCase()] = el}>
<VideoCoverflow title={tab.title} subtitle={tab.subtitle} videos={tab.videos} />
</div>
))}

View File

@ -2,11 +2,13 @@
import React from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Autoplay, EffectCoverflow } from 'swiper/modules';
import { Autoplay, EffectCoverflow, EffectCards } from 'swiper/modules';
import type { Swiper as SwiperType } from 'swiper/types';
import { useDeviceType } from '@/hooks/useDeviceType';
import 'swiper/css';
import 'swiper/css/effect-coverflow';
import 'swiper/css/effect-cards';
/** 默认视频列表(来自 home-page2.tsx 中的数组) */
const DEFAULT_VIDEOS: string[] = [
@ -40,21 +42,22 @@ const VideoCoverflow: React.FC<VideoCoverflowProps> = ({
}) => {
const swiperRef = React.useRef<SwiperType | null>(null);
const videoRefs = React.useRef<Record<number, HTMLVideoElement | null>>({});
const [isMobile, setIsMobile] = React.useState<boolean>(false);
const { isMobile } = useDeviceType();
const [activeIndex, setActiveIndex] = React.useState<number>(0);
const playActive = React.useCallback((activeIndex: number) => {
Object.entries(videoRefs.current).forEach(([key, el]) => {
if (!el) return;
const video = el as HTMLVideoElement | null;
if (!video) return;
const index = Number(key);
if (index === activeIndex) {
// 尝试播放当前居中视频
el.play().catch(() => {});
video.play().catch(() => {});
} else {
// 暂停其他视频,重置到起点以减少解码负担
el.pause();
video.pause();
try {
el.currentTime = 0;
video.currentTime = 0;
} catch {}
}
});
@ -115,28 +118,32 @@ const VideoCoverflow: React.FC<VideoCoverflowProps> = ({
</p>
<div data-alt="video-coverflow" className="w-screen sm:w-full mx-auto overflow-hidden">
<Swiper
modules={[Autoplay, EffectCoverflow]}
effect="coverflow"
modules={isMobile ? [Autoplay, EffectCards] : [Autoplay, EffectCoverflow]}
effect={isMobile ? 'cards' : 'coverflow'}
key={isMobile ? 'cards' : 'coverflow'}
data-test={isMobile}
centeredSlides
slidesPerView={isMobile ? 1 : 2}
loop
autoplay={{ delay: autoplayDelay, disableOnInteraction: false }}
speed={1000}
coverflowEffect={{
{...(!isMobile ? {
coverflowEffect: {
rotate: -56,
stretch: 10,
depth: 80,
scale: 0.6,
modifier: 1,
slideShadows: true,
}}
},
} : {})}
onAfterInit={handleAfterInit}
onSlideChange={handleSlideChange}
className="w-full py-8"
>
{videos.map((src, index) => (
<SwiperSlide key={src} className="select-none">
<div data-alt="video-card" className={`${isMobile ? (activeIndex === index ? 'w-screen' : 'w-[80vw]') : 'w-[48vw]'} mx-auto aspect-video overflow-hidden rounded-xl shadow-lg`}>
<div data-alt="video-card" className={`${isMobile ? 'w-screen' : 'w-[48vw]'} mx-auto aspect-video overflow-hidden rounded-xl shadow-lg`}>
<video
data-alt="video"
ref={(el) => { videoRefs.current[index] = el; }}