diff --git a/src/components/Player.tsx b/src/components/Player.tsx
index cb06505..1e6afe8 100644
--- a/src/components/Player.tsx
+++ b/src/components/Player.tsx
@@ -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);
}
diff --git a/src/components/player/Slider/index.tsx b/src/components/player/Slider/index.tsx
index 917938e..94e4f12 100644
--- a/src/components/player/Slider/index.tsx
+++ b/src/components/player/Slider/index.tsx
@@ -54,6 +54,13 @@ export default function Slider({ audioPlayer, progress }: Props) {
}
}}
/>
+
{formatTime(currentTime, totalTime)} / {formatTime(totalTime)}
diff --git a/src/components/player/Slider/styles.css b/src/components/player/Slider/styles.css
index 81228e0..790defe 100644
--- a/src/components/player/Slider/styles.css
+++ b/src/components/player/Slider/styles.css
@@ -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;
@@ -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;
@@ -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));
+ }
}