혼자 이것저것 공부해보는/디즈니 앱 플러스 클론 코딩
비디오 배너 생성하기
silver님
2024. 6. 10. 18:21
1. Play 버튼 클릭 시 비디오로 전환
play를 누르면 해당 비디오를 틀어주는 부분
*Banner.js
const [isClicked, setIsClicked] = useState(false);
if(isClicked) {
return (
<div>
clicked
</div>
)
} else {
.
.
}
<button
className='banner__button play'
onClick={() => setIsClicked(true)}
>
Play
</button>
2. Styled Component를 이용한 UI 생성
*컨테이너
Banner.js
return (
<Container>
<HomeContainer>
clicked
</HomeContainer>
</Container>
);
const Container = styled.div`
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 100vh;
`;
const HomeContainer = styled.div`
width: 100%;
height: 100%;
`;
* Iframe
Iframe은 HTML inline Frame 요소이며, inline frame의 약자이다.
효과적으로 다른 HTML페이지를 현재 페이지에 포함시키는 중첩된 브라우저로 iframe요소를 이용하면
해당 웹 페이지 안에 어떠한 제한 없이 다른 페이지를 불러와서 삽입할 수 있다.
Banner.js
<HomeContainer>
<Iframe
src={`https://www.youtube.com/embed/${movie.videos.results[0].key}?controls=0&autoplay=1&loop=1&mute=1&playlist=${movie.videos.results[0].key}`}
width="640"
height="360"
frameborder="0"
allow="autoplay; fullscreen"
></Iframe>
</HomeContainer>
const Iframe = styled.iframe`
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.65;
border: none;
&::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
`;
3. 비디오 배너에서 이미지 배너로 돌아가기 버튼 생성
return (
<>
<Container>
<HomeContainer>
<Iframe
src={`https://www.youtube.com/embed/${movie.videos.results[0].key}?controls=0&autoplay=1&loop=1&mute=1&playlist=${movie.videos.results[0].key}`}
width="640"
height="360"
frameborder="0"
allow="autoplay; fullscreen"
></Iframe>
</HomeContainer>
</Container>
<button onClick={() => setIsClicked(false)}>X</button>
</>
* 로직 요약
- isClicked 상태에 따라 두 가지 다른 UI를 렌더링합니다:
- isClicked가 true일 때는 비디오 재생 화면과 X 버튼을 렌더링합니다.
- isClicked가 false일 때는 영화 정보 배너를 렌더링합니다.
- X 버튼을 클릭하면 setIsClicked(false)가 호출되어 isClicked가 false로 설정되며, 다시 홈 화면을 렌더링합니다.
* Banner.js
import React, { useEffect, useState } from 'react'
import axios from '../api/axios';
import requests from '../api/request';
import "./Banner.css";
import styled from 'styled-components';
const Banner = () => {
const [movie, setMovie] = useState([]);
const [isClicked, setIsClicked] = useState(false);
useEffect(() => {
fetchData();
}, [])
const fetchData = async() => {
// 현재 상영중인 영화 정보를 가져오기(여러 영화)
const response = await axios.get(requests.fetchNowPlaying);
// 여러 영화 중 영화 하나의 ID를 가져오기
const movieId = response.data.results[
Math.floor(Math.random() * response.data.results.length)
].id
// 특정 영화의 더 상세한 정보를 가져오기(비디오 정보도 포함)
const { data: movieDetail } = await axios.get(`movie/${movieId}`, {
params: { append_to_response: "videos" }
})
setMovie(movieDetail);
}
const truncate = (str, n) => {
return str?.length > n ? str.substring(0 , n) + "..." : str;
}
if(isClicked) {
return (
<>
<Container>
<HomeContainer>
<Iframe
src={`https://www.youtube.com/embed/${movie.videos.results[0].key}?controls=0&autoplay=1&loop=1&mute=1&playlist=${movie.videos.results[0].key}`}
width="640"
height="360"
frameborder="0"
allow="autoplay; fullscreen"
></Iframe>
</HomeContainer>
</Container>
<button onClick={() => setIsClicked(false)}>X</button>
</>
);
} else {
return (
<header
className='banner'
style={{
backgroundImage: `url("https://image.tmdb.org/t/p/original/${movie.backdrop_path}")`,
backgroundPosition: "top center",
backgroundSize: "cover"
}}
>
<div className='banner__contents'>
<h1 className='banner__title'>
{ movie.title || movie.name || movie.original_name }
</h1>
<div className='banner__buttons'>
{ movie?.videos?.results[0]?.key &&
<button
className='banner__button play'
onClick={() => setIsClicked(true)}
>
Play
</button>
}
</div>
<p className='banner__description'>
{ truncate(movie.overview, 100) }
</p>
</div>
<div className='banner--fadeBottom' />
</header>
)
}
}
export default Banner
const Container = styled.div`
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 100vh;
`;
const HomeContainer = styled.div`
width: 100%;
height: 100%;
`;
const Iframe = styled.iframe`
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.65;
border: none;
&::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
`;
728x90
반응형