Skip to content
Merged
11 changes: 11 additions & 0 deletions src/components/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,24 @@ export default function Player() {
const percentage =
(audioPlayer.current.currentTime / audioPlayer.current.duration) * 100;
setProgress(percentage);

const slider = document.querySelector('.slider');
const particles = document.querySelector('.ship-particles');

if (slider) {
(slider as HTMLElement).style.setProperty(
'--seek-before-width',
`${percentage}%`
);
}

if (particles && slider) {
const pxOffset = slider.clientWidth * (percentage / 100);
(particles as HTMLElement).style.setProperty(
'--seek-particles-left',
`${pxOffset - 10}px` // -5 to put the dots into the track
);
}
}
progressRef.current = requestAnimationFrame(whilePlaying);
}
Expand Down
7 changes: 7 additions & 0 deletions src/components/player/Slider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ export default function Slider({ audioPlayer, progress }: Props) {
}
}}
/>
<div className={"ship-particles absolute h-full -top-[1px] grid place-items-center place-content-center pointer-events-none"}>
<div className="w-1 h-1 rounded-full row-start-1 col-start-1"></div>
<div className="w-1 h-1 rounded-full row-start-1 col-start-1"></div>
<div className="w-1 h-1 rounded-full row-start-1 col-start-1"></div>
<div className="w-1 h-1 rounded-full row-start-1 col-start-1"></div>
<div className="w-1 h-1 rounded-full row-start-1 col-start-1"></div>
</div>
<span class="hidden text-nowrap text-sm tabular-nums md:inline-block">
{formatTime(currentTime, totalTime)} / {formatTime(totalTime)}
</span>
Expand Down
78 changes: 78 additions & 0 deletions src/components/player/Slider/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
@apply relative -mt-[5px] box-content h-4 w-4 cursor-pointer appearance-none bg-contain bg-no-repeat transition-opacity duration-300 lg:opacity-0;
background-image: url('/images/rocket-dark.svg');
background-position: center center;
box-shadow: none;
background-color: #0000;
}
&::-moz-range-track {
@apply h-1.5 w-full cursor-pointer border-none bg-gray-200 outline-none dark:bg-gray-700;
Expand All @@ -35,6 +37,15 @@
background-position: center center;
}

@media (prefers-color-scheme: light) {
&::-webkit-slider-thumb {
background-image: url('/images/rocket-light.svg');
}
&::-moz-range-thumb {
background-image: url('/images/rocket-light.svg');
}
}

&:hover {
&::-webkit-slider-thumb {
@apply opacity-100;
Expand All @@ -44,4 +55,71 @@
@apply opacity-100;
}
}

&:not(:hover) ~ .ship-particles {
display: none;
}
}

.ship-particles {
left: max(0px, var(--seek-particles-left));

> div {
animation:
ship-particles-x 1s ease infinite,
ship-particles-y 1s ease infinite;
animation-composition: add;
background-color: #B0ECFF;
opacity: 0;

@media (prefers-color-scheme: light) {
background-color: #906BFF;
}

&:nth-child(1) {
animation-delay: 0.4s;
--y-offset: -10px;
--x-offset: -20px;
}
&:nth-child(2) {
animation-delay: 0.8s;
--y-offset: -20px;
--x-offset: -15px;
}
&:nth-child(3) {
animation-delay: 0.1s;
--y-offset: 15px;
--x-offset: -25px;
}
&:nth-child(4) {
animation-delay: 0.3s;
--y-offset: 25px;
--x-offset: -10px;
}
&:nth-child(5) {
animation-delay: 0.7s;
--y-offset: 17px;
--x-offset: -15px;
}
}
}

@keyframes ship-particles-x {
0% {
opacity: 1;
transform: translateX(0) scale(1);
}
100% {
opacity: 0;
transform: translateX(var(--x-offset)) scale(.25) translateY(var(--y-offset));
}
}

@keyframes ship-particles-y {
0%, 15% {
transform: translateY(0);
}
100% {
transform: translateY(var(--y-offset));
}
}