forked from 77media/video-flow
新增 h5视频使用card效果
This commit is contained in:
parent
0ec9fc39b8
commit
7e49b48d0f
@ -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>
|
||||
))}
|
||||
|
||||
@ -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={{
|
||||
rotate: -56,
|
||||
stretch: 10,
|
||||
depth: 80,
|
||||
scale: 0.6,
|
||||
modifier: 1,
|
||||
slideShadows: true,
|
||||
}}
|
||||
{...(!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; }}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user