diff --git a/README.md b/README.md index df34f41..2aaf488 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# live preview +https://recoded-bprm-turkey-few-2022.github.io/movie-project-bamya/ + + # Movie Project This is a movie database project, where it shows movies, their casts, ratings, trailers, related movies, genres, and so on. diff --git a/enjoy.png b/enjoy.png new file mode 100644 index 0000000..8e1dfa3 Binary files /dev/null and b/enjoy.png differ diff --git a/index.html b/index.html index a9f6ca7..b4dde51 100644 --- a/index.html +++ b/index.html @@ -4,15 +4,116 @@ - + - Movie + + + + + Movie -
+ + + +
- + + + + + + + diff --git a/no_image.jpg b/no_image.jpg new file mode 100644 index 0000000..db92a79 Binary files /dev/null and b/no_image.jpg differ diff --git a/script.js b/script.js index 4cd93d6..ecf24e0 100644 --- a/script.js +++ b/script.js @@ -3,14 +3,22 @@ const TMDB_BASE_URL = "https://api.themoviedb.org/3"; const PROFILE_BASE_URL = "http://image.tmdb.org/t/p/w185"; const BACKDROP_BASE_URL = "http://image.tmdb.org/t/p/w780"; -const CONTAINER = document.querySelector(".container"); +const CONTAINER = document.querySelector("#movies"); +const home = document.getElementById("home") +const genersNav = document.getElementById("genres") +const actors = document.getElementById("actors") +const searchForm = document.getElementById("searchForm") +const searchInput = document.getElementById("search") + // Don't touch this function please const autorun = async () => { const movies = await fetchMovies(); - renderMovies(movies.results); + + renderMoviesHxH(movies.results); }; + // Don't touch this function please const constructUrl = (path) => { return `${TMDB_BASE_URL}/${path}?api_key=${atob( @@ -18,17 +26,43 @@ const constructUrl = (path) => { )}`; }; +// generate the genres url +const genresUrl = (genreId) => { + return `${TMDB_BASE_URL}/discover/movie?api_key=${atob('NTQyMDAzOTE4NzY5ZGY1MDA4M2ExM2M0MTViYmM2MDI=')}&sort_by=popularity.desc&with_genres=${genreId}`; +} + +// generate the search url +const searchUrl = (search) => { + return `${TMDB_BASE_URL}/search/multi?api_key=${atob('NTQyMDAzOTE4NzY5ZGY1MDA4M2ExM2M0MTViYmM2MDI=')}&query=${search}`; +} + + + // You may need to add to this function, definitely don't delete it. const movieDetails = async (movie) => { const movieRes = await fetchMovie(movie.id); renderMovie(movieRes); + }; +const fetchTrailer = async (id) => { + const url = constructUrl(`movie/${id}/videos`); + const res = await fetch(url); + const data = await res.json() + // console.log(data) + for ( let i in data.results){ + if(data.results[i].name === 'Official Trailer'){ + return data.results[i].key + } + } +} // This function is to fetch movies. You may need to add it or change some part in it in order to apply some of the features. const fetchMovies = async () => { const url = constructUrl(`movie/now_playing`); const res = await fetch(url); - return res.json(); + const data = await res.json(); + return data; + }; // Don't touch this function please. This function is to fetch one movie. @@ -38,44 +72,609 @@ const fetchMovie = async (movieId) => { return res.json(); }; -// You'll need to play with this function in order to add features and enhance the style. + +// generate the list of movies for one genre +const genreFilter = async (genreId) => { + const url = genresUrl(genreId) + const response = await fetch(url) + const data = await response.json() + renderMovies(data.results) +} + + +// fetch the genres object +const fetchGenres = async () => { + const url = constructUrl(`/genre/movie/list`); + const res = await fetch(url); + const data = await res.json() + return data['genres'] +} + + +// fetch the movie genre +const getGenre = async (ida) => { + const res = await fetchGenres(); + for (let i in res) { + if (res[i].id === ida) { + return res[i].name + } + } + +} + + + + +// + + + + +//fetching actors +const fetchActors = async () => { + const url = constructUrl(`person/popular`); + const res = await fetch(url); + const data = await res.json() + return data.results +} + +// fetch one actor details object +const fetchActor = async (actorId) => { + const url = constructUrl(`person/${actorId}`); + const res = await fetch(url); + const data = await res.json() + return data +} + +// display one actor details on page +const actorDetails = async (actor) => { + const actorDetail = await fetchActor(actor.id); + console.log(actorDetail) + renderActor(actorDetail); +}; + + + +// adding genres to navbar + +const genresUl = async () => { + const genres = await fetchGenres() + const genresList = document.createElement("ul") + genresList.classList.add("dropdown-menu") + genresList.setAttribute("aria-labelledby", "navbarDropdown") + + // looping through the genres array and creating list items + for (let i in genres) { + const li = document.createElement("li") + li.classList.add("dropdown-item") + li.innerHTML = genres[i]['name'] + genresList.appendChild(li) + // on click event for each list item fetch the movies for that genre + li.addEventListener('click', () => { + genreFilter(genres[i].id) + }) + + } + genersNav.appendChild(genresList) +} +genresUl() + + +// search movie + +//fetch results + +const searchRes = async (value) => { + const url = searchUrl(value) + const res = await fetch(url) + const data = await res.json() + return data.results +} + + +// search on submit + +searchForm.addEventListener("submit", async (e) => { + e.preventDefault + const results = await searchRes(searchInput.value) + renderMovies(results) +}) + + +// getting genres for each movie and creting span for each genre +async function getGenr(movie) { + let genreSpan = document.createElement("div") + for (let i in movie.genre_ids) { + const res = await getGenre(movie.genre_ids[i]) + const span = document.createElement("span") + span.innerHTML = res + " | " + genreSpan.appendChild(span) + } + return genreSpan; +} + + +// rendering movies from an array of objects const renderMovies = (movies) => { - movies.map((movie) => { - const movieDiv = document.createElement("div"); - movieDiv.innerHTML = ` - ${
-      movie.title
-    } poster -

