Reputation: 11
I have cooked up some code to display video overlay hotspots. However, when I make the video fullscreen, the hotspots are no longer visible or clickable. I tried to inspect element in fullscreen mode and the hotspots would highlight(not visible or clickable) when I dragged my pointer over their <div> but they would be in the wrong position relative to the video. None of this is a problem in windowed mode.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Video with Responsive Hotspots</title>
<style>
/* Responsive container for the video and hotspots */
#videoContainer {
position: relative;
max-width: 100%;
height: auto;
}
/* Video element should maintain aspect ratio */
#myVideo {
width: 100%;
height: auto;
display: block;
}
/* Hotspot styling */
.hotspot {
position: absolute;
background-color: rgba(255, 0, 0, 0.5); /* Semi-transparent red */
color: white;
cursor: pointer;
display: none; /* Hidden by default */
transition: all 0.2s ease;
}
</style>
</head>
<body>
<div id="videoContainer">
<video id="myVideo" controls>
<source src="video1.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
<div id="hotspot1" class="hotspot" onclick="hotspotClick('Hotspot 1')">1</div>
<div id="hotspot2" class="hotspot" onclick="hotspotClick('Hotspot 2')">2</div>
<div id="hotspot3" class="hotspot" onclick="hotspotClick('Hotspot 3')">3</div>
<div id="hotspot4" class="hotspot" onclick="hotspotClick('Hotspot 4')">4</div>
</div>
<script>
const video = document.getElementById('myVideo');
const hotspot1 = document.getElementById('hotspot1');
const hotspot2 = document.getElementById('hotspot2');
const hotspot3 = document.getElementById('hotspot3');
const hotspot4 = document.getElementById('hotspot4');
// Define the relative positions (as percentages) and rectangular padding for the hotspots
const hotspotData = {
hotspot1: {
showTime: 3, // Show at 3 seconds
hideTime: 6, // Hide at 6 seconds
positions: { leftPercent: 18, topPercent: 30, widthPercent: 8, heightPercent: 4 }
},
hotspot2: {
showTime: 3,
hideTime: 6,
positions: { leftPercent: 35, topPercent: 30, widthPercent: 8, heightPercent: 4 }
},
hotspot3: {
showTime: 3,
hideTime: 6,
positions: { leftPercent: 52, topPercent: 30, widthPercent: 8, heightPercent: 4 }
},
hotspot4: {
showTime: 3,
hideTime: 6,
positions: { leftPercent: 68, topPercent: 30, widthPercent: 8, heightPercent: 4 }
}
};
// Adjust hotspot position and size based on video and container size, with rectangular padding
function adjustHotspotPosition(hotspot, video, positionData) {
const videoRect = video.getBoundingClientRect();
const left = (positionData.leftPercent / 100) * videoRect.width;
const top = (positionData.topPercent / 100) * videoRect.height;
const width = (positionData.widthPercent / 100) * videoRect.width;
const height = (positionData.heightPercent / 100) * videoRect.height;
hotspot.style.left = left + 'px';
hotspot.style.top = top + 'px';
hotspot.style.width = width + 'px';
hotspot.style.height = height + 'px';
hotspot.style.padding = (height * 0.2) + 'px ' + (width * 0.2) + 'px'; // Rectangular padding
}
// Toggle visibility of the hotspot based on video time and update its position
function toggleHotspot(hotspot, data, currentTime) {
if (currentTime >= data.showTime && currentTime <= data.hideTime) {
hotspot.style.display = 'block';
adjustHotspotPosition(hotspot, video, data.positions);
} else {
hotspot.style.display = 'none';
}
}
// Event listener to update hotspots on video time update
video.addEventListener('timeupdate', function () {
const currentTime = video.currentTime;
toggleHotspot(hotspot1, hotspotData.hotspot1, currentTime);
toggleHotspot(hotspot2, hotspotData.hotspot2, currentTime);
toggleHotspot(hotspot3, hotspotData.hotspot3, currentTime);
toggleHotspot(hotspot4, hotspotData.hotspot4, currentTime);
});
// Event listener to adjust hotspot positions when the window resizes or video enters fullscreen
function adjustAllHotspots() {
adjustHotspotPosition(hotspot1, video, hotspotData.hotspot1.positions);
adjustHotspotPosition(hotspot2, video, hotspotData.hotspot2.positions);
adjustHotspotPosition(hotspot3, video, hotspotData.hotspot3.positions);
adjustHotspotPosition(hotspot4, video, hotspotData.hotspot4.positions);
}
// Listen for window resize to reposition hotspots
window.addEventListener('resize', adjustAllHotspots);
// Listen for fullscreen change to reposition hotspots for all browsers (Chrome/Brave included)
function addFullscreenListeners() {
document.addEventListener('fullscreenchange', adjustAllHotspots); // Standard
document.addEventListener('webkitfullscreenchange', adjustAllHotspots); // Safari/Chrome
document.addEventListener('mozfullscreenchange', adjustAllHotspots); // Firefox
document.addEventListener('MSFullscreenChange', adjustAllHotspots); // IE/Edge
}
addFullscreenListeners();
// Optional: Action on hotspot click
function hotspotClick(hotspotName) {
alert(hotspotName + ' clicked!');
}
</script>
</body>
</html>
I just need hotspots videos embedded on html5 browsers that maintain their shape, size and position according to the timestamps I want them to appear at. My code works in windowed mode but not in fullscreen mode on any browser
Upvotes: 1
Views: 59
Reputation: 1144
When you click on the fullscreen button on a <video>
tag, the document itself will remain in windowed state. Only the video content will overlay everything else in fullscreen mode. So, this causes your hotspots to not be displayed (because they're overlayed by the video).
To achieve what you want, you could intercept the fullscreen button which shoud do the following (just a suggestion):
z-index
than overlayed elements.<video>
.Then, when the user lefts the fullscreen mode:
Upvotes: 1