[실전 프로젝트] ASMR 페이지 구현
본문 바로가기
항해 중/8-13주차 실전 프로젝트

[실전 프로젝트] ASMR 페이지 구현

by 은돌1113 2021. 12. 30.

오늘 한 일

  1. 카테고리별로 해당 카테고리에 맞는 음원 출력
  2. 각 음원을 눌렀을 때 활성화 되면서 최대 3개까지 선택 가능
  3. 활성화된 음원을 다시 누르면 비활성화 시키기
  4. 음원 하나라도 활성화 되면 음량 조절 버튼 나오기
  5. 음원 하나라도 활성화 되면 음원 play 되도록

기능 구현

 

1. Asmr.js 페이지에서 각 카테고리를 누를 때마다 활성화/비활성화 설정

2. 음원 선택하면 활성화 / 비활성화 구현 + 3개까지만 선택 가능

  const select = (categoryIdx, asmrUrl) => {
    if (play.includes(asmrUrl)) {
      // 비활성화
      let arr = [...play];
      arr = arr.filter((item) => {
        if (asmrUrl !== item) {
          return item;
        }
      });
      setPlay(arr);

      // 선택한 음원 비활성화 style
      const deleteItem = document.getElementById(categoryIdx);
      deleteItem.style.backgroundColor = "gray";

      // 음원 재생 중지 시킴
      soundPause(asmrUrl);
    } else {
      // 활성화
      if (play.length > 2) {
        window.alert("음원은 3개까지만 담으실 수 있습니다.");
      } else {
        const arr = [...play, asmrUrl];
        setPlay(arr);

        // 선택한 음원 활성화 style
        const selectItem = document.getElementById(categoryIdx);
        selectItem.style.backgroundColor = "#dddddd";

        // 음원 재생 시킴
        soundPlay(asmrUrl);
      }
    }
  };

 

3. 음원 재생 / 중지 시키는 함수 생성해서 필요한 부분에 호출해서 사용함.

→ 서버에서 .mp3 데이터 받아 왔을 때 테스트 해봐야 할 것 같다. 또는 .mp3 파일을 다운로드 받아서 src에 넣어놓고 테스트 해보면 될 것 같다.

  // 음원 재생
  const soundPlay = (asmrUrl) => {
    const audio = new Audio(asmrUrl); // Audio 객체를 생성해서 음악을 재생한다.
    audio.loop = true; // 반복재생 여부
    audio.volume = 1; // 볼륨
    audio.play(); // 음원 재생
  };

  // 음원 중지
  const soundPause = (asmrUrl) => {
    const audio = new Audio(asmrUrl);
    audio.pause(); // 음원 재생 중지
  };

 

음원 재생 참고 사이트

https://stackoverflow.com/questions/9419263/how-to-play-audio

 

How to play audio?

I am making a game with HTML5 and JavaScript. How could I play game audio via JavaScript?

stackoverflow.com

 

전체 코드 (Asmr.js)

더보기
더보기
import React from "react";
import styled from "styled-components";
import { useDispatch, useSelector } from "react-redux";
import { useHistory } from "react-router-dom";
import { actionCreators as asmrActions } from "../redux/modules/asmr";

