Skip to content

Commit

Permalink
Fix: Hero Section Drag Movement and Link Routes
Browse files Browse the repository at this point in the history
  • Loading branch information
ErickLimaS committed Feb 2, 2024
1 parent 37ba3cd commit 0cb4f92
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 112 deletions.
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![Logo Do Site AniProject.](https://user-images.githubusercontent.com/69987890/177884319-0678f842-f3ca-4f62-8d31-7638ca954057.png)

Projeto de um site de animes, mangas e filmes relacionados. A API da <a href='https://anilist.gitbook.io/anilist-apiv2-docs/'>AniList</a> dispoe informações de animes e episodios sendo lançados atualmente, dados do elenco por trâs de tal mídia, e muito mais.
Projeto de um site de animes e mangas, utilizando a API da <a href='https://anilist.gitbook.io/anilist-apiv2-docs/'>AniList</a> que dispoe informações de animes e episódios sendo lançados atualmente, dados do elenco por trás de tal mídia, e muito mais.

## :hammer: Funcionalidades

Expand All @@ -12,11 +12,11 @@ Projeto de um site de animes, mangas e filmes relacionados. A API da <a href='ht

## :pushpin: Em Planejamento

- [ ] `Crie sua Conta`: Usando MongoDB e Express, criei um banco de dados para salvar os dados dos usuários que se registrarem no site.
- [ ] `Marque Mangas e Episódios já vistos`: Mantenha o progresso de quais você terminou ou que precisa terminar.
- [ ] `Marque seus Animes e Mangas Favoritos`: Apos criar uma conta, você podera marcar animes e mangas, para ter um rápido acesso da próxima vez que usar o site.
- [ ] `Crie sua Conta`
- [ ] `Marque Mangas e Episódios já vistos`
- [ ] `Marque seus Animes e Mangas Favoritos`
- [ ] `Tenha o histórico registrado do que já assitiu até agora`
- [ ] `Seja Alertado de Novos Episódios Lançados`:
- [ ] `Seja Alertado de Novos Episódios Lançados`

## :heavy_check_mark: Tecnologias Utilizadas

Expand All @@ -40,14 +40,17 @@ Back-End (planning):

Its simple!

1. ``Clone`` this code
1. ``Clone`` this repository
```javascript
git clone https://github.com/ErickLimaS/anime-website.git
```

3. From the ``front-end`` directory, run ``npm install`` on your CMD to get all dependencies
3. From the ``front-end directory``, run ``npm install`` on your CMD to get all dependencies
```javascript
npm install
```

3. From ``front-end`` directory, run ``npm run dev`` to initialize the website
3. From ``front-end directory``, run ``npm run dev`` to initialize the website
```javascript
npm run dev
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ ul.carousel_container {

}

ul.carousel_container img {

position: absolute;
max-width: 100vw;

}

ul.carousel_container li.carousel_item {

overflow: hidden;
Expand All @@ -22,20 +29,29 @@ ul.carousel_container li.carousel_item div.item_info {

position: relative;

top: 10%;
/* top: 10%; */
bottom: calc(-20% - 2vh);
left: 2%;
width: 96%;

}

@media((min-width: 380px)) {

ul.carousel_container li.carousel_item div.item_info {
bottom: -50%;
}
}

@media((min-width: 1200px)) {

ul.carousel_container li.carousel_item div.item_info {

left: calc(var(--breakpoint-sm) / 4);

bottom: auto;
top: 35%;
max-width: 35%;
max-width: 34%;

}

Expand Down Expand Up @@ -200,7 +216,7 @@ ul.carousel_container li.carousel_item div.item_info .item_buttons>button {
/* RECOMENDATIONS */
#recomendations_container {

z-index: 0;
z-index: 1;

margin-top: 24px;

Expand All @@ -214,7 +230,7 @@ ul.carousel_container li.carousel_item div.item_info .item_buttons>button {

}

@media((min-width: 620px)) {
@media((min-width: 1200px)) {
#recomendations_container {

margin-top: 0;
Expand Down Expand Up @@ -313,8 +329,43 @@ ul.carousel_container li.carousel_item div.item_info .item_buttons>button {

}

#recomendations_container ul li>img {
#recomendations_container ul li a>img {

object-fit: cover;

}

#recomendations_container ul li span {
opacity: 0;

display: block;

position: relative;
bottom: 0;

transition: all ease-in-out 100ms;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;

text-align: center;
font-size: var(--font-size--small-1);
font-weight: 600;
padding: 4px 0;

color: var(--white-100);
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;

background-color: var(--black-75);

}

#recomendations_container ul li:hover span {

opacity: 1;

}
182 changes: 86 additions & 96 deletions front-end/app/components/HeroCarouselHomePage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,141 +1,128 @@
'use client'
import React, { useEffect } from 'react'
import React, { useState } from 'react'
import styles from "./carouselComponent.module.css"
import Link from 'next/link'
import Image from 'next/image'
import { ApiTrendingMidiaResults } from '@/app/ts/interfaces/apiAnilistDataInterface'
import { wrap } from 'popmotion'
import { AnimatePresence, motion } from 'framer-motion'

function HeroCarousel({ data }: { data: ApiTrendingMidiaResults[] }) {

useEffect(() => {

scrollHeroSection()

}, [])

function scrollHeroSection() {

if (typeof window !== "undefined") {
let isDragging = false;

let startPosition = 0;
let currentTranslate = 0;

let currentListIndex = 1

const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
let wasDraggedMoreThanOneThirdScreen = false

const carousel = document.getElementById(`carousel`) as HTMLElement;

if (carousel) {

carousel.addEventListener('mousedown', (e) => {
isDragging = true;
startPosition = e.clientX - currentTranslate;
});

carousel.addEventListener('mouseup', (e) => {
isDragging = false;
currentTranslate = vw - (vw * (currentListIndex + 1))
const newPosition = e.clientX - (startPosition - currentTranslate)

currentTranslate = newPosition - vw;

if (wasDraggedMoreThanOneThirdScreen) {
transitionBeetweenItens()
}

});

carousel.addEventListener('mousemove', (e) => {
if (!isDragging) return;

const newPosition = currentListIndex > 1 ? (e.clientX - (vw * currentListIndex)) : (e.clientX - startPosition)

currentTranslate = newPosition;

if ((currentListIndex + 1) == data.length) return

updateCarousel();

if (currentTranslate + (vw * 1.25)) {
wasDraggedMoreThanOneThirdScreen = true
}

});
}

const updateCarousel = () => {
carousel.style.transform = `translateX(${currentTranslate}px)`;
}
const [[page, direction], setPage] = useState([0, 0]);

const variants = {
enter: (direction: number) => {
return {
x: direction > 0 ? 1000 : -1000,
opacity: 0
};
},
center: {
zIndex: 1,
x: 0,
opacity: 1
},
exit: (direction: number) => {
return {
zIndex: 0,
x: direction < 0 ? 1000 : -1000,
opacity: 0
};
}
};

const transitionBeetweenItens = () => {
const swipeConfidenceThreshold = 10000;
const swipePower = (offset: number, velocity: number) => {
return Math.abs(offset) * velocity;
};

carousel.style.transform = `translateX(${(vw - (vw * (currentListIndex + 1)))}px)`;
currentListIndex++
currentTranslate = 0
wasDraggedMoreThanOneThirdScreen = false
const imageIndex = wrap(0, data.length, page);

}
const paginate = (newDirection: number) => {
setPage([page + newDirection, newDirection]);
};

}
const styledList = {
background: `linear-gradient(rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.10)), url(${data[imageIndex]?.media.bannerImage})`,
backgroundPosition: "center",
backgroundSize: "cover",
backgroundRepeat: "no-repeat"
}

return (
<>
<ul id="carousel" className={`${styles.carousel_container} display_flex_row`}>
{data != undefined && (
<ul id="carousel" className={`${styles.carousel_container} display_flex_row`}>

<AnimatePresence initial={false} custom={direction}>

{data != undefined && (
data.map((item: ApiTrendingMidiaResults, key: number) => (
<li
key={key}
<motion.li
key={page}
className={styles.carousel_item}
style={{
background: `linear-gradient(rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.10)), url(${item.media.bannerImage})`,
backgroundPosition: "center",
backgroundSize: "cover",
backgroundRepeat: "no-repeat"
}}>
style={styledList}
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
x: { type: "spring", stiffness: 300, damping: 30 },
opacity: { duration: 0.2 }
}}
drag="x"
dragConstraints={{ left: 0, right: 0 }}
dragElastic={1}
onDragEnd={(e, { offset, velocity }) => {
const swipe = swipePower(offset.x, velocity.x);

if (swipe < -swipeConfidenceThreshold) {
paginate(1);
} else if (swipe > swipeConfidenceThreshold) {
paginate(-1);
}
}}
>
<div className={styles.item_info}>

<h2><Link href={`/media/${item.media.id}`}>{item.media.title.romaji}</Link></h2>
<h2><Link href={`/media/${data[imageIndex]?.media.id}`}>{data[imageIndex]?.media.title.romaji}</Link></h2>

<div className={`${styles.item_info_inside} display_flex_row`}>

{item.media.seasonYear != undefined && (
<p>{item.media.seasonYear.toString()}</p>
{data[imageIndex]?.media.seasonYear != undefined && (
<p>{data[imageIndex].media.seasonYear.toString()}</p>
)}
{((item.media.genres != undefined) && (item.media.seasonYear != undefined)) && (
{((data[imageIndex]?.media.genres != undefined) && (data[imageIndex]?.media.seasonYear != undefined)) && (
<span>|</span>
)}
{item.media.genres != undefined && (
<p><Link href={`/genre/${item.media.genres[0].toLowerCase()}`}>{item.media.genres[0]}</Link></p>
{data[imageIndex]?.media.genres != undefined && (
<p><Link href={`/genre/${data[imageIndex]?.media.genres[0].toLowerCase()}`}>{data[imageIndex]?.media.genres[0]}</Link></p>
)}
{((item.media.seasonYear != undefined) && (item.media.episodes != undefined)) && (
{((data[imageIndex]?.media.seasonYear != undefined) && (data[imageIndex]?.media.episodes != undefined)) && (
<span>|</span>
)}
{item.media.episodes != undefined && (
<p>{item.media.episodes.toString()} Episodes</p>
{data[imageIndex]?.media.episodes != undefined && (
<p>{data[imageIndex].media.episodes.toString()} Episodes</p>
)}

</div>

<div className={styles.item_buttons}>

<Link href={`/media/${item.media.id}`}>WATCH NOW</Link>
<Link href={`/media/${data[imageIndex]?.media.id}`}>WATCH NOW</Link>

<button>+ PLAYLIST</button>

</div>

</div>

</li>
))
)}
</motion.li>

</AnimatePresence>

</ul>
</ul >
)}

<div id={styles.recomendations_container}>

Expand All @@ -146,7 +133,10 @@ function HeroCarousel({ data }: { data: ApiTrendingMidiaResults[] }) {
data.slice(0, 6).map((item: ApiTrendingMidiaResults, key: number) => (
item.media.bannerImage && (
<li key={key}>
<Image src={item.media.bannerImage} alt={`Cover for ${item.media.title.romaji}`} fill />
<Link href={`/media/${item.media.id}`}>
<Image src={item.media.bannerImage} alt={`Cover for ${item.media.title.romaji}`} fill />
</Link>
<span>{item.media.title.romaji}</span>
</li>
))
)
Expand Down
Loading

0 comments on commit 0cb4f92

Please sign in to comment.