${movie.title}

`; - movieDiv.addEventListener("click", () => { + CONTAINER.innerHTML = "" + const mainContainer = document.createElement("div"); + mainContainer.classList.add("row", "justify-content-center") + movies.map(async (movie) => { + console.log(movie); + let genr = await getGenr(movie) + let imagePath = "/no_image.jpg"; + if (movie.backdrop_path !== null) + imagePath = BACKDROP_BASE_URL + movie.backdrop_path; + + const movieCard = document.createElement("div"); + movieCard.classList.add("mainCard") + + const genres = document.createElement("span") + movieCard.innerHTML = ` + ${movie.title
+      } poster  + +
+
${movie.title}
+ ratings: ${movie.vote_average}/10 +

genre: ${genr.innerHTML}

+
`; + const cardBody = document.querySelector(".mainCard .cardBody") + movieCard.addEventListener("click", () => { movieDetails(movie); }); - CONTAINER.appendChild(movieDiv); + movieCard.classList.add("col-md-5", "col-lg-3", "card", "p-0") + mainContainer.appendChild(movieCard); + CONTAINER.appendChild(mainContainer) }); }; -// You'll need to play with this function in order to add features and enhance the style. -const renderMovie = (movie) => { - CONTAINER.innerHTML = ` -
-
- +// home page + +const renderMoviesHxH = (movies) => { + CONTAINER.innerHTML = "" + const post = document.createElement("div") + + post.innerHTML = ` + + ` + const popBar = document.createElement("div") + popBar.innerHTML = ` +
+

Now Playing

+
+ ` + CONTAINER.appendChild(post) + CONTAINER.appendChild(popBar) + const mainContainer = document.createElement("div"); + mainContainer.classList.add("row", "justify-content-center") + movies.map(async (movie) => { + + let genr = await getGenr(movie) + let imagePath = "/no_image.jpg"; + if (movie.backdrop_path !== null) + imagePath = BACKDROP_BASE_URL + movie.backdrop_path; + + const movieCard = document.createElement("div"); + movieCard.classList.add("mainCard") + + const genres = document.createElement("span") + movieCard.innerHTML = ` + ${movie.title
+      } poster  + +
+
${movie.title}
+ ratings: ${movie.vote_average}/10 +

genre: ${genr.innerHTML}

