style(artplayer): remove shadows and enhance custom controls

- Inject custom global styles to remove shadows and filters from all ArtPlayer elements
- Adjust ArtPlayer controls to have transparent backgrounds and no drop shadows
- Style play button and state controls with subtle hover effects and centered background
- Update bookmark and rating controls layout and appearance with conditional rendering
- Modify position and z-index of custom controls for better UI alignment
- Add format info display that adapts visibility when loading
- Fix error indicator position to avoid overlapping with custom controls
- Clean up injected styles on component unmount to prevent residue
This commit is contained in:
tigeren 2025-09-20 17:21:21 +00:00
parent d94fed7e01
commit 86f4d47be1
2 changed files with 94 additions and 12 deletions

View File

@ -5,6 +5,7 @@ import Artplayer from 'artplayer';
import Hls from 'hls.js';
import { detectVideoFormat, VideoFormat, VideoFile } from '@/lib/video-format-detector';
import { createHLSErrorHandler, HLSErrorHandler } from '@/lib/hls-error-handler';
import { artPlayerStyles } from '@/lib/artplayer-config';
import { Bookmark, Star } from 'lucide-react';
interface ArtPlayerWrapperProps {
@ -69,6 +70,15 @@ export default function ArtPlayerWrapper({
useEffect(() => {
if (!useArtPlayer || !isOpen || !containerRef.current) return;
// Inject custom styles to remove shadows
const styleId = 'artplayer-custom-styles';
if (!document.getElementById(styleId)) {
const style = document.createElement('style');
style.id = styleId;
style.textContent = artPlayerStyles;
document.head.appendChild(style);
}
setIsLoading(true);
setError(null);
@ -139,24 +149,24 @@ export default function ArtPlayerWrapper({
],
// Custom layer for bookmark and rating controls
layers: [
layers: showBookmarks || showRatings ? [
{
html: `<div class="artplayer-custom-controls absolute top-4 right-4 flex items-center gap-2 z-10">
<div class="artplayer-bookmark-control flex items-center gap-1 px-2 py-1 rounded hover:bg-white/20 transition-colors cursor-pointer text-white">
html: `<div class="artplayer-custom-controls absolute top-4 right-16 flex items-center gap-2 z-15">
${showBookmarks ? `<div class="artplayer-bookmark-control flex items-center gap-1 px-2 py-1 rounded hover:bg-black/50 transition-colors cursor-pointer text-white bg-black/30">
<svg class="h-4 w-4" fill="${localIsBookmarked ? 'currentColor' : 'none'}" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"></path>
</svg>
<span class="text-xs">${localBookmarkCount}</span>
</div>
<div class="artplayer-rating-control flex items-center gap-1 px-2 py-1 rounded hover:bg-white/20 transition-colors cursor-pointer text-white">
</div>` : ''}
${showRatings ? `<div class="artplayer-rating-control flex items-center gap-1 px-2 py-1 rounded hover:bg-black/50 transition-colors cursor-pointer text-white bg-black/30">
<span class="text-xs"> ${localAvgRating.toFixed(1)}</span>
</div>
</div>` : ''}
</div>`,
style: {
position: 'absolute',
top: '16px',
right: '16px',
zIndex: '10'
right: '64px', // Positioned to the left of close button
zIndex: '15'
} as any,
click: function(this: any, component: any, event: Event) {
const target = event.target as HTMLElement;
@ -167,7 +177,7 @@ export default function ArtPlayerWrapper({
}
}
}
],
] : [],
// Custom initialization for HLS
customType: {
@ -478,6 +488,11 @@ export default function ArtPlayerWrapper({
hlsErrorHandlerRef.current.detach();
hlsErrorHandlerRef.current = null;
}
// Clean up custom styles
const styleElement = document.getElementById('artplayer-custom-styles');
if (styleElement) {
styleElement.remove();
}
};
}, []);
@ -506,7 +521,7 @@ export default function ArtPlayerWrapper({
{/* Error indicator */}
{error && (
<div className="absolute top-4 left-4 right-4 z-20 bg-red-500/20 border border-red-500/50 text-red-400 rounded-lg px-4 py-3 flex items-center gap-3">
<div className="absolute top-4 left-4 right-20 z-20 bg-red-500/20 border border-red-500/50 text-red-400 rounded-lg px-4 py-3 flex items-center gap-3">
<div className="w-3 h-3 bg-red-500 rounded-full flex-shrink-0"></div>
<div className="flex-1">
<div className="text-sm font-medium">ArtPlayer Error</div>
@ -524,8 +539,8 @@ export default function ArtPlayerWrapper({
</div>
)}
{/* Format info */}
{format && (
{/* Format info - positioned below loading indicator when both are visible */}
{format && !isLoading && (
<div className="absolute top-4 left-4 z-20 bg-green-500/20 text-green-400 rounded-full px-3 py-1.5 flex items-center gap-2">
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
<span className="text-xs">
@ -534,6 +549,17 @@ export default function ArtPlayerWrapper({
</span>
</div>
)}
{/* Format info when loading - positioned below loading indicator */}
{format && isLoading && (
<div className="absolute top-16 left-4 z-20 bg-green-500/20 text-green-400 rounded-full px-3 py-1.5 flex items-center gap-2">
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
<span className="text-xs">
{format.supportLevel === 'native' ? 'Native' :
format.supportLevel === 'hls' ? 'HLS' : 'Fallback'}
</span>
</div>
)}
{/* Video container */}
<div

View File

@ -123,6 +123,62 @@ export const artPlayerStyles = `
position: relative;
}
/* Remove shadows from ALL ArtPlayer elements */
.artplayer-container * {
box-shadow: none !important;
filter: none !important;
text-shadow: none !important;
}
/* Remove shadows from ArtPlayer controls */
.artplayer-controls {
box-shadow: none !important;
background: linear-gradient(to top, rgba(0,0,0,0.7), transparent) !important;
backdrop-filter: none !important;
}
/* Play button and state controls */
.artplayer-control-play,
.artplayer-state,
.artplayer-control {
box-shadow: none !important;
filter: none !important;
background: transparent !important;
backdrop-filter: none !important;
}
.artplayer-control-play:hover,
.artplayer-state:hover,
.artplayer-control:hover {
box-shadow: none !important;
filter: none !important;
background-color: rgba(255, 255, 255, 0.1) !important;
backdrop-filter: none !important;
}
/* Remove any drop shadows or filters from buttons */
.artplayer-control-play svg,
.artplayer-state svg,
.artplayer-control svg {
filter: none !important;
drop-shadow: none !important;
}
/* Center play button styling */
.artplayer-state {
background: rgba(0, 0, 0, 0.3) !important;
border-radius: 50% !important;
backdrop-filter: none !important;
}
/* Progress bar and other elements */
.artplayer-progress,
.artplayer-volume,
.artplayer-time {
box-shadow: none !important;
filter: none !important;
}
.artplayer-bookmark-control {
display: flex;
align-items: center;