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) { } }} /> +
+
+
+
+
+
+
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)); + } }