티스토리 뷰

728x90
반응형

 

안녕하세요. Teus입니다.

 

지난번까지, 어떻게 모바일 청첩장 페이지를 구성할지 다뤘습니다.

 

이제 이 페이지 레이아웃의 Components를 하나씩 채워보겠습니다.

 

이번에는 가장 최 상단에 위치하는 오디오 입니다.

 

​# 1. 오디오영역 Components

모바일 청첩장에 BGM이 빠질 수 없죠?

 

다들 결혼식 하면 생각날 아주 따스한 음악으로 깔아 주지용.

 

이제 이 BGM을 모바일 청첩장 프로젝트에 추가해 보도록 하겠습니다.

 

오디오영역 Components 같은 경우는 오디오 버튼이 존재하고

 

해당 버튼을 누르면 Audio가 나오고, 버튼을 다시 누르면 Audio가 종료되는 형태로 동작합니다.

 

아래와 같이 간단하게 설계할 수 있겠네요.

 

일단 Audio 버튼을 만들기 위한 Audio icon을 구글에 검색하면 다양한 이미지를 확인할 수 있습니다

이중에 본인 맘에 드시는거 가지고 오시면 될거 같습니다.

(제가 받은거는 저작권 때문에 재업로드를 못해요!)

 

그리고 이렇게 받아온 파일을 프로잭트의 src/assets 위치에 옮겨줍니다.

그리고 이 audio 버튼을 react에서 가지고와서 화면에 표시해 줍니다.

 

저는 Audio버튼의 위치를 오른쪽 정렬 하려고 설계했기 때문에

 

아래처럼 코드를 수정해 줍니다.

 

import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'

import audioIcon from './assets/audio.svg'

function App() {
  const debug = process.env.NODE_ENV === 'development'?"solid":"none";
  return (
    <>
      <div className='main-frame'>
      <div style={{ border: debug, textAlign: 'right' }}>
          {/*Audio icon을 화면에 표기하기*/}
          <img
            src={audioIcon} 
            width={"20px"} 
            style={{ marginRight: "10px", marginTop: "10px" }} 
            onClick
          />
        </div>
        <div style={{ border: debug}}>
          신랑/신부 이름 어디서 언제 결혼 표시 영역
        </div>
        <div style={{ border: debug}}>
          신랑/신부 대표 사진
        </div>
        <div style={{ border: debug}}>
          웰컴 문구
        </div>
        <div style={{ border: debug}}>
          달력
        </div>
        <div style={{ border: debug}}>
          이미지 갤러리
        </div>
        <div style={{ border: debug}}>
          결혼식 장소
        </div>
        <div style={{ border: debug}}>
          신랑신부 계좌 정보
        </div>
        <div style={{ border: debug}}>
          카카오톡 공유하기 / 모청 주소 복사하기
        </div>
      </div>
    </>
  )
}

export default App

그러면 보는것처럼 우측에 적당한 여백을 두고 오디오 이미지가 생성된것을 볼 수 있습니다.

 

문제는 아직 audio버튼을 누른다고 재생이 되지는 않습니다.

 

이제 적당한 audio를 찾아야 겠죠?

 

저같은 경우 아래 동영상의 음성을 mp4로 따와서 임시로 만들었습니다🤣

 

https://www.youtube.com/watch?v=YLd0_8WnouM

추출하는 방법은
구글에 유튜브 음원추출 이라고 하면...🙄

 

 

저는 이 파일을 background_music.weba 라는 파일로 만들었고, 이 파일을 역시 src/assets폴더에 넣어줬습니다.

 

그리고 Audio 버튼을 누를 때 마다 켜졌다, 꺼졌다 해야겠죠?

 

이부분을 React의 useRef와 useEffect, useState를 사용해서 구현 해 줍니다.

 

App.jsx

import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'

import audioFile from './assets/background_music.weba'
import audioIcon from './assets/audio.svg'
import { useEffect, useRef, useState } from 'react';

