Fix overlay to use Plyr's built-in poster element
Instead of custom overlay, use Plyr's .plyr__poster element which: - Naturally covers the iframe when paused/initial load - Allows Plyr controls to receive clicks (z-index hierarchy) - Hides (opacity: 0) when playing, shows (opacity: 1) when paused - Blocks YouTube UI interactions when visible This matches the reference implementation behavior. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,7 @@ export const VideoPlayerWithChapters = forwardRef<VideoPlayerRef, VideoPlayerWit
|
|||||||
const videoRef = useRef<HTMLVideoElement>(null);
|
const videoRef = useRef<HTMLVideoElement>(null);
|
||||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||||
const playerRef = useRef<Plyr | null>(null);
|
const playerRef = useRef<Plyr | null>(null);
|
||||||
|
const posterRef = useRef<HTMLDivElement | null>(null);
|
||||||
const [currentChapterIndex, setCurrentChapterIndex] = useState<number>(-1);
|
const [currentChapterIndex, setCurrentChapterIndex] = useState<number>(-1);
|
||||||
const [isPlaying, setIsPlaying] = useState<boolean>(false);
|
const [isPlaying, setIsPlaying] = useState<boolean>(false);
|
||||||
|
|
||||||
@@ -93,12 +94,32 @@ export const VideoPlayerWithChapters = forwardRef<VideoPlayerRef, VideoPlayerWit
|
|||||||
|
|
||||||
playerRef.current = player;
|
playerRef.current = player;
|
||||||
|
|
||||||
// Track play/pause state to show/hide overlay
|
// Get poster element
|
||||||
player.on('play', () => setIsPlaying(true));
|
posterRef.current = player.elements.wrapper.querySelector('.plyr__poster') as HTMLDivElement;
|
||||||
player.on('pause', () => setIsPlaying(false));
|
|
||||||
player.on('ended', () => setIsPlaying(false));
|
|
||||||
|
|
||||||
// Apply custom accent color
|
// Track play/pause state to show/hide poster overlay
|
||||||
|
player.on('play', () => {
|
||||||
|
setIsPlaying(true);
|
||||||
|
if (posterRef.current) {
|
||||||
|
posterRef.current.style.opacity = '0';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
player.on('pause', () => {
|
||||||
|
setIsPlaying(false);
|
||||||
|
if (posterRef.current) {
|
||||||
|
posterRef.current.style.opacity = '1';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
player.on('ended', () => {
|
||||||
|
setIsPlaying(false);
|
||||||
|
if (posterRef.current) {
|
||||||
|
posterRef.current.style.opacity = '1';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Apply custom accent color and poster styles
|
||||||
if (accentColor) {
|
if (accentColor) {
|
||||||
const style = document.createElement('style');
|
const style = document.createElement('style');
|
||||||
style.textContent = `
|
style.textContent = `
|
||||||
@@ -114,6 +135,11 @@ export const VideoPlayerWithChapters = forwardRef<VideoPlayerRef, VideoPlayerWit
|
|||||||
.plyr__progress__buffer {
|
.plyr__progress__buffer {
|
||||||
color: ${accentColor}40 !important;
|
color: ${accentColor}40 !important;
|
||||||
}
|
}
|
||||||
|
/* Poster overlay to block YouTube UI when paused */
|
||||||
|
.plyr__poster {
|
||||||
|
background-color: transparent !important;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
document.head.appendChild(style);
|
document.head.appendChild(style);
|
||||||
|
|
||||||
@@ -200,22 +226,12 @@ export const VideoPlayerWithChapters = forwardRef<VideoPlayerRef, VideoPlayerWit
|
|||||||
return (
|
return (
|
||||||
<div ref={wrapperRef} className={`plyr__video-embed relative ${className}`}>
|
<div ref={wrapperRef} className={`plyr__video-embed relative ${className}`}>
|
||||||
{youtubeId && (
|
{youtubeId && (
|
||||||
<>
|
<iframe
|
||||||
{/* CSS Overlay to block YouTube UI interactions - shows when paused */}
|
src={`https://www.youtube-nocookie.com/embed/${youtubeId}?origin=${window.location.origin}&iv_load_policy=3&modestbranding=1&playsinline=1&rel=0&showinfo=0&controls=0&disablekb=1&fs=0`}
|
||||||
<div
|
allowFullScreen
|
||||||
className="absolute inset-0 z-10"
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||||
style={{
|
className="pointer-events-none"
|
||||||
background: 'transparent',
|
/>
|
||||||
pointerEvents: isPlaying ? 'none' : 'auto'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<iframe
|
|
||||||
src={`https://www.youtube-nocookie.com/embed/${youtubeId}?origin=${window.location.origin}&iv_load_policy=3&modestbranding=1&playsinline=1&rel=0&showinfo=0&controls=0&disablekb=1&fs=0`}
|
|
||||||
allowFullScreen
|
|
||||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
||||||
style={{ pointerEvents: 'none' }}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user