+
`; + const cardBody = document.querySelector(".mainCard .cardBody") + movieCard.addEventListener("click", () => { + movieDetails(movie); + }); + movieCard.classList.add("col-md-5", "col-lg-3", "card", "p-0") + mainContainer.appendChild(movieCard); + CONTAINER.appendChild(mainContainer) + }); +}; + + +// render actor details +// actors page + +const renderActors = (movies) => { + CONTAINER.innerHTML = "" + const mainContainer = document.createElement("div"); + mainContainer.classList.add("row", "justify-content-center") +// looping through the actors array and creating cards for each actor + movies.map((movie) => { + console.log(movie) + + let imagePath = "/no_image.jpg"; + if (movie.profile_path !== null) + imagePath = PROFILE_BASE_URL + movie.profile_path; + + + const movieCard = document.createElement("div"); + movieCard.innerHTML = ` + ${movie.name
+      } poster  + +
+
${movie.name}
+ popularity: ${movie.popularity}/10 +
`; + + // calling the actor details function on click + movieCard.addEventListener("click", () => { + actorDetails(movie); + }); + movieCard.classList.add("col-md-5", "col-lg-3", "card", "p-0") + movieCard.classList.add("mainCard") + mainContainer.appendChild(movieCard); + CONTAINER.appendChild(mainContainer) + }); +}; + + + +// click event for each actor card +actors.addEventListener("click", async () => { + const movies = await fetchActors() + renderActors(movies) +}) + + +// get related movies +const movieRelated = async (id) => { + const url = constructUrl(`movie/${id}/similar`) + const res = await fetch(url) + const data = await res.json() + const arrOfResults = data.results + // desplay related movies + for (let i = 0; i < 5; i++) { + let imagePath = "/no_image.jpg"; + if (arrOfResults[i].backdrop_path !== null) { + imagePath = BACKDROP_BASE_URL + arrOfResults[i].backdrop_path; + } + + const movieCard = document.createElement("div"); + movieCard.innerHTML = ` + ${arrOfResults[i].title
+      } poster  + +
+
${arrOfResults[i].title}
+ popularity: ${arrOfResults[i].popularity}/10 +
`; + movieCard.classList.add("col-md-5", "col-lg-3", "card", "p-0") + movieCard.classList.add("mainCard") + knownForR.appendChild(movieCard) + + movieCard.addEventListener("click", () => { + actorDetails(arrOfResults[i]); + console.log(movie) + }); + + } +} + +// getting the director for a specific movie + +const director = async (id) => { + const url = constructUrl(`movie/${id}/credits`) + const res = await fetch(url) + const data = await res.json() + const arrOfResults = data.crew + + + for (let i in data["crew"]) { + if (data["crew"][i].known_for_department === 'Directing') { + return data["crew"][i].name + } + } +} + + +// get movie cast + +const movieCredits = async (id) => { + const url = constructUrl(`movie/${id}/credits`) + const res = await fetch(url) + const data = await res.json() + const arrOfResults = data['cast'] + console.log(data) + + const knownFor = document.getElementById("knownForM") + const dir = document.getElementById("director") + + // displaying the cast on the DOM + for (let i = 0; i < 5; i++) { + + let imagePath = "/no_image.jpg"; + if (arrOfResults[i].profile_path !== null) + imagePath = PROFILE_BASE_URL + arrOfResults[i].profile_path; + + const movieCard = document.createElement("div"); + movieCard.innerHTML = ` + ${arrOfResults[i].title
+      } poster  + +
+
${arrOfResults[i].name}
+ popularity: ${arrOfResults[i].popularity}/10 +
`; + movieCard.classList.add("col-md-5", "col-lg-2", "card", "p-0") + movieCard.classList.add("mainCard") + knownFor.appendChild(movieCard) + // display the actor page on click + movieCard.addEventListener("click", () => { + actorDetails(arrOfResults[i]); + }); + + } +} + + +// display one movie details on the DOM +const renderMovie = async (movie) => { + console.log(movie.id); + let ddd = await director(movie.id) + const trailer = await fetchTrailer(movie.id) + + CONTAINER.innerHTML = ` +
+
+ + +

${movie.title}

-

Release Date: ${ - movie.release_date - }

+

Release Date: ${movie.release_date + }

