├── images └── logo.png ├── screenshots ├── favicon.png ├── filter.png ├── homepage.png └── search.png ├── Readme.md ├── index.html ├── style.css └── script_main.js /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyjinchuriki/cinephile/HEAD/images/logo.png -------------------------------------------------------------------------------- /screenshots/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyjinchuriki/cinephile/HEAD/screenshots/favicon.png -------------------------------------------------------------------------------- /screenshots/filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyjinchuriki/cinephile/HEAD/screenshots/filter.png -------------------------------------------------------------------------------- /screenshots/homepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyjinchuriki/cinephile/HEAD/screenshots/homepage.png -------------------------------------------------------------------------------- /screenshots/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyjinchuriki/cinephile/HEAD/screenshots/search.png -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Cinephile 2 | [![Visit My Website](https://img.shields.io/badge/Visit%20My-Website-blue?style=for-the-badge&logo=arrow-right&logoColor=white)](https://lazyjinchuriki.github.io/cinephile/) 3 | 4 | Cinephile is a `Movies` and `TvShows` finder website that allows you to get an overview and trailer of popular movies and shows. You can even search for your favourite Movies and Shows and get an overview and trailer for them. 5 | 6 | The website is built with basic HTML, CSS, and vanilla JavaScript, and uses `TMDB API` to fetch data on movies and TV shows. 7 | 8 | ## Tech Stacks 9 | 10 | ![HTML5](https://img.shields.io/badge/-HTML5-E34F26?style=for-the-badge&logo=html5&logoColor=white) ![CSS3](https://img.shields.io/badge/-CSS3-1572B6?style=for-the-badge&logo=css3&logoColor=white) ![JavaScript](https://img.shields.io/badge/-JavaScript-F7DF1E?style=for-the-badge&logo=javascript&logoColor=black) 11 | 12 | ## Features 13 | 14 | Cinephile offers the following features: 15 | 16 | - Search for movies and TV shows 17 | - Get an overview and trailer for movies and TV shows 18 | - View popular movies and TV shows 19 | - View top-rated movies and TV shows 20 | - View upcoming movies 21 | - Filter out movies and shows based on genres 22 | - Go to next and previous page 23 | 24 | ## Installation 25 | 26 | To install Cinephile, follow these steps: 27 | 28 | 1. Download the source code from the repository: https://github.com/lazyjinchuriki/cinephile 29 | 2. Extract the files from the downloaded ZIP archive. 30 | 3. Open the `index.html` file in your web browser. 31 | 32 | ## Usage 33 | 34 | Once you have installed Cinephile, you can use it by opening `index.html` in your web browser. 35 | 36 | ## Screenshots 37 | 38 | Here are some screenshots of Cinephile in action: 39 | 40 | ![Homepage screenshot](/screenshots/homepage.png "Homepage") 41 | ![Search results screenshot](/screenshots/search.png "Search Result") 42 | ![Genre filter screenshot](/screenshots/filter.png "Genre Filtering") 43 | 44 | ## Credits 45 | 46 | Cinephile uses the following open source libraries: 47 | 48 | - TMDB API: https://www.themoviedb.org/documentation/api 49 | 50 | ## Contributing 51 | 52 | Contributions to Cinephile are always welcome. If you find any bugs or issues, please open an issue on GitHub or submit a pull request. 53 | 54 | ## Contact 55 | 56 | If you have any questions or concerns, you can contact the author of this project at [rahulkhushalani@proton.me](mailto:rahulkhushalani@proton.me). 57 | 58 | ### Donations 59 | 60 | If you found Gallery useful, consider buying me a coffee! 61 | 62 | 63 | 64 | 65 | 66 | ## Social 67 | 68 | If you're not coding right now, check out my socials: 69 | 70 | [![Instagram](https://img.shields.io/badge/Instagram-%40amundaneguy-E4405F?style=for-the-badge&logo=instagram&logoColor=white)](https://www.instagram.com/amundaneguy/) 71 | [![LinkedIn](https://img.shields.io/badge/LinkedIn-Rahul%20Khushalani-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/rahul-khushalani-77ab21201/) 72 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Movie&TV App 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 | 22 | 23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 | 31 | 43 | 44 | 47 | 48 | 49 | 50 | 51 |
52 | 53 |
54 | 55 | 56 |
57 |
58 | 66 | 71 | 72 |
73 | 74 |
75 | 76 |
77 | 85 | 90 | 91 |
92 |
93 | 94 | 95 |
96 | × 99 |
100 |
101 | 102 | 103 |
104 | 105 | 106 | 111 | 112 | 113 | 138 | 139 | 202 | 203 | 204 | 205 | 206 | 207 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap'); 2 | 3 | :root { 4 | --primary-color: #22254b; 5 | --secondary-color: #373b69; 6 | } 7 | 8 | * { 9 | box-sizing: border-box; 10 | } 11 | 12 | html{ 13 | scroll-behavior: smooth; 14 | } 15 | 16 | body { 17 | background-color: var(--primary-color); 18 | font-family: 'Poppins', sans-serif; 19 | margin: 0; 20 | } 21 | 22 | body::-webkit-scrollbar { 23 | width: 12px; 24 | } 25 | 26 | body::-webkit-scrollbar-thumb { 27 | height: 40px; 28 | background-color: #7378c5; 29 | border-radius: 10px; 30 | } 31 | 32 | body::-webkit-scrollbar-thumb:hover { 33 | background: #4d5293; 34 | } 35 | 36 | body::-webkit-scrollbar-track { 37 | box-shadow: inset 2px 2px 5px #2d2d2d; 38 | background-color: #eeeeee; 39 | } 40 | 41 | header { 42 | justify-content: space-between; 43 | padding: 1rem; 44 | display: flex; 45 | background-color: var(--secondary-color); 46 | } 47 | 48 | middle{ 49 | padding: 1rem; 50 | display: flex; 51 | justify-content: center; 52 | } 53 | .pageChange:hover{ 54 | cursor: pointer; 55 | } 56 | .switch { 57 | width: 50px; 58 | height: 50px; 59 | position: relative; 60 | border: 2px solid var(--primary-color); 61 | border-radius: 50%; 62 | font-family: inherit; 63 | padding: 0.5rem 0.5rem; 64 | outline: none; 65 | margin-right: 5%; 66 | } 67 | .switch:hover{ 68 | background-color: var(--primary-color); 69 | } 70 | 71 | /* for heading */ 72 | .animate-charcter 73 | { 74 | text-transform: uppercase; 75 | background-image: linear-gradient( 76 | -225deg, 77 | #231557 0%, 78 | #44107a 29%, 79 | #ff1361 67%, 80 | #fff800 100% 81 | ); 82 | background-size: auto auto; 83 | background-clip: border-box; 84 | background-size: 200% auto; 85 | color: #fff; 86 | background-clip: text; 87 | text-fill-color: transparent; 88 | -webkit-background-clip: text; 89 | -webkit-text-fill-color: transparent; 90 | animation: textclip 2s linear infinite; 91 | display: inline-block; 92 | font-size: 20px; 93 | } 94 | 95 | @keyframes textclip { 96 | to { 97 | background-position: 200% center; 98 | } 99 | } 100 | /* this is for flex container */ 101 | .flex-container { 102 | display: flex; 103 | align-items: center; 104 | justify-content: center; 105 | } 106 | .flex-container img { 107 | margin-left: 10px; 108 | } 109 | 110 | .search { 111 | width: 90%; 112 | position: relative; 113 | right: 4%; 114 | background-color: transparent; 115 | border: 2px solid var(--primary-color); 116 | border-radius: 45px; 117 | font-family: inherit; 118 | font-size: 1rem; 119 | padding: 0.5rem 1rem; 120 | color: #fff; 121 | margin-left: 5%; 122 | } 123 | 124 | .search::placeholder { 125 | color: #7378c5; 126 | } 127 | 128 | .search:focus { 129 | outline: none; 130 | background-color: var(--primary-color); 131 | } 132 | 133 | /*For any screens at or below 244px.*/ 134 | @media only screen and (max-width: 244px) { 135 | .search { 136 | width: 23vw; 137 | margin-top: 20px; 138 | } 139 | .flex-container { 140 | flex-direction: column; 141 | align-items: center; 142 | margin-top: -20px; 143 | } 144 | } 145 | 146 | /* For any screens between 245px and 309px. */ 147 | @media only screen and (min-width: 245px) and (max-width: 309px) { 148 | .search { 149 | width: 30vw; 150 | margin-top: 20px; 151 | } 152 | .flex-container { 153 | flex-direction: column; 154 | align-items: center; 155 | margin-top: -20px; 156 | } 157 | } 158 | 159 | /*For any screens between 310px and 380px. Devices such as iPhone SE*/ 160 | @media only screen and (min-width: 310px) and (max-width: 380px) { 161 | .search { 162 | width: 35vw; 163 | margin-top: 20px; 164 | } 165 | .flex-container { 166 | flex-direction: column; 167 | align-items: center; 168 | margin-top: -20px; 169 | } 170 | .flex-container img { 171 | margin-top: -20px; 172 | } 173 | } 174 | /*For any screens between 310px and 380px. Devices such as iPhone SE*/ 175 | @media only screen and (min-width: 380px) and (max-width: 500px) { 176 | .search { 177 | width: 36vw; 178 | margin-top: 20px; 179 | } 180 | .flex-container { 181 | flex-direction: column; 182 | align-items: center; 183 | margin-top: -20px; 184 | } 185 | .flex-container img { 186 | margin-top: -20px; 187 | } 188 | } 189 | 190 | /*For any screens between 500px and 599px. Devices such as Pixel 5 and Surface Duo.*/ 191 | @media only screen and (min-width: 500px) and (max-width: 599px) { 192 | .search { 193 | width: 50vw; 194 | margin-top: 20px; 195 | } 196 | .flex-container { 197 | flex-direction: column; 198 | align-items: center; 199 | margin-top: -20px; 200 | } 201 | .flex-container img { 202 | margin-top: -20px; 203 | } 204 | } 205 | 206 | /*For any screens at or above 600px. Enlarges search box to fit laptops, desktops, and TVs.*/ 207 | @media only screen and (min-width: 600px) { 208 | .search { 209 | width: 60vw; /*View Width to expand based on user's device width*/ 210 | } 211 | 212 | } 213 | @media only screen and (min-width: 900) { 214 | .search { 215 | width: 70vw; /*View Width to expand based on user's device width*/ 216 | } 217 | } 218 | 219 | main { 220 | display: flex; 221 | flex-wrap: wrap; 222 | justify-content: center; 223 | } 224 | 225 | .movie, .tvshow { 226 | width: 300px; 227 | margin: 1rem; 228 | background-color: var(--secondary-color); 229 | box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2); 230 | position: relative; 231 | overflow: hidden; 232 | border-radius: 3px; 233 | 234 | } 235 | .movie:hover, .tvshow:hover{ 236 | cursor: pointer; 237 | box-shadow: 0 8px 18px rgba(255, 255, 255, 0.5), 0 0 32px rgba(0, 0, 0, 0.3); 238 | transform: translateY(-20px); 239 | z-index: 2; 240 | transition: all 0.4s ease-in-out; 241 | } 242 | 243 | .tvshow { 244 | width: 300px; 245 | margin: 1rem; 246 | background-color: var(--secondary-color); 247 | box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2); 248 | position: relative; 249 | overflow: hidden; 250 | border-radius: 3px; 251 | } 252 | 253 | 254 | .movie img { 255 | width: 100%; 256 | transition: all 0.3s ease-in; 257 | } 258 | 259 | .tvshow img { 260 | width: 100%; 261 | transition: all 0.3s ease-in; 262 | } 263 | 264 | .movie-info { 265 | color: #eee; 266 | display: flex; 267 | align-items: center; 268 | justify-content: space-between; 269 | gap:0.2rem; 270 | padding: 0.5rem 1rem 1rem; 271 | letter-spacing: 0.5px; 272 | } 273 | 274 | .movie-info h3 { 275 | margin-top: 0; 276 | } 277 | 278 | .movie-info span { 279 | background-color: var(--primary-color); 280 | padding: 0.25rem 0.5rem; 281 | border-radius: 3px; 282 | font-weight: bold; 283 | } 284 | 285 | .movie-info span.green { 286 | color: lightgreen; 287 | } 288 | 289 | .movie-info span.orange { 290 | color: orange; 291 | } 292 | 293 | .movie-info span.red { 294 | color: red; 295 | } 296 | 297 | .releaseDate{ 298 | position: absolute; 299 | top: 4px; 300 | left: 4px; 301 | color: white; 302 | font-weight: bold; 303 | font-family: inherit; 304 | padding: 0.25rem 0.5rem; 305 | background-color: rgba(0, 0, 0, 0.63); 306 | border-radius: 3px; 307 | z-index: 0.9; 308 | } 309 | 310 | .overview { 311 | background-color: #fff; 312 | padding: 2rem; 313 | position: absolute; 314 | left: 0; 315 | bottom: 0; 316 | right: 0; 317 | max-height: 100%; 318 | transform: translateY(101%); 319 | overflow-y: auto; 320 | transition: transform 0.7s ease-in; 321 | } 322 | .overview::-webkit-scrollbar{ 323 | display: none; 324 | } 325 | 326 | .overview .overview-content { 327 | overflow: hidden; 328 | display: -webkit-box; 329 | -webkit-line-clamp: 10; 330 | line-clamp: 10; 331 | -webkit-box-orient: vertical; 332 | } 333 | 334 | .movie:hover img, .tvshow:hover img { 335 | filter: brightness(0.5); 336 | } 337 | 338 | .movie:hover .overview { 339 | transform: translateY(0); 340 | } 341 | 342 | .tvshow:hover .overview { 343 | transform: translateY(0); 344 | } 345 | 346 | 347 | 348 | 349 | .pagination{ 350 | display: flex; 351 | justify-content: center; 352 | margin: 10px 20px; 353 | align-items: center; 354 | color: white; 355 | 356 | } 357 | 358 | .page{ 359 | padding: 10px; 360 | cursor: pointer; 361 | font-family: inherit; 362 | font-size: 1rem; 363 | } 364 | .page:hover{ 365 | background-color: var(--secondary-color); 366 | border-radius: 20px; 367 | } 368 | 369 | .disabled{ 370 | cursor: not-allowed; 371 | color: grey; 372 | } 373 | 374 | .knowmore{ 375 | color: white; 376 | font-weight: bold; 377 | font-size: 14px; 378 | background-color: var(--secondary-color); 379 | border-radius: 50px; 380 | border: none; 381 | margin: 5px; 382 | padding: 15px 20px; 383 | display: inline-block; 384 | cursor: pointer; 385 | } 386 | 387 | .knowmore:hover{ 388 | background-color: var(--primary-color); 389 | } 390 | 391 | /* The Overlay (background) */ 392 | .overlay { 393 | /* Height & width depends on how you want to reveal the overlay (see JS below) */ 394 | height: 100%; 395 | width: 0; 396 | position: fixed; /* Stay in place */ 397 | z-index: 1; /* Sit on top */ 398 | left: 0; 399 | top: 0; 400 | background-color: rgb(0,0,0); /* Black fallback color */ 401 | background-color: rgba(0,0,0, 0.9); /* Black w/opacity */ 402 | overflow-x: hidden; /* Disable horizontal scroll */ 403 | transition: 0.5s; /* 0.5 second transition effect to slide in or slide down the overlay (height or width, depending on reveal) */ 404 | } 405 | 406 | /* Position the content inside the overlay */ 407 | .overlay-content { 408 | position: relative; 409 | top: 15%; /* 25% from the top */ 410 | width: auto !important; /* 100% width */ 411 | height: auto !important; 412 | text-align: center; /* Centered text/links */ 413 | max-width: 1080px; 414 | margin: 0 auto; /* centered the wraper */ 415 | margin-top: 30px; /* 30px top margin to avoid conflict with the close button on smaller screens */ 416 | } 417 | 418 | /* The navigation links inside the overlay */ 419 | .overlay a { 420 | padding: 8px; 421 | text-decoration: none; 422 | font-size: 36px; 423 | color: #818181; 424 | display: block; /* Display block instead of inline */ 425 | transition: 0.3s; /* Transition effects on hover (color) */ 426 | } 427 | 428 | /* When you mouse over the navigation links, change their color */ 429 | .overlay a:hover, .overlay a:focus { 430 | color: #f1f1f1; 431 | } 432 | 433 | /* Position the close button (top right corner) */ 434 | .overlay .closebtn { 435 | position: absolute; 436 | top: 20px; 437 | right: 45px; 438 | font-size: 60px; 439 | } 440 | 441 | /* When the height of the screen is less than 450 pixels, change the font-size of the links and position the close button again, so they don't overlap */ 442 | @media screen and (max-height: 450px) { 443 | .overlay a {font-size: 20px} 444 | .overlay .closebtn { 445 | font-size: 40px; 446 | top: 15px; 447 | right: 35px; 448 | } 449 | } 450 | 451 | 452 | .embed.hide{ 453 | display: none; 454 | } 455 | 456 | .embed.show{ 457 | display: inline-block; 458 | } 459 | 460 | .video-container { 461 | position: relative; 462 | padding-bottom: 56.25%; /* 16:9 */ 463 | height: 0; 464 | } 465 | .video-container iframe { 466 | position: absolute; 467 | top: 0; 468 | left: 0; 469 | width: 100%; 470 | height: 100%; 471 | } 472 | 473 | .scrollable-tabs-container:hover{ 474 | cursor: pointer; 475 | } 476 | 477 | 478 | 479 | 480 | 481 | 482 | .scrollable-tabs-container{ 483 | max-width: 100%; 484 | margin: 16px auto; 485 | border-radius: 5px; 486 | overflow: hidden; 487 | position: relative; 488 | 489 | } 490 | 491 | .scrollable-tabs-container svg{ 492 | width: 40px; 493 | height: 40px; 494 | padding: 8px; 495 | cursor: pointer; 496 | color: white; 497 | border-radius: 50%; 498 | pointer-events: auto; 499 | 500 | } 501 | 502 | #tags{ 503 | display: flex; 504 | gap: 16px; 505 | padding: 12px 24px; 506 | margin: 0; 507 | list-style: none; 508 | overflow-x: scroll; 509 | -ms-overflow-style: none; 510 | scrollbar-width: none; 511 | scroll-behavior: smooth; 512 | } 513 | /* Genres - Animation on hover */ 514 | #tags div{ 515 | transition: 0.3s all; 516 | } 517 | 518 | #tags div:hover{ 519 | background-color: white; 520 | color: #231557; 521 | transform: scale(1.1); 522 | transition: 0.3s all; 523 | } 524 | 525 | #tags.dragging{ 526 | scroll-behavior: auto; 527 | } 528 | /* .scrollable-tabs-container ul.dragging a{ 529 | pointer-events: none; 530 | } */ 531 | 532 | #tags::-webkit-scrollbar{ 533 | display: none; 534 | } 535 | 536 | .scrollable-tabs-container .tag { 537 | color: white; 538 | text-decoration: none; 539 | background: var(--secondary-color); 540 | padding: 4px 24px; 541 | display: inline-block; 542 | border-radius: 4px; 543 | user-select: none; 544 | white-space: nowrap; 545 | cursor: pointer; 546 | } 547 | 548 | .scrollable-tabs-container .tag.active{ 549 | background-color: rgba(255, 255, 255, 0.508); 550 | font-weight: bold; 551 | color: rgba(0, 0, 0, 0.757); 552 | } 553 | 554 | .scrollable-tabs-container .right-arrow, 555 | .scrollable-tabs-container .left-arrow{ 556 | position: absolute; 557 | height: 100%; 558 | width: 100px; 559 | top: 0; 560 | display: none; 561 | align-items: center; 562 | padding: 0 10px; 563 | pointer-events: none; 564 | 565 | } 566 | .scrollable-tabs-container .right-arrow.active, 567 | .scrollable-tabs-container .left-arrow.active{ 568 | display: flex; 569 | } 570 | 571 | .scrollable-tabs-container .right-arrow{ 572 | right: 0; 573 | justify-content: flex-end; 574 | background: linear-gradient(to left, #22254b 50%, transparent); 575 | } 576 | 577 | .scrollable-tabs-container .left-arrow{ 578 | background: linear-gradient(to right, #22254b 50%, transparent); 579 | } 580 | 581 | 582 | .scrollable-tabs-container svg:hover{ 583 | background: var(--secondary-color); 584 | } 585 | 586 | /* Reset some default styles */ 587 | body { 588 | margin: 0; 589 | padding: 0; 590 | } 591 | 592 | /* Footer styles */ 593 | .footer { 594 | background-color:#333; 595 | color: #fff; 596 | text-align: center; 597 | padding: 15px 0 15px 0; 598 | } 599 | 600 | .contact-text { 601 | margin:0; 602 | padding-top: 15px; 603 | font-size: 10px 15px; 604 | color: rgba(255, 255, 255, 0.5); 605 | text-align: center; 606 | margin: 0; 607 | } 608 | 609 | .copy{ 610 | margin:0; 611 | padding-top: 15px; 612 | font-size: 10px 15px; 613 | color: rgba(255, 255, 255, 0.5); 614 | } 615 | 616 | .footer-content { 617 | justify-content: center; 618 | align-items: center; 619 | gap: 20px; 620 | } 621 | 622 | .icon { 623 | margin: 0; 624 | padding: 10px; 625 | } 626 | 627 | .icon:hover { 628 | transform: scale(1.1); 629 | } 630 | 631 | svg { 632 | color: #fff; 633 | cursor: pointer; 634 | width: 30px; 635 | height: 30px; 636 | transition: transform 0.3s ease-in-out; 637 | } 638 | 639 | .all{ 640 | margin-top: 10px; 641 | align-items: center; 642 | } 643 | 644 | .social-top { 645 | margin: 0 auto; 646 | width: 90%; 647 | justify-content: space-between; 648 | align-items: center; 649 | } 650 | 651 | .social p { 652 | font-size: 20px; 653 | padding: 10px; 654 | } 655 | 656 | .social { 657 | justify-items: center; 658 | align-items: center; 659 | } 660 | 661 | .social a svg { 662 | text-decoration: none; 663 | } 664 | 665 | #topBtn p { 666 | font-size: 20px; 667 | padding: 10px 15px; 668 | cursor: pointer; 669 | } 670 | 671 | #topBtn { 672 | margin:0; 673 | display: flex; 674 | justify-items: center; 675 | align-items: center; 676 | background: none; 677 | border: none; 678 | border-radius: 100%; 679 | background-color: rgba(255, 255, 255, 0.5); 680 | padding: 5px; 681 | cursor: pointer; 682 | position: fixed; 683 | right: 2.5rem; 684 | bottom: 2rem; 685 | transition: all; 686 | transition-duration: 300ms; 687 | } 688 | 689 | .top-icon{ 690 | margin: 0; 691 | padding: 0; 692 | } 693 | 694 | .top-icon svg{ 695 | color: #373b69; 696 | } 697 | 698 | .top-icon:hover { 699 | transform: scale(1.1); 700 | transition: all; 701 | transition-duration: 300ms; 702 | } 703 | 704 | hr { 705 | border-color: rgba(255, 255, 255, 0.5); 706 | width: 90%; 707 | margin-left: auto; 708 | margin-right: auto; 709 | display: table; 710 | } 711 | .switch:hover + .page-name { 712 | opacity: 1; 713 | transform: translateX(10px); 714 | transition: opacity 0.3s ease, transform 0.3s ease; 715 | } 716 | 717 | .page-name { 718 | opacity: 0; 719 | transition: opacity 0.3s ease, transform 0.3s ease; 720 | margin-left: 10px; 721 | display: inline-block; 722 | color: white; 723 | } 724 | 725 | .switch-button-container { 726 | display: justify-content; 727 | flex-direction: column; 728 | align-items: center; 729 | text-align: center; 730 | } 731 | 732 | .logo { 733 | width: 50px; 734 | height: 50px; 735 | transition: transform 0.3s ease-in-out; 736 | } 737 | 738 | .logo:hover { 739 | transform: scale(1.2) rotate(360deg); 740 | } 741 | 742 | .text-effect { 743 | transition: transform 0.3s ease-in-out, color 0.3s ease-in-out; 744 | } 745 | 746 | .text-effect:hover { 747 | transform: scale(1.2); 748 | color: #ff5722; 749 | } 750 | 751 | .icon a:hover svg path { 752 | fill:#CBD5E1; 753 | } 754 | 755 | -------------------------------------------------------------------------------- /script_main.js: -------------------------------------------------------------------------------- 1 | //All the url used to fetch movies and tvshows from TMDB api. 2 | const API_key = 'api_key=4b153b123319df27bb67fcbfe219537d'; 3 | const BASE_url = 'https://api.themoviedb.org/3'; 4 | const API_url = BASE_url + '/discover/movie?sort_by=popularity.desc&' + API_key; 5 | const IMG_url = 'https://image.tmdb.org/t/p/w500' 6 | const SEARCH_url = 'https://api.themoviedb.org/3/search/movie?api_key=4b153b123319df27bb67fcbfe219537d&query=' 7 | const TV_url = BASE_url + '/tv/popular?' + API_key + '&vote_count.gte=100'; 8 | const TV_Search_url = 'https://api.themoviedb.org/3/search/tv?' + API_key + '&query=' 9 | 10 | 11 | //Array of all the genres of movies. 12 | const genres = [ 13 | { 14 | "id": 28, 15 | "name": "Action" 16 | }, 17 | { 18 | "id": 12, 19 | "name": "Adventure" 20 | }, 21 | { 22 | "id": 16, 23 | "name": "Animation" 24 | }, 25 | { 26 | "id": 35, 27 | "name": "Comedy" 28 | }, 29 | { 30 | "id": 80, 31 | "name": "Crime" 32 | }, 33 | { 34 | "id": 99, 35 | "name": "Documentary" 36 | }, 37 | { 38 | "id": 18, 39 | "name": "Drama" 40 | }, 41 | { 42 | "id": 10751, 43 | "name": "Family" 44 | }, 45 | { 46 | "id": 14, 47 | "name": "Fantasy" 48 | }, 49 | { 50 | "id": 36, 51 | "name": "History" 52 | }, 53 | { 54 | "id": 27, 55 | "name": "Horror" 56 | }, 57 | { 58 | "id": 10402, 59 | "name": "Music" 60 | }, 61 | { 62 | "id": 9648, 63 | "name": "Mystery" 64 | }, 65 | { 66 | "id": 10749, 67 | "name": "Romance" 68 | }, 69 | { 70 | "id": 878, 71 | "name": "Science Fiction" 72 | }, 73 | { 74 | "id": 10770, 75 | "name": "TV Movie" 76 | }, 77 | { 78 | "id": 53, 79 | "name": "Thriller" 80 | }, 81 | { 82 | "id": 10752, 83 | "name": "War" 84 | }, 85 | { 86 | "id": 37, 87 | "name": "Western" 88 | } 89 | ] 90 | 91 | // run after loading page 92 | window.addEventListener("DOMContentLoaded", (ev)=>{ 93 | // console.log("page loaded"); 94 | let main = document.querySelector('#main'); 95 | 96 | // set the genre categories 97 | setGenres(); 98 | 99 | // set arrow movement for categories 100 | const rightArrow = document.querySelector(".scrollable-tabs-container .right-arrow svg"); 101 | const leftArrow = document.querySelector(".scrollable-tabs-container .left-arrow svg"); 102 | const tagsEl = document.getElementById('tags'); 103 | 104 | rightArrow.addEventListener("click", ()=>{ 105 | tagsEl.scrollLeft += 500; 106 | manageIcons(); 107 | }); 108 | leftArrow.addEventListener("click", ()=>{ 109 | tagsEl.scrollLeft -= 500; 110 | manageIcons(); 111 | }); 112 | 113 | 114 | let onPage=null; 115 | let whichPage = localStorage.getItem('page'); 116 | if(whichPage == null){ 117 | localStorage.setItem("page", "movie"); 118 | onPage = "movie"; 119 | } 120 | else{ 121 | onPage = whichPage; 122 | } 123 | 124 | 125 | // change page variable from localstorage 126 | let pgChange = document.querySelector('.pageChange'); 127 | pgChange.addEventListener('click', ()=>{ 128 | let whichPage = localStorage.getItem('page'); 129 | if(whichPage == 'movie'){ 130 | localStorage.setItem('page', 'tv'); 131 | let tv_svg = ` 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | `; 142 | pgChange.innerHTML = tv_svg; 143 | LoadDataAndDisplay(); 144 | } 145 | else if (whichPage == 'tv'){ 146 | localStorage.setItem('page', 'movie'); 147 | let movie_svg = ` 148 | 149 | 150 | 151 | 152 | 153 | `; 154 | pgChange.innerHTML = movie_svg; 155 | LoadDataAndDisplay(); 156 | } 157 | }) 158 | 159 | // Load data and display function wrapper which fetches data asynchronously and displays it 160 | LoadDataAndDisplay(); 161 | 162 | 163 | const prev = document.getElementById("prev") 164 | const current = document.getElementById("current") 165 | const next = document.getElementById("next") 166 | 167 | prev.addEventListener('click', () =>{ 168 | if(prevPage > 0){ 169 | pageCall(prevPage); 170 | main.scrollIntoView({behavior : 'smooth'}); 171 | } 172 | }) 173 | 174 | next.addEventListener('click', () =>{ 175 | if(nextPage <= totalPages){ 176 | pageCall(nextPage); 177 | main.scrollIntoView({behavior : 'smooth'}); 178 | } 179 | }) 180 | 181 | 182 | let searchBar = document.querySelector('.search'); 183 | searchBar.addEventListener('input', searchStart); 184 | 185 | 186 | let copyRightYear = document.getElementById("copyright-year"); 187 | let currentDate = new Date(); 188 | let currentYear = currentDate.getFullYear(); 189 | copyRightYear.innerText = currentYear; 190 | 191 | }) 192 | 193 | function topFunction() { 194 | document.body.scrollTop = 0; // For Safari 195 | document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera 196 | } 197 | 198 | // set all genres on the page 199 | let selectedGenre=[] 200 | function setGenres(){ 201 | let tags_el = document.querySelector('#tags'); 202 | // console.log(tags_el); 203 | 204 | genres.forEach(genre =>{ 205 | const t = document.createElement('div'); 206 | t.classList.add('tag'); 207 | t.id = genre.id; 208 | t.innerText = genre.name; 209 | 210 | t.addEventListener('click', () => { 211 | if(selectedGenre.length == 0){ 212 | selectedGenre.push(genre.id); 213 | }else{ 214 | if(selectedGenre.includes(genre.id)){ 215 | selectedGenre.forEach((id, idx) =>{ 216 | if(id == genre.id){ 217 | selectedGenre.splice(idx, 1); 218 | } 219 | }) 220 | }else{ 221 | selectedGenre.push(genre.id); 222 | } 223 | } 224 | // console.log(selectedGenre) 225 | 226 | let newurl = API_url + '&with_genres=' + encodeURI(selectedGenre.join(',')); 227 | let whichPage = localStorage.getItem('page'); 228 | LoadMovieOrTv(whichPage, newurl) 229 | highlightSelection(); 230 | 231 | }) 232 | 233 | tags_el.append(t); 234 | }) 235 | } 236 | 237 | // manange the left and right arrows for genre categories 238 | const manageIcons = ()=>{ 239 | const tagsEl = document.getElementById('tags'); 240 | const leftArrowContainer = document.querySelector(".scrollable-tabs-container .left-arrow") 241 | const rightArrowContainer = document.querySelector(".scrollable-tabs-container .right-arrow") 242 | 243 | if(tagsEl.scrollLeft >= 20){ 244 | leftArrowContainer.classList.add("active") 245 | }else{ 246 | leftArrowContainer.classList.remove("active") 247 | } 248 | let maxScrollValue = tagsEl.scrollWidth - tagsEl.clientWidth - 20; 249 | // console.log(tagsEl.scrollWidth); 250 | // console.log(tagsEl.clientWidth); 251 | 252 | if(tagsEl.scrollLeft >= maxScrollValue){ 253 | rightArrowContainer.classList.remove("active") 254 | 255 | }else{ 256 | rightArrowContainer.classList.add("active"); 257 | } 258 | } 259 | 260 | //highlighting the selected genre. 261 | function highlightSelection(){ 262 | const tags = document.querySelectorAll('.tag'); 263 | tags.forEach(tag =>{ 264 | tag.classList.remove('active') 265 | }) 266 | //calling clearBtn function which shows a button to clear all the selected genre when clicking. 267 | // clearBtn() 268 | if(selectedGenre.length != 0){ 269 | selectedGenre.forEach(id =>{ 270 | const highlightedTag = document.getElementById(id); 271 | highlightedTag.classList.add('active'); 272 | }) 273 | } 274 | } 275 | 276 | 277 | var currentPage = 1; 278 | var nextPage = 2; 279 | var prevPage = 3; 280 | var lastUrl = ''; 281 | var totalPages = 100; 282 | // change page number 283 | function pageCall(page){ 284 | 285 | let urlSplit = lastUrl.split('?'); 286 | let queryParameter = urlSplit[1].split('&'); 287 | let key = queryParameter[queryParameter.length - 1].split('='); 288 | if(key[0] != 'page'){ 289 | let url = lastUrl + '&page=' + page; 290 | let whichPage = localStorage.getItem('page'); 291 | LoadMovieOrTv(whichPage, url); 292 | } 293 | else{ 294 | key[1] = page.toString(); 295 | let a = key.join('='); 296 | queryParameter[queryParameter.length - 1] = a; 297 | let b = queryParameter.join('&'); 298 | let url = urlSplit[0] + '?' + b 299 | let whichPage = localStorage.getItem('page'); 300 | LoadMovieOrTv(whichPage, url); 301 | } 302 | 303 | } 304 | 305 | // load and display wrapper 306 | function LoadDataAndDisplay(){ 307 | let whichPage = localStorage.getItem('page'); 308 | let main = document.querySelector('#main'); 309 | main.innerHTML=' '; 310 | 311 | if(whichPage == 'movie'){ 312 | LoadMovieOrTv(whichPage, API_url) 313 | } 314 | else if (whichPage == 'tv'){ 315 | LoadMovieOrTv(whichPage, TV_url) 316 | } 317 | } 318 | 319 | // Asynchronous function which loads data from API 320 | async function LoadMovieOrTv(whichPage, url){ 321 | lastUrl = url; 322 | let main = document.querySelector('#main'); 323 | let res = await fetch(url); 324 | let data = await res.json(); 325 | 326 | if(data.results.length !== 0){ 327 | if(whichPage == 'movie'){ 328 | showMovies(data.results); 329 | } 330 | else if (whichPage == 'tv'){ 331 | showTvShows(data.results); 332 | } 333 | currentPage = data.page; 334 | nextPage = currentPage + 1; 335 | prevPage = currentPage - 1; 336 | totalPages = data.total_pages; 337 | current.innerText = currentPage; 338 | 339 | if(currentPage <= 1){ 340 | prev.classList.add('disabled') 341 | next.classList.remove('disabled') 342 | } 343 | else if(currentPage >= totalPages){ 344 | prev.classList.remove('disabled') 345 | next.classList.add('disabled') 346 | } 347 | else{ 348 | prev.classList.remove('disabled') 349 | next.classList.remove('disabled') 350 | } 351 | 352 | } 353 | else{ 354 | main.innerHTML = ` 355 |

WOW! SUCH EMPTY 🙂

356 | ` 357 | } 358 | } 359 | 360 | 361 | //dynamically loading the movie data in form of Cards consisting of [Title, Poster, Rating, Overview and Release Date]. 362 | function showMovies(data){ 363 | let main = document.querySelector('#main'); 364 | 365 | main.innerHTML=' '; 366 | 367 | data.forEach( movie => { 368 | const {title, poster_path, vote_average, overview, release_date, id} = movie; 369 | const movieEl = document.createElement('div'); 370 | movieEl.classList.add('movie'); 371 | 372 | movieEl.innerHTML = ` 373 |
374 | ${release_date} 375 | ${title} 376 | 377 |
378 |
379 |

${title}

380 | ${vote_average} 381 |
382 |
383 | 384 |

${title}

385 | 386 | ${overview} 387 | 388 |
389 | 390 |
391 |
392 | ` 393 | main.appendChild(movieEl) 394 | 395 | document.getElementById(id).addEventListener('click', ()=>{ 396 | // console.log(id); 397 | openNav(movie); 398 | }) 399 | }) 400 | } 401 | // display Tv shows 402 | function showTvShows(data){ 403 | let main = document.querySelector('#main'); 404 | main.innerHTML=' '; 405 | 406 | data.forEach(tvshow => { 407 | const {name,overview,poster_path,vote_average,first_air_date,id} = tvshow; 408 | const tvEl = document.createElement('div'); 409 | tvEl.classList.add('tvshow'); 410 | 411 | tvEl.innerHTML = ` 412 |
413 | ${first_air_date} 414 | ${name} 415 | 416 |
417 |
418 |

${name}

419 | ${vote_average} 420 |
421 |
422 |

${name}

423 | 424 | ${overview} 425 | 426 |
427 | 428 | 429 |
430 | ` 431 | main.appendChild(tvEl) 432 | 433 | document.getElementById(id).addEventListener('click', ()=>{ 434 | console.log(id); 435 | openNav(tvshow); 436 | }) 437 | }) 438 | } 439 | //change the class of vote_average based on the rating to show different colors for different ratings. 440 | function getColor(vote){ 441 | if(vote >= 7){ 442 | return 'green' 443 | } 444 | else if(vote >= 5){ 445 | return 'orange' 446 | } 447 | else{ 448 | return 'red' 449 | } 450 | } 451 | 452 | // search functionality for searching the results 453 | function searchResultsAndDisplayWrapper(ev){ 454 | let whichPage = localStorage.getItem('page'); 455 | 456 | if(ev.target.value == ''){ 457 | // when the search field is empty for TV or Movie 458 | if(whichPage == 'movie'){ 459 | LoadMovieOrTv(whichPage, API_url); 460 | } 461 | else if (whichPage == 'tv'){ 462 | LoadMovieOrTv(whichPage, TV_url); 463 | 464 | } 465 | } 466 | else{ 467 | // when the search field is NOT empty for TV or Movie 468 | if(whichPage == 'movie'){ 469 | let url_search = SEARCH_url + ev.target.value; 470 | LoadMovieOrTv(whichPage, url_search); 471 | } 472 | else if (whichPage == 'tv'){ 473 | let url_search = TV_Search_url + ev.target.value; 474 | LoadMovieOrTv(whichPage, url_search); 475 | } 476 | 477 | } 478 | } 479 | function searchAndDisplay(func, delay){ 480 | let timer; 481 | 482 | return function (){ 483 | let context = this, 484 | arg = arguments; 485 | 486 | clearTimeout(timer); 487 | 488 | timer = setTimeout(()=>{ 489 | func.apply(context, arguments); 490 | 491 | }, delay) 492 | } 493 | } 494 | const searchStart = searchAndDisplay(searchResultsAndDisplayWrapper, 900); 495 | 496 | 497 | 498 | function showVideos(){ 499 | let embedClass = document.querySelectorAll('.embed'); 500 | embedClass.forEach((embedTag, idx)=>{ 501 | if(activeSlide == idx){ 502 | embedTag.classList.add('show'); 503 | embedTag.classList.remove('hide'); 504 | }else{ 505 | embedTag.classList.add('hide'); 506 | embedTag.classList.remove('show'); 507 | } 508 | }) 509 | } 510 | 511 | /* Open when someone clicks on the span element */ 512 | function openNav(tvOrMovie) { 513 | let id=tvOrMovie.id; 514 | let whichPage = localStorage.getItem('page'); 515 | let _url; 516 | if (whichPage == 'movie'){ 517 | _url = BASE_url+ '/movie/'+ id + '/videos?' + API_key; 518 | } 519 | else if (whichPage == 'tv'){ 520 | _url = BASE_url+ '/tv/'+ id + '/videos?' + API_key; 521 | } 522 | getVideo(_url); 523 | } 524 | 525 | async function getVideo(url){ 526 | const overlayContent = document.getElementById('overlay-content'); 527 | 528 | let res = await fetch(url); 529 | let videoData = await res.json(); 530 | 531 | if(videoData){ 532 | console.log(videoData); 533 | document.getElementById("myNav").style.width = "100%"; 534 | if(videoData.results.length > 0){ 535 | var embed = []; 536 | videoData.results.forEach(video => { 537 | let{name,key,site,type} = video; 538 | 539 | if(site == 'YouTube' && type == 'Trailer'){ 540 | embed.push(` 541 |
542 |
543 | `) 544 | } 545 | }) 546 | 547 | overlayContent.innerHTML = embed.join(''); 548 | activeSlide=0; 549 | showVideos(); 550 | } 551 | else{ 552 | overlayContent.innerHTML = ` 553 |

WOW! SUCH EMPTY 🙂

` 554 | } 555 | } 556 | } 557 | 558 | function closeNav() { 559 | const overlay = document.getElementById("myNav"); 560 | overlay.style.width = "0%"; 561 | const embedClass = document.querySelectorAll('.embed'); 562 | embedClass.forEach(embedTag => { 563 | embedTag.src = ''; 564 | embedTag.parentNode.removeChild(embedTag); 565 | }); 566 | activeSlide = 0; 567 | } 568 | 569 | --------------------------------------------------------------------------------