feat: replace CD mockup with animated vinyl player component in music productions list and detail views
This commit is contained in:
@@ -107,35 +107,36 @@
|
|||||||
$detailUrl = route('music-productions.show', $production->slug);
|
$detailUrl = route('music-productions.show', $production->slug);
|
||||||
@endphp
|
@endphp
|
||||||
<div class="project item xl:w-4/12 lg:w-6/12 md:w-6/12 w-full flex-[0_0_auto] max-w-full {{ $variant['filter'] }} px-[20px] xl:!px-[25px] lg:!px-[25px] !mt-[2rem] xl:!mt-[2.5rem] lg:!mt-[2.5rem]">
|
<div class="project item xl:w-4/12 lg:w-6/12 md:w-6/12 w-full flex-[0_0_auto] max-w-full {{ $variant['filter'] }} px-[20px] xl:!px-[25px] lg:!px-[25px] !mt-[2rem] xl:!mt-[2.5rem] lg:!mt-[2.5rem]">
|
||||||
<div class="card !shadow-[0_0.25rem_1.75rem_rgba(30,34,40,0.07)]">
|
<div class="player-container">
|
||||||
<figure class="card-img-top music-production-cover itooltip {{ $variant['tooltip'] }}" title='<h5 class="!mb-0">{{ e(__('music_productions.view_details_tooltip')) }}</h5>'>
|
<div class="player" data-player data-playlist="prod-{{ $production->id }}" data-track="0">
|
||||||
<a href="{{ $detailUrl }}" class="music-production-cover__link">
|
<div class="player__content">
|
||||||
@if($production->cover_image_url)
|
<div class="player__artist">{{ $production->translate('client_name') ?: __('music_productions.card_category_default') }}</div>
|
||||||
<img src="{{ $production->cover_image_url }}" alt="{{ $production->translate('title') }}" loading="lazy">
|
<div class="player__album">
|
||||||
@else
|
|
||||||
<img src="{{ asset('assets/img/photos/pd6.jpg') }}" alt="{{ $production->translate('title') }}" loading="lazy">
|
|
||||||
@endif
|
|
||||||
</a>
|
|
||||||
</figure>
|
|
||||||
<div class="card-body p-7">
|
|
||||||
<div class="post-header">
|
|
||||||
<div class="d-none {{ $variant['label_class'] }}">
|
|
||||||
@if($production->production_date)
|
@if($production->production_date)
|
||||||
{{ $production->production_date->format('d.m.Y') }}
|
{{ $production->production_date->format('Y') }}
|
||||||
@else
|
@else
|
||||||
{{ __('music_productions.production_date_unknown') }}
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
<div class="player__track">{{ $production->translate('title') }}</div>
|
||||||
<h3 class="!mb-0 truncate" title="{{ $production->translate('title') }}">{{ $production->translate('title') }}</h3>
|
|
||||||
|
<a href="{{ $detailUrl }}" class="album" data-album>
|
||||||
|
@if($production->cover_image_url)
|
||||||
|
<div class="album__cover" style="background-image: url('{{ $production->cover_image_url }}');"></div>
|
||||||
|
@else
|
||||||
|
<div class="album__cover" style="background-image: url('{{ asset('assets/img/photos/pd6.jpg') }}');"></div>
|
||||||
|
@endif
|
||||||
|
<div class="vinyl">
|
||||||
|
<div class="vinyl__shadow"></div>
|
||||||
|
<div class="vinyl__circle">
|
||||||
|
<div class="vinyl__center" style="--center-bg: url('{{ $production->cover_image_url ?: asset('assets/img/photos/pd6.jpg') }}')"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.post-header -->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /.card-body -->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /.card -->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /.project -->
|
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
<!-- /.row -->
|
<!-- /.row -->
|
||||||
@@ -308,5 +309,243 @@
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- Vinyl Player Styles --- */
|
||||||
|
:root {
|
||||||
|
--color-black: #000;
|
||||||
|
--color-gray: #5e6062;
|
||||||
|
--color-white: #fff;
|
||||||
|
--color-yellow: #f0f39c;
|
||||||
|
--color-yellow-light: #fff99e;
|
||||||
|
--transition-time: 250ms;
|
||||||
|
--transition-method: ease-in-out;
|
||||||
|
--album-size: 260px;
|
||||||
|
--vinyl-offset: 15px;
|
||||||
|
--vinyl-size: calc(var(--album-size) - var(--vinyl-offset));
|
||||||
|
--vinyl-center-size: 110px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 15px 0;
|
||||||
|
perspective: 1000px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player {
|
||||||
|
color: var(--color-gray);
|
||||||
|
font-family: 'Raleway', 'Outfit', sans-serif;
|
||||||
|
height: var(--album-size);
|
||||||
|
line-height: 1.2;
|
||||||
|
position: relative;
|
||||||
|
width: var(--album-size);
|
||||||
|
transition: all var(--transition-time) var(--transition-method);
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player::after {
|
||||||
|
transform: rotate(-2deg);
|
||||||
|
transition: all var(--transition-time) var(--transition-method);
|
||||||
|
background: #777;
|
||||||
|
bottom: 12px;
|
||||||
|
box-shadow: 0 15px 23px rgba(0, 0, 0, 0.3);
|
||||||
|
content: '';
|
||||||
|
height: 10px;
|
||||||
|
left: 2%;
|
||||||
|
opacity: 0;
|
||||||
|
padding-left: 5%;
|
||||||
|
position: absolute;
|
||||||
|
width: 96%;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player:hover::after {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player .player__content {
|
||||||
|
background-color: var(--color-white);
|
||||||
|
height: 100%;
|
||||||
|
padding: 50px 15px 0 15px;
|
||||||
|
position: relative;
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 10;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
border: 1px solid rgba(8, 60, 130, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.player .player__artist {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
max-width: 140px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: #343f52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player .player__album {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 300;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
max-width: 140px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: #a4aec6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player .player__track {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
max-width: 140px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: #60697b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player .player__track::before,
|
||||||
|
.player .player__track::after {
|
||||||
|
content: '"';
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album {
|
||||||
|
transform: translateY(-50%);
|
||||||
|
transition: all var(--transition-time) var(--transition-method);
|
||||||
|
box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.15);
|
||||||
|
cursor: pointer;
|
||||||
|
height: var(--album-size);
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 50%;
|
||||||
|
width: var(--album-size);
|
||||||
|
z-index: 100;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player:hover {
|
||||||
|
transform: scale(1.08) translateY(-5px);
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player:hover .player__content {
|
||||||
|
box-shadow: 0 15px 35px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.player:hover .album {
|
||||||
|
right: -140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album__cover {
|
||||||
|
background-color: var(--color-black);
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 20;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl {
|
||||||
|
transition: all var(--transition-time) var(--transition-method);
|
||||||
|
left: calc(var(--vinyl-offset) / 2);
|
||||||
|
position: absolute;
|
||||||
|
top: calc(var(--vinyl-offset) / 2);
|
||||||
|
height: var(--vinyl-size);
|
||||||
|
width: var(--vinyl-size);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__shadow,
|
||||||
|
.vinyl__circle {
|
||||||
|
border-radius: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__shadow {
|
||||||
|
box-shadow: 2px 8px 15px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__circle {
|
||||||
|
animation: rotate-vinyl 3s linear infinite both paused;
|
||||||
|
background-color: #1e1b1b;
|
||||||
|
background-image: radial-gradient(circle, #2c2727 10%, transparent 10%),
|
||||||
|
repeating-radial-gradient(circle, #2c2727, #1e1b1b 2px, #2c2727 4px);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player:hover .vinyl {
|
||||||
|
left: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player:hover .vinyl__circle {
|
||||||
|
animation-play-state: running;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__center {
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: #292424;
|
||||||
|
border-radius: 100%;
|
||||||
|
height: var(--vinyl-center-size);
|
||||||
|
left: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
width: var(--vinyl-center-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__center::before,
|
||||||
|
.vinyl__center::after {
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
border-radius: 100%;
|
||||||
|
content: '';
|
||||||
|
left: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__center::before {
|
||||||
|
background-color: #e31e24;
|
||||||
|
background-image: var(--center-bg);
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
height: calc(var(--vinyl-center-size) - 20px);
|
||||||
|
width: calc(var(--vinyl-center-size) - 20px);
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__center::after {
|
||||||
|
background-color: #fff;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
z-index: 10;
|
||||||
|
box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate-vinyl {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@endpush
|
@endpush
|
||||||
|
|||||||
@@ -40,28 +40,51 @@
|
|||||||
}
|
}
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
{{-- CD Jewel Case 3D Mockup --}}
|
{{-- Vinyl Player Mockup --}}
|
||||||
@if($production->cover_image_url)
|
@if($production->cover_image_url)
|
||||||
<div class="cd-mockup-wrapper flex justify-center !mb-12 xl:!mb-16">
|
<div class="player-container flex justify-center !mb-12 xl:!mb-16">
|
||||||
<div class="cd-case-perspective">
|
<div class="player player--open" id="detail-vinyl-player" data-player>
|
||||||
<div class="cd-case" @if($videoId) id="play-cd-btn" style="cursor: pointer;" title="{{ __('music_productions.youtube_watch_on_youtube') }}" @endif>
|
<div class="player__content">
|
||||||
{{-- Left Spine (Plastic Hinge) --}}
|
<div class="player__artist has-fade-in">{{ $production->translate('client_name') ?: __('music_productions.card_category_default') }}</div>
|
||||||
<div class="cd-spine"></div>
|
<div class="player__album has-fade-in">
|
||||||
{{-- Cover Graphic --}}
|
@if($production->production_date)
|
||||||
<div class="cd-cover" style="background-image: url('{{ $production->cover_image_url }}');">
|
{{ $production->production_date->format('Y') }}
|
||||||
{{-- Glass shine reflection --}}
|
@else
|
||||||
<div class="cd-shine"></div>
|
|
||||||
{{-- Play Button Overlay --}}
|
@endif
|
||||||
@if($videoId)
|
</div>
|
||||||
<div class="cd-play-overlay">
|
<div class="player__track has-fade-in">{{ $production->translate('title') }}</div>
|
||||||
<div class="cd-play-btn">
|
|
||||||
<i class="uil uil-play before:content-['\ea15'] text-white text-[2rem] ml-1"></i>
|
<div class="album" data-album>
|
||||||
|
<div class="album__cover" style="background-image: url('{{ $production->cover_image_url }}');"></div>
|
||||||
|
<div class="vinyl">
|
||||||
|
<div class="vinyl__shadow"></div>
|
||||||
|
<div class="vinyl__circle">
|
||||||
|
<div class="vinyl__center" style="--center-bg: url('{{ $production->cover_image_url }}')"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
|
||||||
|
<div class="player__controls has-fade-in">
|
||||||
|
@if($prev)
|
||||||
|
<a href="{{ route('music-productions.show', $prev->slug) }}" class="player__controls-item player__controls-item--prev" title="{{ __('music_productions.prev') }}"></a>
|
||||||
|
@else
|
||||||
|
<div class="player__controls-item player__controls-item--prev opacity-30 cursor-not-allowed"></div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="player__controls-item player__controls-item--play" id="play-cd-btn" title="{{ __('music_productions.youtube_watch_on_youtube') }}">
|
||||||
|
<div class="rectangle"></div>
|
||||||
|
<div class="triangle"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if($next)
|
||||||
|
<a href="{{ route('music-productions.show', $next->slug) }}" class="player__controls-item player__controls-item--next" title="{{ __('music_productions.next') }}"></a>
|
||||||
|
@else
|
||||||
|
<div class="player__controls-item player__controls-item--next opacity-30 cursor-not-allowed"></div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@@ -188,151 +211,413 @@
|
|||||||
|
|
||||||
@push('styles')
|
@push('styles')
|
||||||
<style>
|
<style>
|
||||||
/* 3D CD Jewel Case Mockup Styles */
|
/* --- Vinyl Player Styles --- */
|
||||||
.cd-mockup-wrapper {
|
:root {
|
||||||
perspective: 2000px;
|
--color-black: #000;
|
||||||
|
--color-gray: #5e6062;
|
||||||
|
--color-white: #fff;
|
||||||
|
--color-yellow: #f0f39c;
|
||||||
|
--color-yellow-light: #fff99e;
|
||||||
|
--transition-time: 250ms;
|
||||||
|
--transition-method: ease-in-out;
|
||||||
|
--album-size: 310px;
|
||||||
|
--vinyl-offset: 20px;
|
||||||
|
--vinyl-size: calc(var(--album-size) - var(--vinyl-offset));
|
||||||
|
--vinyl-center-size: 130px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cd-case-perspective {
|
.player-container {
|
||||||
width: 100%;
|
display: flex;
|
||||||
max-width: 400px;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px 0;
|
||||||
|
perspective: 1000px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player {
|
||||||
|
color: var(--color-gray);
|
||||||
|
font-family: 'Raleway', 'Outfit', sans-serif;
|
||||||
|
height: var(--album-size);
|
||||||
|
line-height: 1.2;
|
||||||
|
position: relative;
|
||||||
|
width: var(--album-size);
|
||||||
|
transition: all var(--transition-time) var(--transition-method);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cd-case {
|
.player::after {
|
||||||
|
transform: rotate(-2deg);
|
||||||
|
transition: all var(--transition-time) var(--transition-method);
|
||||||
|
background: #777;
|
||||||
|
bottom: 12px;
|
||||||
|
box-shadow: 0 15px 23px rgba(0, 0, 0, 0.3);
|
||||||
|
content: '';
|
||||||
|
height: 10px;
|
||||||
|
left: 2%;
|
||||||
|
opacity: 0;
|
||||||
|
padding-left: 5%;
|
||||||
|
position: absolute;
|
||||||
|
width: 96%;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player--open::after {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player .player__content {
|
||||||
|
background-color: var(--color-white);
|
||||||
|
height: 100%;
|
||||||
|
padding: 70px 20px 0 20px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
text-align: left;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
aspect-ratio: 1/1;
|
|
||||||
background: rgba(255, 255, 255, 0.08);
|
|
||||||
border: 4px solid rgba(255, 255, 255, 0.35);
|
|
||||||
border-radius: 12px;
|
|
||||||
box-shadow:
|
|
||||||
-10px 20px 40px rgba(0, 0, 0, 0.3),
|
|
||||||
0 10px 20px rgba(0, 0, 0, 0.15),
|
|
||||||
inset 0 0 15px rgba(255, 255, 255, 0.2);
|
|
||||||
transform: rotateX(15deg) rotateY(-18deg) rotateZ(3deg);
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
transition: all 0.7s cubic-bezier(0.165, 0.84, 0.44, 1);
|
|
||||||
display: flex;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cd-case:hover {
|
|
||||||
transform: rotateX(6deg) rotateY(-6deg) rotateZ(0deg) scale(1.06);
|
|
||||||
border-color: rgba(255, 255, 255, 0.5);
|
|
||||||
box-shadow:
|
|
||||||
-15px 30px 55px rgba(0, 0, 0, 0.4),
|
|
||||||
0 15px 30px rgba(0, 0, 0, 0.2),
|
|
||||||
inset 0 0 25px rgba(255, 255, 255, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CD Hinge / Plastic Tray Spine */
|
|
||||||
.cd-spine {
|
|
||||||
width: 24px;
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(90deg,
|
|
||||||
rgba(20, 20, 20, 0.85) 0%,
|
|
||||||
rgba(70, 70, 70, 0.9) 20%,
|
|
||||||
rgba(35, 35, 35, 0.85) 45%,
|
|
||||||
rgba(90, 90, 90, 0.7) 65%,
|
|
||||||
rgba(25, 25, 25, 0.9) 100%
|
|
||||||
);
|
|
||||||
border-radius: 6px 0 0 6px;
|
|
||||||
border-right: 1.5px solid rgba(255, 255, 255, 0.15);
|
|
||||||
position: relative;
|
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
box-shadow: inset 1px 0 3px rgba(255, 255, 255, 0.2);
|
border-radius: 8px;
|
||||||
}
|
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
||||||
|
|
||||||
/* CD Booklet Cover Art */
|
|
||||||
.cd-cover {
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
border-radius: 0 6px 6px 0;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: flex-start;
|
||||||
box-shadow: inset 0 0 12px rgba(0, 0, 0, 0.55);
|
border: 1px solid rgba(8, 60, 130, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Jewel Case Plastic Glass Reflection */
|
.player .player__artist {
|
||||||
.cd-shine {
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
max-width: 180px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: #343f52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player .player__album {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 300;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
max-width: 180px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: #a4aec6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player .player__track {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
max-width: 180px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: #60697b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player .player__track::before,
|
||||||
|
.player .player__track::after {
|
||||||
|
content: '"';
|
||||||
|
font-size: 16px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player--open {
|
||||||
|
border-radius: 8px;
|
||||||
|
height: 320px;
|
||||||
|
position: relative;
|
||||||
|
width: 440px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 25px;
|
||||||
|
left: 20px;
|
||||||
|
text-align: left;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 180px;
|
||||||
|
z-index: 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item {
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
height: 26px;
|
||||||
|
margin-right: 15px;
|
||||||
|
position: relative;
|
||||||
|
width: 26px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--play {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--play .rectangle,
|
||||||
|
.player__controls-item--play .triangle {
|
||||||
|
height: 26px;
|
||||||
|
left: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
width: 26px;
|
||||||
width: 160%;
|
}
|
||||||
height: 160%;
|
|
||||||
background: linear-gradient(135deg,
|
.player__controls-item--play .rectangle {
|
||||||
rgba(255, 255, 255, 0.5) 0%,
|
|
||||||
rgba(255, 255, 255, 0.18) 32%,
|
|
||||||
rgba(255, 255, 255, 0) 32.5%,
|
|
||||||
rgba(255, 255, 255, 0) 48%,
|
|
||||||
rgba(255, 255, 255, 0.12) 48.5%,
|
|
||||||
rgba(255, 255, 255, 0.06) 65%,
|
|
||||||
rgba(255, 255, 255, 0) 65.5%
|
|
||||||
);
|
|
||||||
transform: translate(-30%, -30%) rotate(4deg);
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
transition: all 0.7s cubic-bezier(0.165, 0.84, 0.44, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cd-case:hover .cd-shine {
|
.player__controls-item--play .rectangle::before,
|
||||||
transform: translate(-18%, -18%) rotate(8deg);
|
.player__controls-item--play .rectangle::after {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
background-color: #e31e24;
|
||||||
|
content: '';
|
||||||
|
height: 100%;
|
||||||
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hover Play Button Overlay */
|
.player--playing .player__controls-item--play .rectangle::before,
|
||||||
.cd-play-overlay {
|
.player--playing .player__controls-item--play .rectangle::after {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--play .rectangle::before {
|
||||||
|
float: left;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--play .rectangle::after {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--play .triangle {
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--play .triangle::before,
|
||||||
|
.player__controls-item--play .triangle::after {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
background-color: transparent;
|
||||||
|
border-bottom: 13px solid transparent;
|
||||||
|
border-right: 26px solid #fff;
|
||||||
|
border-top: 13px solid transparent;
|
||||||
|
content: '';
|
||||||
|
height: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
right: 0;
|
||||||
background: rgba(0, 0, 0, 0.4);
|
top: 0;
|
||||||
display: flex;
|
width: 0;
|
||||||
align-items: center;
|
}
|
||||||
justify-content: center;
|
|
||||||
|
.player__controls-item--play .triangle::before {
|
||||||
|
transform: translate(0, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.player--playing .player__controls-item--play .triangle::before {
|
||||||
|
transform: translate(0, -100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--play .triangle::after {
|
||||||
|
transform: translate(0, 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.player--playing .player__controls-item--play .triangle::after {
|
||||||
|
transform: translate(0, 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--play:hover .rectangle::before,
|
||||||
|
.player__controls-item--play:hover .rectangle::after {
|
||||||
|
background-color: #c1181d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--next,
|
||||||
|
.player__controls-item--prev {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--next::before,
|
||||||
|
.player__controls-item--next::after,
|
||||||
|
.player__controls-item--prev::before,
|
||||||
|
.player__controls-item--prev::after {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border-bottom: 13px solid transparent;
|
||||||
|
border-top: 13px solid transparent;
|
||||||
|
content: '';
|
||||||
|
height: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--next::before,
|
||||||
|
.player__controls-item--next::after {
|
||||||
|
border-left: 16px solid #e31e24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--next::before {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--next::after {
|
||||||
|
left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--next:hover::before,
|
||||||
|
.player__controls-item--next:hover::after {
|
||||||
|
border-left-color: #c1181d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--prev::before,
|
||||||
|
.player__controls-item--prev::after {
|
||||||
|
border-right: 16px solid #e31e24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--prev::before {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--prev::after {
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player__controls-item--prev:hover::before,
|
||||||
|
.player__controls-item--prev:hover::after {
|
||||||
|
border-right-color: #c1181d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album {
|
||||||
|
transform: translateY(-50%);
|
||||||
|
transition: all var(--transition-time) var(--transition-method);
|
||||||
|
box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.15);
|
||||||
|
cursor: pointer;
|
||||||
|
height: var(--album-size);
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 50%;
|
||||||
|
width: var(--album-size);
|
||||||
|
z-index: 100;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player--open .album {
|
||||||
|
cursor: default;
|
||||||
|
right: -80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album__cover {
|
||||||
|
background-color: var(--color-black);
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 20;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl {
|
||||||
|
transition: all var(--transition-time) var(--transition-method);
|
||||||
|
left: calc(var(--vinyl-offset) / 2);
|
||||||
|
position: absolute;
|
||||||
|
top: calc(var(--vinyl-offset) / 2);
|
||||||
|
height: var(--vinyl-size);
|
||||||
|
width: var(--vinyl-size);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__shadow,
|
||||||
|
.vinyl__circle {
|
||||||
|
border-radius: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__shadow {
|
||||||
|
box-shadow: 2px 8px 15px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__circle {
|
||||||
|
animation: rotate-vinyl 3s linear infinite both paused;
|
||||||
|
background-color: #1e1b1b;
|
||||||
|
background-image: radial-gradient(circle, #2c2727 10%, transparent 10%),
|
||||||
|
repeating-radial-gradient(circle, #2c2727, #1e1b1b 2px, #2c2727 4px);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player--open .vinyl {
|
||||||
|
left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player--playing .vinyl {
|
||||||
|
left: 45% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player--playing .vinyl__circle {
|
||||||
|
animation-play-state: running;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__center {
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: #292424;
|
||||||
|
border-radius: 100%;
|
||||||
|
height: var(--vinyl-center-size);
|
||||||
|
left: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
width: var(--vinyl-center-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__center::before,
|
||||||
|
.vinyl__center::after {
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
border-radius: 100%;
|
||||||
|
content: '';
|
||||||
|
left: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__center::before {
|
||||||
|
background-color: #e31e24;
|
||||||
|
background-image: var(--center-bg);
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
height: calc(var(--vinyl-center-size) - 20px);
|
||||||
|
width: calc(var(--vinyl-center-size) - 20px);
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vinyl__center::after {
|
||||||
|
background-color: #fff;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
z-index: 10;
|
||||||
|
box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate-vinyl {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.has-fade-in {
|
||||||
|
transition: all calc(var(--transition-time) * 2) var(--transition-method);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: all 0.3s ease;
|
pointer-events: none;
|
||||||
z-index: 6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cd-case:hover .cd-play-overlay {
|
.player--open .has-fade-in {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
pointer-events: auto;
|
||||||
|
|
||||||
.cd-play-btn {
|
|
||||||
width: 68px;
|
|
||||||
height: 68px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #e31e24;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-shadow:
|
|
||||||
0 10px 25px rgba(227, 30, 36, 0.5),
|
|
||||||
0 0 0 0px rgba(227, 30, 36, 0.3);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
transform: scale(0.85);
|
|
||||||
}
|
|
||||||
|
|
||||||
.cd-case:hover .cd-play-btn {
|
|
||||||
transform: scale(1);
|
|
||||||
animation: pulse-red-ring 2s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse-red-ring {
|
|
||||||
0% {
|
|
||||||
box-shadow: 0 0 0 0px rgba(227, 30, 36, 0.7);
|
|
||||||
}
|
|
||||||
70% {
|
|
||||||
box-shadow: 0 0 0 15px rgba(227, 30, 36, 0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
box-shadow: 0 0 0 0px rgba(227, 30, 36, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Content styling */
|
/* Content styling */
|
||||||
@@ -369,13 +654,11 @@ article {
|
|||||||
to { opacity: 1; transform: translateY(0); }
|
to { opacity: 1; transform: translateY(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flatten 3D CD element when lightbox is open to fix stacking context issues */
|
/* Flatten elements when lightbox is open to fix stacking context issues */
|
||||||
body.lightbox-open .cd-mockup-wrapper,
|
body.lightbox-open .player-container,
|
||||||
body.lightbox-open .cd-case-perspective,
|
body.lightbox-open .player {
|
||||||
body.lightbox-open .cd-case {
|
|
||||||
transform: none !important;
|
transform: none !important;
|
||||||
perspective: none !important;
|
perspective: none !important;
|
||||||
transform-style: flat !important;
|
|
||||||
z-index: 1 !important;
|
z-index: 1 !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -385,6 +668,7 @@ body.lightbox-open .cd-case {
|
|||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const cdBtn = document.getElementById('play-cd-btn');
|
const cdBtn = document.getElementById('play-cd-btn');
|
||||||
|
const playerEl = document.getElementById('detail-vinyl-player');
|
||||||
const lightbox = document.getElementById('youtube-lightbox');
|
const lightbox = document.getElementById('youtube-lightbox');
|
||||||
const lightboxBg = document.getElementById('lightbox-bg');
|
const lightboxBg = document.getElementById('lightbox-bg');
|
||||||
const lightboxContent = document.getElementById('lightbox-content');
|
const lightboxContent = document.getElementById('lightbox-content');
|
||||||
@@ -393,10 +677,17 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
const videoId = "{{ $videoId }}";
|
const videoId = "{{ $videoId }}";
|
||||||
|
|
||||||
if (cdBtn && lightbox && iframe) {
|
if (cdBtn && lightbox && iframe) {
|
||||||
cdBtn.addEventListener('click', function() {
|
cdBtn.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
// Set autoplay & enable javascript API
|
// Set autoplay & enable javascript API
|
||||||
iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=1&enablejsapi=1`;
|
iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=1&enablejsapi=1`;
|
||||||
|
|
||||||
|
// Start vinyl spinning animation
|
||||||
|
if (playerEl) {
|
||||||
|
playerEl.classList.add('player--playing');
|
||||||
|
}
|
||||||
|
|
||||||
// Show lightbox container with transition
|
// Show lightbox container with transition
|
||||||
lightbox.classList.remove('opacity-0', 'pointer-events-none');
|
lightbox.classList.remove('opacity-0', 'pointer-events-none');
|
||||||
document.body.classList.add('lightbox-open');
|
document.body.classList.add('lightbox-open');
|
||||||
@@ -410,6 +701,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
lightbox.classList.add('opacity-0', 'pointer-events-none');
|
lightbox.classList.add('opacity-0', 'pointer-events-none');
|
||||||
document.body.classList.remove('lightbox-open');
|
document.body.classList.remove('lightbox-open');
|
||||||
|
|
||||||
|
// Stop vinyl spinning animation
|
||||||
|
if (playerEl) {
|
||||||
|
playerEl.classList.remove('player--playing');
|
||||||
|
}
|
||||||
|
|
||||||
// Clear source to halt playback after transition completes
|
// Clear source to halt playback after transition completes
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
iframe.src = "";
|
iframe.src = "";
|
||||||
|
|||||||
Reference in New Issue
Block a user