function App() {
  const debug = process.env.NODE_ENV === 'development'?"solid":"none";

  const [isPlaying, setIsPlaying] = useState(false);
  const audioRef = useRef(null);
  const handleAudioToggle = () => {
    //버튼을 누르는 순간 load되게 만들어줌
    //미리 load할 경우 iphone에서 문제가 발생함
    if (!audioRef.current) {
      audioRef.current = new Audio(audioFile);
      audioRef.current.load()
      audioRef.current.addEventListener('ended', () => setIsPlaying(false));
    }
    if (isPlaying) {
      audioRef.current.pause();
    } else {
      audioRef.current.play();
    }
    setIsPlaying(!isPlaying);
  };
  useRef
  useEffect(() => {
    //페이지를 나갈 경우 음악이 종료되게 설정
    return () =>{
      if (audioRef.current){
        audioRef.current.pause();
        audioRef.current = null;
      }
    }
  }, [])


  return (
    <>
      <div className='main-frame'>
      <div style={{ border: debug, textAlign: 'right' }}>
          <img
            src={audioIcon} 
            width={"20px"} 
            style={{ marginRight: "10px", marginTop: "10px" }} 
            onClick={()=>handleAudioToggle()}
          />
        </div>
        <div style={{ border: debug}}>
          신랑/신부 이름 어디서 언제 결혼 표시 영역
        </div>
        <div style={{ border: debug}}>
          신랑/신부 대표 사진
        </div>
        <div style={{ border: debug}}>
          웰컴 문구
        </div>
        <div style={{ border: debug}}>
          달력
        </div>
        <div style={{ border: debug}}>
          이미지 갤러리
        </div>
        <div style={{ border: debug}}>
          결혼식 장소
        </div>
        <div style={{ border: debug}}>
          신랑신부 계좌 정보
        </div>
        <div style={{ border: debug}}>
          카카오톡 공유하기 / 모청 주소 복사하기
        </div>
      </div>
    </>
  )
}

export default App
 

그리고 vite 프로젝트에서 정상적으로 weba 파일을 재생시킬 수 있게

 

vite.config.js 파일을 조금 수정해줍니다

vite.config.js

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
  assetsInclude: ['**/*.weba'],
})
 

그리고 코드의 상태를 좀더 깔끔하게 관리하기 위해서

 

audio를 구현한 부분을 Audiocomp.jsx 파일로 꺼내줍니다.

 

Audiocomp.jsx

import audioFile from './assets/background_music.weba'
import audioIcon from './assets/audio.svg'
import { useEffect, useRef, useState } from 'react';
const Audiocomp = () => {
    const [isPlaying, setIsPlaying] = useState(false);
    const audioRef = useRef(null);
    const handleAudioToggle = () => {
    //버튼을 누르는 순간 load되게 만들어줌
    //미리 load할 경우 iphone에서 문제가 발생함
    if (!audioRef.current) {
        audioRef.current = new Audio(audioFile);
        audioRef.current.load()
        audioRef.current.addEventListener('ended', () => setIsPlaying(false));
    }
    if (isPlaying) {
        audioRef.current.pause();
    } else {
        audioRef.current.play();
    }
    setIsPlaying(!isPlaying);
    };
    useEffect(() => {
    //페이지를 나갈 경우 음악이 종료되게 설정
        return () =>{
            if (audioRef.current){
            audioRef.current.pause();
            audioRef.current = null;
            }
        }
    }, [])
    return (
        <>
            <img
                src={audioIcon} 
                width={"20px"} 
                style={{ marginRight: "10px", marginTop: "10px" }} 
                onClick={()=>handleAudioToggle()}
            />
        </>
    )
}
export default Audiocomp
 

App.jsx

import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'

import audioFile from './assets/background_music.weba'
import audioIcon from './assets/audio.svg'
import { useEffect, useRef, useState } from 'react';
import Audiocomp from './Audiocomp'

function App() {
  const debug = process.env.NODE_ENV === 'development'?"solid":"none";

  


  return (
    <>
      <div className='main-frame'>
      <div style={{ border: debug, textAlign: 'right' }}>
          <Audiocomp/>
        </div>
        <div style={{ border: debug}}>
          신랑/신부 이름 어디서 언제 결혼 표시 영역
        </div>
        <div style={{ border: debug}}>
          신랑/신부 대표 사진
        </div>
        <div style={{ border: debug}}>
          웰컴 문구
        </div>
        <div style={{ border: debug}}>
          달력
        </div>
        <div style={{ border: debug}}>
          이미지 갤러리
        </div>
        <div style={{ border: debug}}>
          결혼식 장소
        </div>
        <div style={{ border: debug}}>
          신랑신부 계좌 정보
        </div>
        <div style={{ border: debug}}>
          카카오톡 공유하기 / 모청 주소 복사하기
        </div>
      </div>
    </>
  )
}

export default App

 

728x90
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함