Skip to content

Commit 41fb650

Browse files
author
Bharat Sharma
committed
download video on demand
1 parent e9f42ba commit 41fb650

2 files changed

Lines changed: 203 additions & 4 deletions

File tree

src/pages/crazy-crosswords.astro

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,17 @@ const features = [
139139

140140
<div class="game-video">
141141
<div class="video-container">
142-
<video controls poster="/images/crazy-crosswords/gameplay-thumbnail.png" class="gameplay-video">
143-
<source src="/images/crazy-crosswords/gameplay-video.mp4" type="video/mp4">
142+
<video controls poster="/images/crazy-crosswords/gameplay-thumbnail.png" class="gameplay-video" preload="none">
143+
<source data-src="/images/crazy-crosswords/gameplay-video.mp4" type="video/mp4">
144144
Your browser does not support the video tag.
145145
</video>
146+
<div class="play-overlay">
147+
<button class="play-button" aria-label="Play video">
148+
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="#ffffff">
149+
<path d="M8 5v14l11-7z"/>
150+
</svg>
151+
</button>
152+
</div>
146153
</div>
147154
</div>
148155
</div>
@@ -305,6 +312,8 @@ const features = [
305312
overflow: hidden;
306313
box-shadow: 0 12px 32px rgba(0,0,0,0.2);
307314
margin: 0 auto;
315+
position: relative;
316+
cursor: pointer;
308317
}
309318

310319
.gameplay-video {
@@ -313,6 +322,43 @@ const features = [
313322
display: block;
314323
}
315324

325+
.play-overlay {
326+
position: absolute;
327+
top: 0;
328+
left: 0;
329+
width: 100%;
330+
height: 100%;
331+
display: flex;
332+
align-items: center;
333+
justify-content: center;
334+
background-color: rgba(0, 0, 0, 0.2);
335+
transition: background-color 0.3s ease;
336+
}
337+
338+
.play-overlay:hover {
339+
background-color: rgba(0, 0, 0, 0.4);
340+
}
341+
342+
.play-button {
343+
background: none;
344+
border: none;
345+
cursor: pointer;
346+
width: 60px;
347+
height: 60px;
348+
padding: 0;
349+
display: flex;
350+
align-items: center;
351+
justify-content: center;
352+
background-color: rgba(0, 0, 0, 0.6);
353+
border-radius: 50%;
354+
transition: transform 0.2s ease, background-color 0.2s ease;
355+
}
356+
357+
.play-button:hover {
358+
transform: scale(1.1);
359+
background-color: rgba(0, 0, 0, 0.8);
360+
}
361+
316362
@media (max-width: 768px) {
317363
.hero-content {
318364
grid-template-columns: 1fr;
@@ -641,6 +687,7 @@ const features = [
641687

642688
<script>
643689
document.addEventListener('DOMContentLoaded', function() {
690+
// Reviews carousel functionality
644691
const track = document.getElementById('reviewsTrack');
645692
const reviews = document.querySelectorAll('.review-card:not(.duplicate)');
646693
const totalReviews = reviews.length;
@@ -689,5 +736,56 @@ const features = [
689736

690737
// Initial setup
691738
updateCarousel();
739+
740+
// Video lazy loading functionality
741+
const videoContainer = document.querySelector('.video-container');
742+
const video = document.querySelector('.gameplay-video');
743+
const playOverlay = document.querySelector('.play-overlay');
744+
const videoSource = video.querySelector('source');
745+
746+
if (videoContainer && video && playOverlay && videoSource) {
747+
// Function to load and play the video
748+
function loadAndPlayVideo() {
749+
// Set the actual source from data-src
750+
const actualSrc = videoSource.getAttribute('data-src');
751+
videoSource.setAttribute('src', actualSrc);
752+
753+
// Load the video
754+
video.load();
755+
756+
// Play the video
757+
video.play()
758+
.then(() => {
759+
// Hide the overlay when video starts playing
760+
playOverlay.style.display = 'none';
761+
})
762+
.catch(error => {
763+
console.error('Error playing video:', error);
764+
// Keep overlay visible if autoplay fails (common on mobile)
765+
});
766+
}
767+
768+
// Add click event to the container
769+
videoContainer.addEventListener('click', (e) => {
770+
loadAndPlayVideo();
771+
});
772+
773+
// Add intersection observer for auto-loading when scrolled into view
774+
const observer = new IntersectionObserver((entries) => {
775+
entries.forEach(entry => {
776+
// If video is in viewport and src hasn't been set yet
777+
if (entry.isIntersecting && !videoSource.hasAttribute('src')) {
778+
// Just set the source but don't autoplay
779+
const actualSrc = videoSource.getAttribute('data-src');
780+
videoSource.setAttribute('src', actualSrc);
781+
video.load();
782+
// Don't remove the overlay or autoplay
783+
}
784+
});
785+
}, { threshold: 0.5 });
786+
787+
// Start observing the video element
788+
observer.observe(videoContainer);
789+
}
692790
});
693791
</script>

src/pages/how-to-play.astro

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,17 @@ const footerLinks = [
2828
<div class="video-section">
2929
<h3>Watch Gameplay</h3>
3030
<div class="video-container">
31-
<video controls poster="/images/crazy-crosswords/gameplay-thumbnail.png" class="gameplay-video">
32-
<source src="/images/crazy-crosswords/gameplay-video.mp4" type="video/mp4">
31+
<video controls poster="/images/crazy-crosswords/gameplay-thumbnail.png" class="gameplay-video" preload="none">
32+
<source data-src="/images/crazy-crosswords/gameplay-video.mp4" type="video/mp4">
3333
Your browser does not support the video tag.
3434
</video>
35+
<div class="play-overlay">
36+
<button class="play-button" aria-label="Play video">
37+
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="#ffffff">
38+
<path d="M8 5v14l11-7z"/>
39+
</svg>
40+
</button>
41+
</div>
3542
</div>
3643
</div>
3744

@@ -106,6 +113,61 @@ const footerLinks = [
106113
<Footer links={footerLinks} />
107114
</BaseLayout>
108115

116+
<script>
117+
// Wait for the DOM to be fully loaded
118+
document.addEventListener('DOMContentLoaded', () => {
119+
const videoContainer = document.querySelector('.video-container');
120+
const video = document.querySelector('.gameplay-video');
121+
const playOverlay = document.querySelector('.play-overlay');
122+
const videoSource = video.querySelector('source');
123+
124+
if (videoContainer && video && playOverlay && videoSource) {
125+
// Function to load and play the video
126+
function loadAndPlayVideo() {
127+
// Set the actual source from data-src
128+
const actualSrc = videoSource.getAttribute('data-src');
129+
videoSource.setAttribute('src', actualSrc);
130+
131+
// Load the video
132+
video.load();
133+
134+
// Play the video
135+
video.play()
136+
.then(() => {
137+
// Hide the overlay when video starts playing
138+
playOverlay.style.display = 'none';
139+
})
140+
.catch(error => {
141+
console.error('Error playing video:', error);
142+
// Keep overlay visible if autoplay fails (common on mobile)
143+
});
144+
}
145+
146+
// Add click event to the container
147+
videoContainer.addEventListener('click', (e) => {
148+
loadAndPlayVideo();
149+
});
150+
151+
// Add intersection observer for auto-loading when scrolled into view
152+
const observer = new IntersectionObserver((entries) => {
153+
entries.forEach(entry => {
154+
// If video is in viewport and src hasn't been set yet
155+
if (entry.isIntersecting && !videoSource.hasAttribute('src')) {
156+
// Just set the source but don't autoplay
157+
const actualSrc = videoSource.getAttribute('data-src');
158+
videoSource.setAttribute('src', actualSrc);
159+
video.load();
160+
// Don't remove the overlay or autoplay
161+
}
162+
});
163+
}, { threshold: 0.5 });
164+
165+
// Start observing the video element
166+
observer.observe(videoContainer);
167+
}
168+
});
169+
</script>
170+
109171
<style>
110172
.guide-container {
111173
max-width: 900px;
@@ -217,6 +279,8 @@ const footerLinks = [
217279
overflow: hidden;
218280
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
219281
aspect-ratio: 9/16;
282+
position: relative;
283+
cursor: pointer;
220284
}
221285

222286
.gameplay-video {
@@ -225,6 +289,43 @@ const footerLinks = [
225289
display: block;
226290
}
227291

292+
.play-overlay {
293+
position: absolute;
294+
top: 0;
295+
left: 0;
296+
width: 100%;
297+
height: 100%;
298+
display: flex;
299+
align-items: center;
300+
justify-content: center;
301+
background-color: rgba(0, 0, 0, 0.2);
302+
transition: background-color 0.3s ease;
303+
}
304+
305+
.play-overlay:hover {
306+
background-color: rgba(0, 0, 0, 0.4);
307+
}
308+
309+
.play-button {
310+
background: none;
311+
border: none;
312+
cursor: pointer;
313+
width: 60px;
314+
height: 60px;
315+
padding: 0;
316+
display: flex;
317+
align-items: center;
318+
justify-content: center;
319+
background-color: rgba(0, 0, 0, 0.6);
320+
border-radius: 50%;
321+
transition: transform 0.2s ease, background-color 0.2s ease;
322+
}
323+
324+
.play-button:hover {
325+
transform: scale(1.1);
326+
background-color: rgba(0, 0, 0, 0.8);
327+
}
328+
228329
.download-section {
229330
text-align: center;
230331
margin: 3rem 0 2rem 0;

0 commit comments

Comments
 (0)