<목표>
1. 왼쪽에 4개씩의 이미지를 보여주고 클릭하면 오른쪽에 그 이미지에 대한 설명을 나타나게 해야함.
2. 이미지가 5개가 넘어가면 페이징처리를 해야함.
3. 클릭을 했을 때, 어떤 이미지가 클릭되었는지 확인할 수 있어야함. 밝기 조절을 해서 클릭한 이미지가 무엇인지 눈에 띄게 보이게 만들었음. 테두리 색상 변경과 박스 그림자 강조 배경색 변경 등 여러가지 시도 했지만 밝기 조절이 가장 이뻐보였음.
1번쨰 이미지를 클릭해서 1번째 이미지는 "ListPlz"라는 데스크탑 어플리케이션을 만들예정이기에 그림과 같이 해놓았다.
글자의 배치같은 경우 대부분 position: absolute을 이용했기 때문에 나중에 쉽게 다시 배치를 변경 가능하다.
설명과 다른 부분이 완성되면 제대로 배치할 생각이다.
ContentSectionTwo.jsx
import React,{useState} from 'react';
import { FaArrowLeft, FaArrowRight } from 'react-icons/fa';
import './ContentSectionTwo.scss';
const softwareList = [
{
id: 1,
name: 'Listplz',
description: 'An advanced text editor for developers.',
image: 'https://via.placeholder.com/150?text=Alpha+Software',
},
{
id: 2,
name: 'Chatplz',
description: 'A powerful tool for data analysis and visualization.',
image: 'https://via.placeholder.com/150?text=Beta+Analytics',
},
{
id: 3,
name: 'Toonplz',
description: 'A robust security suite to protect your digital life.',
image: 'https://via.placeholder.com/150?text=Gamma+Security',
},
{
id: 4,
name: 'Talkplz',
description: 'A robust security suite to protect your digital life.',
image: 'https://via.placeholder.com/150?text=Gamma+Security',
},
{
id: 5,
name: 'Talkplz',
description: 'A robust security suite to protect your digital life.',
image: 'https://via.placeholder.com/150?text=Gamma+Security',
},
];
const ContentSectionTwo = () => {
const [activeSoftware, setActiveSoftware] = useState(null);
const [pageIndex, setPageIndex] = useState(0);
const itemsPerPage = 4;
const maxPageIndex = Math.ceil(softwareList.length / itemsPerPage) - 1;
const displayedSoftware = softwareList.slice(
pageIndex * itemsPerPage,
pageIndex * itemsPerPage + itemsPerPage
);
const handleCardClick = (software) => {
setActiveSoftware(software);
};
const handleNextClick = () => {
setPageIndex(prevIndex => Math.min(prevIndex + 1, maxPageIndex));
};
const handlePrevClick = () => {
setPageIndex(prevIndex => Math.max(prevIndex - 1, 0));
};
return (
<div className="content-section-two">
<div className="carousel-container">
<div className="card-container">
{displayedSoftware.map((software) => (
<div
key={software.id}
className={`software-card ${activeSoftware === software ? 'active' : ''}`}
onClick={() => handleCardClick(software)}
>
<img src={software.image} alt={software.name} />
</div>
))}
</div>
</div>
<div className="button-container">
<button onClick={handlePrevClick} disabled={pageIndex === 0}>
<FaArrowLeft />
</button>
<button onClick={handleNextClick} disabled={pageIndex === maxPageIndex}>
<FaArrowRight />
</button>
</div>
<div className="software-details">
{activeSoftware ? (
<>
<div className="software-description-container">
<p className="software-description">{activeSoftware.description}</p>
<button className="find-dealer-button">Download</button>
</div>
</>
) : (
<p>Select a software to see details.</p>
)}
</div>
{activeSoftware && (
<h1 className="software-title">{activeSoftware.name}</h1>
)}
</div>
);
};
export default ContentSectionTwo;
//ContentSectionTwo.scss
.content-section-two {
justify-content: center; // Center the content vertically
align-items: center; // Center the content horizontally
display: flex;
width: 100vw;
height: 100vh;
position: relative;
background-color: #000;
z-index: 2;
}
.carousel-container {
transform: translate(5%, 13%);
height: 100%;
width: 100%;
.card-container {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 80%;
height: 80%;
.software-card {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
cursor: pointer;
transition:
transform 0.3s ease,
box-shadow 0.3s ease;
position: relative;
overflow: hidden;
z-index: 2;
&.active {
background-color: rgba(255, 255, 255, 0.1); // 배경색 약간 변경
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4); // 박스 그림자 강조
filter: brightness(130%); // 밝기 조절
z-index: 3;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
}
.button-container {
position: absolute;
bottom: 3%; // 이미지 하단에서 10px 떨어진 위치
left: 22%;
background-color: #000;
display: flex;
button {
background-color: transparent;
display: flex;
justify-content: center;
align-items: center;
margin: 0 50px;
padding: 5px 40px;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
&:hover {
background-color: #555;
}
&:disabled {
cursor: not-allowed;
}
svg {
font-size: 20px;
}
}
}
.software-details {
flex: 0 0 30%;
padding: 2em;
border-radius: 10px;
position: relative;
z-index: 5;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.software-title {
font-family: "Oswald", sans-serif;
font-family: "Playfair Display", serif;
font-size: 8em;
color: #f0f0f0;
margin-bottom: 1em;
text-align: center;
position: absolute;
top: 50px;
width: 100%;
padding-top: 10%;
padding-left: 40%;
}
.software-description {
font-family: "Oswald", sans-serif;
font-size: 1em;
color: #f0f0f0;
text-align: center;
margin-top: auto;
}
.find-dealer-button {
align-self: center;
margin-top: 1em;
padding: 10px 20px;
background-color: #333;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
text-transform: uppercase;
font-weight: bold;
&:hover {
background-color: #555;
}
}
@media (max-width: 1200px) {
.card-container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) {
.content-section-two {
flex-direction: column;
align-items: center;
}
.carousel-container,
.software-details {
flex: 0 0 100%;
max-width: 100%;
}
.card-container {
grid-template-columns: 1fr;
}
}
<시도한 점>
1. 처음에 antd 라이브러리의 Carousels을 사용했지만 화면상에 크기 조절과 Carousels안의 이미지들이 클릭하도록 만들어도 넘어가는 부분들이 깨져서 bootstrap Carousels을 시도 했지만 마찬가지로 여러 불편한 점 떄문에 react-bootstrap으로 시도했다가 생각대로 잘 안되어서 Carousels말고 페이징처리로 마무리 했다.
도중에 세션마다 높이들이 어긋나 고생을 좀 했다.
2. ContentSectionThree을 만들다가 footer로 높이를 각 세션마다 빼야 footer를 배치해야 높이가 맞겠구나 이런 병신같은 생각을 해서 개짓거리를 했다. 새벽에 술먹으면서 코딩한 죄같다.
mainPage.scss에서 높이를 calc(100vh - 60px);로 해놔서 그런걸 다른 모든 Section높이들을 설정하느라 몇시간을 날려먹은지 모르겠다. 해결은 했고 이 높이 때문에 싹 다 다시 리펙토링해서 나름 만족한 결과였다.
//고치기 전
.section {
scroll-snap-align: start;
height: calc(100vh - 60px);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: var(--secondary-color);
border-radius: 15px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
margin: 20px 0;
}
//고친 후
.section {
scroll-snap-align: start;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: var(--secondary-color);
border-radius: 15px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
margin: 20px 0;
}
'개인프로젝트 > unitedPrompt' 카테고리의 다른 글
예전 아이콘 (0) | 2024.01.20 |
---|---|
ContentSectionThree 눈 내리기 추가 (0) | 2024.01.20 |
ContentSectionThree (0) | 2024.01.18 |