Skip to content

Commit e1b4a84

Browse files
committed
🎨 Design: λ Œλ”©νŽ˜μ΄μ§€μ˜ 이미지 μˆ˜μ •, 슀크둀 μ• λ‹ˆλ©”μ΄μ…˜ μΆ”κ°€
1 parent e44906d commit e1b4a84

File tree

8 files changed

+92
-40
lines changed

8 files changed

+92
-40
lines changed

β€Žpublic/images/HomeExample.svg

Lines changed: 0 additions & 9 deletions
This file was deleted.

β€Žpublic/images/board.svg

Lines changed: 1 addition & 0 deletions
Loading

β€Žpublic/images/flavor.svg

Lines changed: 1 addition & 0 deletions
Loading

β€Žpublic/images/fti.svg

Lines changed: 1 addition & 0 deletions
Loading

β€Žpublic/images/social.svg

Lines changed: 1 addition & 0 deletions
Loading

β€Žsrc/components/landing/Section.tsx

Lines changed: 69 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import React, { useEffect, useRef, useState } from 'react';
12
import { Link } from 'react-router-dom';
23
import { RiArrowRightSLine } from 'react-icons/ri';
34
import ContentLoader from 'react-content-loader';
4-
import React from 'react';
55

66
interface SectionProps {
77
title: string;
@@ -11,6 +11,7 @@ interface SectionProps {
1111
buttonText: string;
1212
isImageLoaded: boolean;
1313
setIsImageLoaded: (loaded: boolean) => void;
14+
imgUrl: string;
1415
}
1516

1617
const Section: React.FC<SectionProps> = ({
@@ -21,36 +22,73 @@ const Section: React.FC<SectionProps> = ({
2122
buttonText,
2223
isImageLoaded,
2324
setIsImageLoaded,
24-
}) => (
25-
<div className="w-full max-w-[800px] bg-slate-100 bg-gradient-to-r from-gray-100 to-gray-200 p-4 text-center">
26-
<h2 className="mt-20 text-2xl font-semibold text-orange-500 xs:text-xl">{title}</h2>
27-
<p className="mt-10 text-3xl font-bold xs:text-2xl">{subtitle}</p>
28-
<p className="mt-10 text-[16px] text-gray-500 xs:text-[16px]">{description}</p>
29-
<div className="flex justify-center">
30-
<Link
31-
to={linkTo}
32-
className="gray-400 mt-4 flex h-12 w-32 items-center justify-center rounded-[20px] bg-white px-4 py-2 font-bold hover:bg-orange-600 hover:text-white xs:h-11 xs:w-28">
33-
{buttonText} <RiArrowRightSLine size={20} />
34-
</Link>
25+
imgUrl,
26+
}) => {
27+
const [isVisible, setIsVisible] = useState(false);
28+
const sectionRef = useRef<HTMLDivElement>(null);
29+
30+
useEffect(() => {
31+
const observer = new IntersectionObserver(
32+
(entries) => {
33+
entries.forEach((entry) => {
34+
if (entry.isIntersecting) {
35+
setIsVisible(true);
36+
}
37+
});
38+
},
39+
{ threshold: 0.05 },
40+
);
41+
if (sectionRef.current) {
42+
observer.observe(sectionRef.current);
43+
}
44+
return () => {
45+
if (sectionRef.current) {
46+
observer.unobserve(sectionRef.current);
47+
}
48+
};
49+
}, []);
50+
51+
return (
52+
<div
53+
ref={sectionRef}
54+
className="relative w-full max-w-[600px] overflow-hidden bg-slate-100 bg-gradient-to-r from-gray-100 to-gray-200 p-4 text-center">
55+
<h2
56+
className={`mt-20 text-2xl font-semibold text-orange-500 xs:text-xl ${isVisible ? 'animate-slideInLeft' : 'opacity-0'}`}>
57+
{title}
58+
</h2>
59+
<p className={`mt-10 text-3xl font-bold xs:text-2xl ${isVisible ? 'animate-slideInLeft' : 'opacity-0'}`}>
60+
{subtitle}
61+
</p>
62+
<p
63+
className={`mt-10 text-[16px] text-gray-500 xs:text-[16px] ${isVisible ? 'animate-slideInLeft' : 'opacity-0'}`}>
64+
{description}
65+
</p>
66+
<div className={`flex justify-center ${isVisible ? 'animate-slideInLeft' : 'opacity-0'}`}>
67+
<Link
68+
to={linkTo}
69+
className="gray-400 mt-4 flex h-12 w-32 items-center justify-center rounded-[20px] bg-white px-4 py-2 font-bold hover:bg-orange-600 hover:text-white xs:h-11 xs:w-28">
70+
{buttonText} <RiArrowRightSLine size={20} />
71+
</Link>
72+
</div>
73+
{!isImageLoaded && (
74+
<ContentLoader
75+
height={200}
76+
width={200}
77+
speed={2}
78+
backgroundColor="#f3f3f3"
79+
foregroundColor="#ecebeb"
80+
className="mx-auto mb-20 mt-20">
81+
<circle cx="100" cy="100" r="100" />
82+
</ContentLoader>
83+
)}
84+
<img
85+
src={imgUrl}
86+
alt="example"
87+
className={`mx-auto mb-5 mt-20 xs:mt-10 ${isVisible ? 'animate-slideInRight' : 'opacity-0'}`}
88+
onLoad={() => setIsImageLoaded(true)}
89+
/>
3590
</div>
36-
{!isImageLoaded && (
37-
<ContentLoader
38-
height={200}
39-
width={200}
40-
speed={2}
41-
backgroundColor="#f3f3f3"
42-
foregroundColor="#ecebeb"
43-
className="mx-auto mb-20 mt-20">
44-
<circle cx="100" cy="100" r="100" />
45-
</ContentLoader>
46-
)}
47-
<img
48-
src="/images/HomeExample.svg"
49-
alt="example"
50-
className={`mx-auto mb-20 mt-20 ${isImageLoaded ? 'block' : 'hidden'}`}
51-
onLoad={() => setIsImageLoaded(true)}
52-
/>
53-
</div>
54-
);
91+
);
92+
};
5593

5694
export default Section;

β€Žsrc/pages/Home/Landing.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const Landing: React.FC = () => {
5454
buttonText="더보기"
5555
isImageLoaded={isImageLoaded}
5656
setIsImageLoaded={setIsImageLoaded}
57+
imgUrl="/images/fti.svg"
5758
/>
5859
<Section
5960
title="κ°œμΈλ³„ μŒμ‹μΆ”μ²œ"
@@ -69,6 +70,7 @@ const Landing: React.FC = () => {
6970
buttonText="더보기"
7071
isImageLoaded={isImageLoaded}
7172
setIsImageLoaded={setIsImageLoaded}
73+
imgUrl="/images/flavor.svg"
7274
/>
7375
<Section
7476
title="μ†Œμ…œλ‹€μ΄λ‹"
@@ -84,6 +86,7 @@ const Landing: React.FC = () => {
8486
buttonText="더보기"
8587
isImageLoaded={isImageLoaded}
8688
setIsImageLoaded={setIsImageLoaded}
89+
imgUrl="/images/social.svg"
8790
/>
8891
<Section
8992
title="λ§›μžˆλŠ” 발견"
@@ -99,6 +102,7 @@ const Landing: React.FC = () => {
99102
buttonText="더보기"
100103
isImageLoaded={isImageLoaded}
101104
setIsImageLoaded={setIsImageLoaded}
105+
imgUrl="/images/board.svg"
102106
/>
103107
<Footer />
104108
</div>

β€Žtailwind.config.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@ module.exports = {
1111
],
1212
theme: {
1313
extend: {
14+
keyframes: {
15+
slideInLeft: {
16+
'0%': { opacity: '0', transform: 'translateX(-30%)' },
17+
'100%': { opacity: '1', transform: 'translateX(0)' },
18+
},
19+
slideInRight: {
20+
'0%': { opacity: '0', transform: 'translateX(30%)' },
21+
'100%': { opacity: '1', transform: 'translateX(0)' },
22+
},
23+
},
24+
animation: {
25+
slideInLeft: 'slideInLeft 0.7s ease-in-out',
26+
slideInRight: 'slideInRight 0.7s ease-in-out',
27+
},
28+
1429
screens: {
1530
xs: { max: '600px' },
1631
xxs: { max: '375px' },

0 commit comments

Comments
Β (0)