Runtime: ${movie.runtime} Minutes

+

director:

+

${ddd}

Overview:

${movie.overview}

-

Actors:

-
    +
    +

    Actors:

    +
    +
    + + +
    `; + const movieBg = document.getElementById("movie"); + movieCredits(movie.id) + movieRelated(movie.id) +}; + +// display one actor details on the DOM +const renderActor = (actor) => { + console.log(actor) + CONTAINER.innerHTML = "" + CONTAINER.innerHTML = ` +
    +
    + +
    +
    +

    ${actor.name}

    +

    Gender:

    +

    ${actor.gender == 1 ? "famale" : "male"}

    +

    Popularity:

    +

    ${actor.popularity}

    +

    Birthday:

    +

    ${actor.birthday}

    +

    Deathday:

    +

    ${actor.deathday}

    + +

    Biography:

    +

    ${actor.biography}

    +
    +
    +

    Related Movies:

    +
    +
    +
    + ` + + if (actor.deathday === null) { + document.getElementById("deathday").remove() + document.getElementById("deathH").remove() + } + credits(actor.id) }; +// get movies by specific actor +const credits = async (id) => { + const url = constructUrl(`person/${id}/movie_credits`) + const res = await fetch(url) + const data = await res.json() + const arrOfResults = data['cast'] + const knownFor = document.getElementById("knownFor") + for (let i = 0; i < 5; i++) { + let imagePath = "/no_image.jpg"; + if (arrOfResults[i].backdrop_path !== null) { + imagePath = BACKDROP_BASE_URL + arrOfResults[i].backdrop_path; + const movieCard = document.createElement("div"); + movieCard.innerHTML = ` + ${arrOfResults[i].title
+        } poster  +
    +
    ${arrOfResults[i].title}
    + ratings: ${arrOfResults[i].vote_average}/10 +
    `; + movieCard.classList.add("col-md-5", "col-lg-3", "card", "p-0") + movieCard.classList.add("mainCard") + knownFor.appendChild(movieCard) + + movieCard.addEventListener("click", () => { + movieDetails(arrOfResults[i]); + }); + } + + } + +} document.addEventListener("DOMContentLoaded", autorun); +home.addEventListener("click", autorun) + + + + + +/*filter section*/ + + +const filtersNav = document.getElementById("filter") + +// by popularity +const filterPopular = async () => { + const url = constructUrl(`movie/popular`); + const res = await fetch(url); + const data = await res.json(); + renderMovies(data.results); +} + +const popular_movies = document.getElementById("popularmovies") +popularmovies.addEventListener("click", filterPopular) + + +//by latest + +const filterrelasedate = async () => { + const url = constructUrl(`movie/latest`); + const res = await fetch(url); + const data = await res.json(); + renderMovie(data) +} + +const last_relesed = document.getElementById("relasedatemovies") +relasedatemovies.addEventListener("click", filterrelasedate) + +//by top_rated + +const filterToprated = async () => { + const url = constructUrl(`movie/top_rated`); + const res = await fetch(url); + const data = await res.json(); + renderMovies(data.results); +} + +const top_rated = document.getElementById("topratedmovies") +topratedmovies.addEventListener("click", filterToprated) + +//Now_plating + +const filterNowplaying = async () => { + const url = constructUrl(`movie/now_playing`); + const res = await fetch(url); + const data = await res.json(); + renderMovies(data.results); +} + +const now_playing = document.getElementById("nowplayingmovies") +nowplayingmovies.addEventListener("click", filterNowplaying) + +//Up_coming + +const filterUpcoming = async () => { + const url = constructUrl(`movie/upcoming`); + const res = await fetch(url); + const data = await res.json(); + renderMovies(data.results); +} + +const Upcoming_movies = document.getElementById("upcomingmovies") +upcomingmovies.addEventListener("click", filterUpcoming) + + + +// About section +const about = document.getElementById("about") +about.addEventListener("click",() => { + + CONTAINER.innerHTML =` +
    + +
    + +
    + +
    + +
    + about image +
    + +
    + +
    Project detail
    + +

    This project was made by two young students who have the ambition + for coding during Re:Coded Bootcamp for front-end development. The main goal of this + project is to pull data from The Movie DB API and display it on the website. You can check + the movie list from the main page and you can also choose the movies you like. There is + great information about actors and the latest movies etc. on the website, so we recommend + you to take a deeper look and explore the movies. we would like to hear from you about your + experience.

    + +
      + +
    • +

      Date

      +

      29.05.2022

      +
    • + +
    • +

      Programming language

      +

      HTML, CSS, Javascript

      +
    • + +
    • +

      By

      +

      Mohamad AGHİ & Kemal DAVUT

      +
    • + +
    + +
    + +
    + +
    + +
    + +
    + ` +}) + diff --git a/style.css b/style.css index d74a3de..11cbd4d 100644 --- a/style.css +++ b/style.css @@ -2,10 +2,363 @@ width: 100%; } -.container { - padding-top: 32px; +body { + background-color: hsl(222deg 25% 10%) !important; + font-family: 'Courgette', cursive; +} +nav { + background-color: hsl(222deg 25% 10%) !important; +} +nav li a { + color: white !important; + margin-left: 20px; +} +#filter > div > a { + color: black !important; + margin: 0; +} +.container { + /* margin-top: 80px; */ + } + +#search { + background-color: rgb(34, 55, 94); + border: 0ch; +} +#search::placeholder{ + color: white; +} +#search + button { + background-color: rgb(34, 55, 94); + border: 0ch; + color: aliceblue; +} +#movie, +#single-actor-page { + position: relative; + padding: 0px 0 !important; + width: 90%; + color: #bdc9df !important; + margin-bottom: 40px !important; +} +#movie-backdrop{ + width: 100%; + position: absolute; + z-index: -1; + top: 0; + left: 0; +} +#movieText{ + padding: 20px ; + width: 40%; + z-index: 1; + /* background-color: rgba(255, 255, 255, 0.131); */ + /* backdrop-filter: blur(5px); */ + +} +.shadow { + position: absolute; + z-index: 0; + width: 80%; + height: 100%; + /* background: hsl(222deg 25% 10%); */ + opacity: 0.7; + background: linear-gradient(90deg, hsl(222deg 25% 10%) 39%, rgba(0, 0, 0, 0.5074404761904762) 48%, rgba(0, 0, 0, 0) 72%, rgba(0, 0, 0, 0) 100%); + } + iframe{ + margin: 30px auto; + width: 73%; + height: 500px; + position: relative; + left: 50%; + transform: translateX(-50%); + /* position: absolute; */ + + + } +.row { + width: 100%; + margin: 0 auto; +} +div > img { + width: 100%; + border-radius: inherit; +} +.mainCard{ + position: relative ; + overflow: hidden; + margin: 10px 10px; + outline: 0; + border:0; + transition-duration: 0.5s ; +} +.mainCard > div{ + display: flex; + align-items: center; + flex-direction: column; + justify-content: center; + position: absolute; + height: 100%; +/* bottom: -555px; */ +/* bottom: 0; */ +opacity: 0; +/* text-align: center; */ +width: 100%; +color: rgb(255, 255, 255); +transition-duration: 0.5s ; +font-size: 18px; +background-color: rgba(255, 255, 255, 0.124); +} +.mainCard img{ + transition-duration: 0.5s ; +} + +h3 { + font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; + +} + +.mainCard h5{ + font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; + margin: 0; + margin-bottom: 5px; + font-size: larger; } +.mainCard:hover > div { +/* top: 50%; +transform: translateY(-50%); */ +/* bottom: 0; */ +opacity: 1; +} + +.mainCard:hover img { + transform: scale(1.3); + filter: blur(5px); +} +.mainCard:hover{ + cursor: pointer; + /* box-shadow: rgba(0, 0, 0, 0.56) 0px 22px 70px 4px; */ +} + +.container:nth-child(2) + #actors { margin: 24px 16px 0 0; -} \ No newline at end of file +} +/* navbar */ +/*navbar sections hovver*/ +.navbarsections:hover{ + transform: scale(1.1); + -webkit-transform: scale(1.1); + background-color: rgb(34, 55, 94); + border-radius: 10px; +} + +/* single movie */ + +#movie { + display: flex; + flex-direction: row; + color: white; + margin: 69px auto; + /* background-color: rgb(34, 55, 94); */ + border-radius: 10px; + padding: 15px; + border-radius: 10px; +} +#movie img { + width: 100%; + height: 100%; + opacity: .7; + border-radius: 10px +} + +@media (max-width : 767px) { + #movie { + flex-direction: column; + } + #movieText { + width: 100%; + } + .shadow { + width: 100%; + background: linear-gradient(90deg, hsl(222deg 25% 10%) 39%, rgba(0, 0, 0, 0.654) 48%, rgba(0, 0, 0, 0.485) 72%, rgba(0, 0, 0, 0) 100%); + } +} + + + + +/*footer css */ + +/*footer*/ +#footer{ + margin-top: 30px; ; + height: 70px; + color: hsl(222deg 25% 10%); + background-image: linear-gradient(to right top, #131720, #161d2b, #192336, #1b2942, #1e2f4e, #223457, #263861, #2b3d6a, #334173, #3c457b, #464984, #504c8c);} + +/*social media position*/ +.socaialmedsection{ + padding-top: 10px; +} + +.navbarsections { + transition: .3s; +} + +/*social media icons*/ +.socaialmediabutton { + width: 25px; + height: 25px; + padding-left: 5px; + position: relative; + transition-duration: 0.3s; + cursor: pointer; +} +/*social media icons hover*/ +.socaialmediabutton:hover{ + transform: scale(1.2); + -webkit-transform: scale(1.1); +} + + + +.banner { + + margin-top: 60px; + margin-bottom: 60px; +} + +.banner-card { + margin: 0 auto; + width: 80%; + position: relative; + height: 400px; + overflow: hidden; + border-radius: 20px; + cursor: pointer; +} + +.banner-img { + /* object-position: bottom; */ +transition-duration: .5s; +} + +.banner-card:hover .banner-img { transform: scale(1.1); +filter: blur(5px); } + +.banner-card .card-content { + color: rgb(10, 0, 86); + position: absolute; + right: 80px; + bottom: 60px; + left: 80px; +} + +.banner-card .card-info { + display: flex; + align-items: center; + margin-bottom: 20px; +} + +.banner-card .card-info div { + display: flex; + align-items: center; + margin-right: 20px; +} + + + +.banner-card .card-info span { font-weight: var(--fw-6); } + +.banner-card .card-info .quality { + background: var(--azure); + padding: 2px 5px; + border-radius: 5px; + font-weight: var(--fw-7); +} + +.banner-card .card-title { + font-size: 3em; + color: var(--white); + text-shadow: 2px 0 2px #0007; +} + +.filter-bar { + color: white; + display: flex; + width: 79%; + margin: 0 auto; + justify-content: center; + align-items: center; + background: hsla(218, 39%, 14%, 0.8); + padding: 20px 30px; + border-radius: 20px; + margin-bottom: 30px; + } + .actors, + .related { + display: flex; + flex-direction:column; + align-items: center; + justify-content: center; + margin-bottom: 30px; + color: white; + } + .actors h3, + .related h3, + #moviesBy { + + margin: 0 auto 40px auto !important; + background-color: rgb(34, 55, 94); + width: 89%; + text-align: center; + padding: 20px; + border-radius: 10px; + } + + #actor-backdrop { + width: 100%; + height: 100%; + background-size: cover; + background-position: center; + background-repeat: no-repeat; + background-color: rgb(34, 55, 94); + border-radius: 20px; + transition-duration: 0.5s; + /* background: linear-gradient(90deg, hsl(222deg 25% 10%) 39%, rgba(0, 0, 0, 0.5074404761904762) 48%, rgba(0, 0, 0, 0) 72%, rgba(0, 0, 0, 0) 100%); */ + + } + + #actor-text { + margin-top: 10px; + } + + + #knownForM, + #knownForR { + display: flex; + flex-direction:row; + /* align-items: center; */ + justify-content: center; + margin-bottom: 30px; + } + + /*about diz and background img*/ + #aboutDiv { background-color: hsl(222deg 25% 10%) !important; + color: white !important; + + } + #aboutDiv img { + transform: scale(0.7); + filter: blur(2px); + + } + + @media (max-width : 768px) { + #hxh { + display: none; + } + } \ No newline at end of file