refactor: replace YouTube lightbox with persistent background playback integration and vinyl animation state management
This commit is contained in:
@@ -434,6 +434,10 @@
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.project.item:has(.player:hover) {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.player:hover {
|
||||
transform: scale(1.08) translateY(-5px);
|
||||
z-index: 999;
|
||||
@@ -490,6 +494,7 @@
|
||||
background-image: radial-gradient(circle, #2c2727 10%, transparent 10%),
|
||||
repeating-radial-gradient(circle, #2c2727, #1e1b1b 2px, #2c2727 4px);
|
||||
z-index: 10;
|
||||
transition: box-shadow var(--transition-time) var(--transition-method);
|
||||
}
|
||||
|
||||
.player:hover .vinyl {
|
||||
@@ -498,6 +503,7 @@
|
||||
|
||||
.player:hover .vinyl__circle {
|
||||
animation-play-state: running;
|
||||
box-shadow: 0 0 25px rgba(227, 30, 36, 0.65), 0 0 50px rgba(227, 30, 36, 0.35);
|
||||
}
|
||||
|
||||
.vinyl__center {
|
||||
|
||||
@@ -88,18 +88,10 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- YouTube Lightbox Modal --}}
|
||||
{{-- Hidden Background YouTube Player --}}
|
||||
@if($videoId)
|
||||
<div id="youtube-lightbox" class="fixed inset-0 z-[9999] flex items-center justify-center bg-black/90 backdrop-blur-md opacity-0 pointer-events-none transition-all duration-300">
|
||||
<div class="absolute inset-0" id="lightbox-bg"></div>
|
||||
<div class="relative w-full max-w-4xl mx-4 aspect-video z-10 scale-95 opacity-0 transition-all duration-300" id="lightbox-content">
|
||||
<button id="lightbox-close" class="absolute -top-12 right-0 text-white hover:text-red-500 transition-colors text-2xl flex items-center gap-1 font-semibold focus:outline-none">
|
||||
<i class="uil uil-times before:content-['\eb50']"></i> {{ t('Kapat') }}
|
||||
</button>
|
||||
<div class="w-full h-full rounded-lg overflow-hidden shadow-2xl bg-black border border-white/10">
|
||||
<iframe id="lightbox-iframe" class="w-full h-full border-0" src="" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<div id="hidden-youtube-player-container" style="position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; overflow: hidden; left: -9999px;">
|
||||
<div id="hidden-youtube-player"></div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -666,62 +658,107 @@ body.lightbox-open .player {
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const cdBtn = document.getElementById('play-cd-btn');
|
||||
// Load YouTube Iframe Player API dynamically
|
||||
var tag = document.createElement('script');
|
||||
tag.src = "https://www.youtube.com/iframe_api";
|
||||
var firstScriptTag = document.getElementsByTagName('script')[0];
|
||||
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||||
|
||||
var ytPlayer;
|
||||
var isPlayerReady = false;
|
||||
|
||||
window.onYouTubeIframeAPIReady = function() {
|
||||
ytPlayer = new YT.Player('hidden-youtube-player', {
|
||||
height: '1',
|
||||
width: '1',
|
||||
videoId: "{{ $videoId }}",
|
||||
playerVars: {
|
||||
'autoplay': 0,
|
||||
'controls': 0,
|
||||
'disablekb': 1,
|
||||
'fs': 0,
|
||||
'modestbranding': 1,
|
||||
'rel': 0,
|
||||
'showinfo': 0
|
||||
},
|
||||
events: {
|
||||
'onReady': onPlayerReady,
|
||||
'onStateChange': onPlayerStateChange
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onPlayerReady(event) {
|
||||
isPlayerReady = true;
|
||||
|
||||
// Check if auto-play was active from previous page
|
||||
const autoPlayActive = localStorage.getItem('vinyl_auto_play') === 'true';
|
||||
if (autoPlayActive) {
|
||||
startPlayback();
|
||||
}
|
||||
}
|
||||
|
||||
function onPlayerStateChange(event) {
|
||||
const playerEl = document.getElementById('detail-vinyl-player');
|
||||
const lightbox = document.getElementById('youtube-lightbox');
|
||||
const lightboxBg = document.getElementById('lightbox-bg');
|
||||
const lightboxContent = document.getElementById('lightbox-content');
|
||||
const lightboxClose = document.getElementById('lightbox-close');
|
||||
const iframe = document.getElementById('lightbox-iframe');
|
||||
const videoId = "{{ $videoId }}";
|
||||
if (!playerEl) return;
|
||||
|
||||
if (cdBtn && lightbox && iframe) {
|
||||
cdBtn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Set autoplay & enable javascript API
|
||||
iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=1&enablejsapi=1`;
|
||||
|
||||
// Start vinyl spinning animation
|
||||
if (playerEl) {
|
||||
if (event.data === YT.PlayerState.PLAYING) {
|
||||
playerEl.classList.add('player--playing');
|
||||
}
|
||||
|
||||
// Show lightbox container with transition
|
||||
lightbox.classList.remove('opacity-0', 'pointer-events-none');
|
||||
document.body.classList.add('lightbox-open');
|
||||
setTimeout(() => {
|
||||
lightboxContent.classList.remove('scale-95', 'opacity-0');
|
||||
}, 50);
|
||||
});
|
||||
|
||||
function closeLightbox() {
|
||||
lightboxContent.classList.add('scale-95', 'opacity-0');
|
||||
lightbox.classList.add('opacity-0', 'pointer-events-none');
|
||||
document.body.classList.remove('lightbox-open');
|
||||
|
||||
// Stop vinyl spinning animation
|
||||
if (playerEl) {
|
||||
localStorage.setItem('vinyl_auto_play', 'true');
|
||||
} else if (event.data === YT.PlayerState.PAUSED || event.data === YT.PlayerState.ENDED) {
|
||||
playerEl.classList.remove('player--playing');
|
||||
if (event.data === YT.PlayerState.ENDED) {
|
||||
localStorage.setItem('vinyl_auto_play', 'false');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear source to halt playback after transition completes
|
||||
setTimeout(() => {
|
||||
iframe.src = "";
|
||||
}, 300);
|
||||
function startPlayback() {
|
||||
if (isPlayerReady && ytPlayer && typeof ytPlayer.playVideo === 'function') {
|
||||
ytPlayer.playVideo();
|
||||
}
|
||||
}
|
||||
|
||||
lightboxBg.addEventListener('click', closeLightbox);
|
||||
lightboxClose.addEventListener('click', closeLightbox);
|
||||
function pausePlayback() {
|
||||
if (isPlayerReady && ytPlayer && typeof ytPlayer.pauseVideo === 'function') {
|
||||
ytPlayer.pauseVideo();
|
||||
}
|
||||
}
|
||||
|
||||
// Listen for ESC key
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape' && !lightbox.classList.contains('opacity-0')) {
|
||||
closeLightbox();
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const playBtn = document.getElementById('play-cd-btn');
|
||||
const playerEl = document.getElementById('detail-vinyl-player');
|
||||
|
||||
if (playBtn) {
|
||||
playBtn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (!isPlayerReady) return;
|
||||
|
||||
if (playerEl.classList.contains('player--playing')) {
|
||||
pausePlayback();
|
||||
localStorage.setItem('vinyl_auto_play', 'false');
|
||||
} else {
|
||||
startPlayback();
|
||||
localStorage.setItem('vinyl_auto_play', 'true');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Capture next/prev clicks to persist play state
|
||||
const prevBtn = document.querySelector('.player__controls-item--prev');
|
||||
const nextBtn = document.querySelector('.player__controls-item--next');
|
||||
|
||||
[prevBtn, nextBtn].forEach(btn => {
|
||||
if (btn && btn.tagName === 'A') {
|
||||
btn.addEventListener('click', function() {
|
||||
if (playerEl && playerEl.classList.contains('player--playing')) {
|
||||
localStorage.setItem('vinyl_auto_play', 'true');
|
||||
} else {
|
||||
localStorage.setItem('vinyl_auto_play', 'false');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
Reference in New Issue
Block a user