const Asmr = ({ location }) => {
  const [getCategory, setCategory] = React.useState(
    location.category ? location.category : "전체"
  );
  const [sound, setSound] = React.useState([]);
  const history = useHistory();
  const dispatch = useDispatch();
  const asmrInfo = useSelector((state) => state.asmr.asmrList);
  const [play, setPlay] = React.useState([]);

  React.useEffect(() => {
    // 1) 카테고리별 활성화 유무
    const arr = ["전체", "자연", "공간", "물체"];

    arr.forEach((arrItem) => {
      if (arrItem !== getCategory) {
        // 비활성화
        document.getElementById(arrItem).style.color = "black";
      }
      document.getElementById(getCategory).style.color = "white"; // 활성화
    });

    // 2) 음원 데이터 유무
    if (!asmrInfo) {
      dispatch(asmrActions.getAsmrDB());
    }

    // 3) 음원을 출력하기 전에 카테고리에 맞게 필터링
    if (getCategory === "전체") {
      const all = asmrInfo.filter((item) => {
        if (item.categoryName === "전체") {
          return item;
        }
      });
      setSound(all);
    } else if (getCategory === "자연") {
      const nature = asmrInfo.filter((item) => {
        if (item.categoryName === "자연") {
          return item;
        }
      });
      setSound(nature);
    } else if (getCategory === "공간") {
      const place = asmrInfo.filter((item) => {
        if (item.categoryName === "공간") {
          return item;
        }
      });
      setSound(place);
    } else if (getCategory === "물체") {
      const object = asmrInfo.filter((item) => {
        if (item.categoryName === "물체") {
          return item;
        }
      });
      setSound(object);
    }

    // 4) 카테고리가 바뀌면 활성화된 음원 초기화
    setPlay([]);
  }, [getCategory]);

  const select = (categoryIdx, asmrUrl) => {
    if (play.includes(asmrUrl)) {
      // 비활성화
      let arr = [...play];
      arr = arr.filter((item) => {
        if (asmrUrl !== item) {
          return item;
        }
      });
      setPlay(arr);

      // 선택한 음원 비활성화 style
      const deleteItem = document.getElementById(categoryIdx);
      deleteItem.style.backgroundColor = "gray";

      // 음원 재생 중지 시킴
      soundPause(asmrUrl);
    } else {
      // 활성화
      if (play.length > 2) {
        window.alert("음원은 3개까지만 담으실 수 있습니다.");
      } else {
        const arr = [...play, asmrUrl];
        setPlay(arr);

        // 선택한 음원 활성화 style
        const selectItem = document.getElementById(categoryIdx);
        selectItem.style.backgroundColor = "#dddddd";

        // 음원 재생 시킴
        soundPlay(asmrUrl);
      }
    }
  };

  // 음원 재생
  const soundPlay = (asmrUrl) => {
    const audio = new Audio(asmrUrl); // Audio 객체를 생성해서 음악을 재생한다.
    audio.loop = true; // 반복재생 여부
    audio.volume = 1; // 볼륨
    audio.play(); // 음원 재생
  };

  // 음원 중지
  const soundPause = (asmrUrl) => {
    const audio = new Audio(asmrUrl);
    audio.pause(); // 음원 재생 중지
  };

  return (
    <>
      <div
        onClick={() => {
          history.push("/");
        }}
      >
        ASMR 페이지
      </div>
      <div style={{ display: "flex", margin: "0px 40%" }}>
        <Category
          id="전체"
          onClick={() => {
            setCategory("전체");
          }}
        >
          전체
        </Category>
        <Category
          id="자연"
          onClick={() => {
            setCategory("자연");
          }}
        >
          자연
        </Category>
        <Category
          id="공간"
          onClick={() => {
            setCategory("공간");
          }}
        >
          공간
        </Category>
        <Category
          id="물체"
          onClick={() => {
            setCategory("물체");
          }}
        >
          물체
        </Category>
      </div>
      <div style={{ margin: "0px 40%", display: "flex", flexWrap: "wrap" }}>
        {sound.map((item) => {
          return (
            <Sound
              id={item.categoryIdx}
              key={item.categoryIdx}
              onClick={() => {
                select(item.categoryIdx, item.asmrUrl);
              }}
            >
              <p>{item.asmrUrl}</p>
              <p>{item.title}</p>
            </Sound>
          );
        })}
      </div>

      {play.length > 0 ? (
        <button
          onClick={() => {
            console.log("음원 url 가지고 이동!!!", play);
          }}
        >
          음량 조절 하러 가기
        </button>
      ) : null}
    </>
  );
};

const Category = styled.div`
  width: 100px;
  height: 50px;
  line-height: 50px;
  background-color: gray;
`;

const Sound = styled.div`
  width: 100px;
  height: 100px;
  background-color: gray;
  margin: 10px;
`;

export default Asmr;

+ indexOf 사용하기 (배열.indexOf(찾을 데이터)

const scoreList = ["1", "3", "5", "4", "2"];
feelNumber={scoreList.indexOf(item.feelScore) + 1}
sleepNumber={scoreList.indexOf(item.sleepScore) + 1}

댓글