feat: optimize VideoCard

This commit is contained in:
shinya
2025-07-11 12:56:43 +08:00
parent 6817ada00a
commit 2b053fb987
2 changed files with 27 additions and 32 deletions

View File

@@ -102,7 +102,7 @@ export default function ScrollableRow({
> >
<div <div
ref={containerRef} ref={containerRef}
className='flex space-x-6 overflow-x-auto scrollbar-hide py-2 sm:py-4 pb-12 sm:pb-14' className='flex space-x-6 overflow-x-auto scrollbar-hide py-1 sm:py-2 pb-12 sm:pb-14'
onScroll={checkScroll} onScroll={checkScroll}
> >
{children} {children}

View File

@@ -264,7 +264,7 @@ export default function VideoCard({
priority={false} priority={false}
/> />
{/* 悬浮层 - 添加渐变动画效果 */} {/* 悬浮层 */}
<div className='absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center cursor-pointer'> <div className='absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center cursor-pointer'>
{config.showPlayButton && ( {config.showPlayButton && (
<PlayCircleIcon <PlayCircleIcon
@@ -274,9 +274,9 @@ export default function VideoCard({
/> />
)} )}
{/* 已看 / 收藏按钮 - 添加弹出动画 */} {/* 已看 / 收藏按钮 */}
{(config.showHeart || config.showCheckCircle) && ( {(config.showHeart || config.showCheckCircle) && (
<div className='absolute bottom-3 right-3 flex items-center gap-3 transform translate-y-4 opacity-0 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300 ease-out'> <div className='absolute bottom-3 right-3 flex items-center gap-3 transform translate-y-2 opacity-0 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300 ease-out'>
{config.showCheckCircle && ( {config.showCheckCircle && (
<button <button
onClick={(e: React.MouseEvent<HTMLButtonElement>) => onClick={(e: React.MouseEvent<HTMLButtonElement>) =>
@@ -315,65 +315,60 @@ export default function VideoCard({
)} )}
</div> </div>
{/* 集数徽章 / 标签元素 - 添加微动画 */} {/* 评分徽章 */}
{config.showRating && rate && ( {config.showRating && rate && (
<div className='absolute top-2 right-2 bg-pink-500 text-white text-xs font-bold w-8 h-8 rounded-full flex items-center justify-center shadow-md transform transition-transform duration-300 group-hover:scale-110'> <div className='absolute top-2 right-2 bg-pink-500 text-white text-xs font-bold w-6 h-6 sm:w-7 sm:h-7 rounded-full flex items-center justify-center shadow-md transform transition-transform duration-300 group-hover:scale-110'>
{rate} {rate}
</div> </div>
)} )}
{['playrecord', 'favorite'].includes(from) && {/* 集数徽章 */}
actualEpisodes && {actualEpisodes && actualEpisodes > 1 && currentEpisode && (
actualEpisodes > 1 && <div className='absolute top-2 right-2 bg-green-500 text-white text-xs font-semibold rounded-md px-2 py-1 shadow-md transform transition-transform duration-300 group-hover:scale-105'>
currentEpisode && ( {currentEpisode}/{actualEpisodes}
<div className='absolute top-2 right-2 bg-green-500 text-white text-xs font-semibold rounded-md px-2 py-1 shadow-md transform transition-transform duration-300 group-hover:scale-105'> </div>
{currentEpisode}/{actualEpisodes} )}
</div>
)}
{from === 'search' && {actualEpisodes && actualEpisodes > 1 && !currentEpisode && (
actualEpisodes && <div className='absolute top-2 right-2 bg-green-500 text-white text-xs font-semibold rounded-md px-2 py-1 shadow-md transform transition-transform duration-300 group-hover:scale-105'>
actualEpisodes > 1 && {actualEpisodes}
!currentEpisode && ( </div>
<div className='absolute top-2 right-2 bg-green-500 text-white text-xs font-semibold rounded-full w-8 h-8 flex items-center justify-center shadow-md transform transition-transform duration-300 group-hover:scale-105'> )}
{actualEpisodes}
</div>
)}
{/* 豆瓣链接按钮 - 添加滑入动画 */} {/* 豆瓣链接按钮 */}
{config.showDoubanLink && actualDoubanId && ( {config.showDoubanLink && actualDoubanId && (
<a <a
href={`https://movie.douban.com/subject/${actualDoubanId}`} href={`https://movie.douban.com/subject/${actualDoubanId}`}
target='_blank' target='_blank'
rel='noopener noreferrer' rel='noopener noreferrer'
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className='absolute top-2 left-2 opacity-0 translate-x-[-10px] group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-300' className='absolute top-2 left-2 opacity-0 -translate-x-2 group-hover:translate-x-0 group-hover:opacity-100 group-hover:scale-110 transition-all duration-300'
> >
<div className='w-8 h-8 rounded-full bg-green-500 flex items-center justify-center shadow-md hover:bg-green-600 transition-colors duration-200 transform hover:scale-105'> <div className='bg-green-500 text-white text-xs font-bold p-1 rounded-full flex-center shadow-md hover:bg-green-600 hover:scale-110 transition-all duration-300'>
<Link size={16} className='text-white' /> <Link size={16} />
</div> </div>
</a> </a>
)} )}
</div> </div>
{/* 进度条 - 移除进度变化动画 */} {/* 进度条 */}
{config.showProgress && progress !== undefined && ( {config.showProgress && progress !== undefined && (
<div className='mt-1 h-1 w-full bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden'> <div className='mt-1 h-1 w-full bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden'>
<div <div
className='h-full bg-green-500 rounded-full' className='h-full bg-green-500 rounded-full transition-all duration-300'
style={{ width: `${progress}%` }} style={{ width: `${progress}%` }}
/> />
</div> </div>
)} )}
{/* 标题与来源信息 - 添加颜色过渡 */} {/* 标题与来源信息 */}
<span className='mt-2 block text-center text-sm font-semibold truncate text-gray-900 dark:text-gray-100 transition-all duration-300 group-hover:text-green-600 dark:group-hover:text-green-400'> <span className='mt-2 block text-center text-sm font-semibold truncate text-gray-900 dark:text-gray-100 transition-colors duration-300 group-hover:text-green-600 dark:group-hover:text-green-400'>
{actualTitle} {actualTitle}
</span> </span>
{config.showSourceName && source_name && ( {config.showSourceName && source_name && (
<span className='block text-center text-xs text-gray-500 dark:text-gray-400 mt-1 transform transition-all duration-300 group-hover:scale-105 group-hover:text-green-500 dark:group-hover:text-green-500'> <span className='block text-center text-xs text-gray-500 dark:text-gray-400 mt-1 transition-all duration-300 group-hover:text-green-500 dark:group-hover:text-green-500 group-hover:scale-105'>
<span className='inline-block border border-gray-500/60 dark:border-gray-400/60 px-2 py-0.5 rounded transition-all duration-300 group-hover:border-green-500/60'> <span className='inline-block border rounded px-2 py-0.5 border-gray-500/60 dark:border-gray-400/60 transition-all duration-300 group-hover:border-green-500/60'>
{source_name} {source_name}
</span> </span>
</span> </span>