[react] audio 슬라이더 div로 만들어보기

해달·2023년 7월 3일
1
post-thumbnail
post-custom-banner

서두

Audio Player의 기능들을 구현해보면서 audio 태그를 처음 다루어 보게 되었다.

기능을 구현하면서 재생시간만큼 표시해주는 플레이어 바를 만들게 되었는데,

  1. youtube 에서 플레이어바를 div로 구현하고 있는걸 확인
  2. 다른사람들은 input range 로 구현하는것을 확인

두가지 방법 중 선택이였는데 div로 만드는게 더 재밌어보였고, 내가 구현해야하는 요구사항이랑 맞게 떨어지는거 같아 1번으로 구현해 보았다 !

완성 된 플레이어 !

디자인은 유튜브 뮤직 따라했다.


재생 된 만큼 플레이어 바 게이지 표시

오디오 플레이어의 ProgressBar를 핸들링 할 useProgress hook 을 생성 후 각 state들로 상태 값들을 핸들링 하였다.

Div로 프로그레스바를 핸들링 하고 싶었기 때문에 바에서 클릭 되었을 때 위치를 구하고, 재생되어야 할 시간을 계산해서 currentTime 을 변경해주었다!

useProgress.tsx

//필요 없는 부분 생략, 각색
const useProgress = (
  selectedMusicRef: React.MutableRefObject<HTMLAudioElement | null>
) => {
  
  const handleProgressClick = (
    e: MouseEvent<HTMLDivElement, globalThis.MouseEvent>
  ) => {
    if (!selectedMusicRef.current) return;

    const { duration } = selectedMusicRef.current;
    const clickX = e.nativeEvent.offsetX;
    const width = e.currentTarget.clientWidth;

    selectedMusicRef.current.currentTime = (clickX / width) * duration;
  };

    return (
      <Container onClick={handleProgressClick}>
        <Progress width={percentage} />
      </Container>
    );

선택 된 audio의 값을 갖고 있는 selectedMusicRef 값을 인자로 받고

3개의 변수 값 가져오기

  1. duration : 미디어의 총 길이를 가진 duration
  2. clickX : 클릭 이벤트가 발생한 위치의 X 좌표
  3. width : 클릭 이벤트가 발생한 요소의 전체 너비 가져오기
(clickX / width) * duration

위 계산식을 통해 클릭한 위치의 비율을 구한 뒤,
총 재생시간을duration 곱해 음악 재생위치(currentTime)를 변경시켜준다.

AudioPlayer.tsx

const AudioPlayer = ({ selectedMusicRef}) => {
  const { currentTime, duration, renderProgressBar } =
    useProgress(selectedMusicRef);


  return (
    <Container>
      {renderProgressBar()}
      <Wrapper>
        <div>{formatTime(currentTime)}</div>
        <div>{formatTime(duration)}</div>
      </Wrapper>
    </Container>
  );
};

export default AudioPlayer;

프로그레스 바를 렌더링 하는 함수와 그 외 필요한 값들을 hook에서 추출하여 화면을 그려 주었다!


Refrenne

post-custom-banner

0개의 댓글