import useLyric from '@/web/hooks/useLyric' import { player } from '@/web/store' import { motion } from 'framer-motion' import { lyricParser } from '@/web/utils/lyric' import { useMemo } from 'react' import { useSnapshot } from 'valtio' import cx from 'classnames' const Lyric = ({ className }: { className?: string }) => { // const ease = [0.5, 0.2, 0.2, 0.8] const playerSnapshot = useSnapshot(player) const track = useMemo(() => playerSnapshot.track, [playerSnapshot.track]) const { data: lyricRaw } = useLyric({ id: track?.id ?? 0 }) const lyric = useMemo(() => { return lyricRaw && lyricParser(lyricRaw) }, [lyricRaw]) const progress = playerSnapshot.progress + 0.3 const currentLine = useMemo(() => { const index = (lyric?.lyric.findIndex(({ time }) => time > progress) ?? 1) - 1 return { index: index < 1 ? 0 : index, time: lyric?.lyric?.[index]?.time ?? 0, } }, [lyric?.lyric, progress]) const displayLines = useMemo(() => { const index = currentLine.index const lines = lyric?.lyric.slice(index === 0 ? 0 : index - 1, currentLine.index + 7) ?? [] if (index === 0) { lines.unshift({ time: 0, content: '', rawTime: '[00:00:00]', }) } return lines }, [currentLine.index, lyric?.lyric]) const variants = { initial: { opacity: [0, 0.2], y: ['24%', 0] }, current: { opacity: 1, y: 0, transition: { ease: [0.5, 0.2, 0.2, 0.8], duration: 0.7, }, }, rest: (index: number) => ({ opacity: 0.2, y: 0, transition: { delay: index * 0.04, ease: [0.5, 0.2, 0.2, 0.8], duration: 0.7, }, }), exit: { opacity: 0, y: -132, height: 0, paddingTop: 0, paddingBottom: 0, transition: { duration: 0.7, ease: [0.5, 0.2, 0.2, 0.8], }, }, } return (
{displayLines.map(({ content, time }, index) => { return ( {content} ) })}
) } export default Lyric