Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified public/favicon.ico
Binary file not shown.
Binary file removed public/slogan.png
Binary file not shown.
Binary file removed public/testlogo.png
Binary file not shown.
Binary file removed public/text_logo.png
Binary file not shown.
212 changes: 123 additions & 89 deletions src/app/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ export default function LandingPage() {
useEffect(() => {
setIsLoaded(true);
lenisRef.current = new Lenis({
duration: 0.8, // 1.2에서 0.8로 변경
easing: (t: number) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
duration: 1.2,
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
smoothWheel: true,
wheelMultiplier: 2,
touchMultiplier: 1.2,
infinite: false,
touchMultiplier: 2,
infinite: true,
});

function raf(time: number) {
Expand All @@ -87,36 +87,38 @@ export default function LandingPage() {
requestAnimationFrame(raf);

let lastScrollTime = 0;
const scrollThreshold = 500; // ms
const scrollThreshold = 150;

lenisRef.current.on("scroll", ({ progress }: { progress: number }) => {
const currentTime = Date.now();
if (currentTime - lastScrollTime < scrollThreshold) return;

if (!isScrollingRef.current) {
const totalSlides = slides.length;
const newSlideIndex = Math.min(slides.length - 1, Math.max(0, Math.round(progress * (totalSlides - 1))));
const progressPerSlide = 1 / (totalSlides - 1);
const currentProgress = progress / progressPerSlide;
let newSlideIndex = Math.round(currentProgress);

if (progress >= 0.99) {
newSlideIndex = 0;
setTimeout(() => {
lenisRef.current?.scrollTo(0, {
duration: 1.2,
easing: (t) => t * (2 - t),
});
}, 100);
}

if (newSlideIndex !== currentSlide) {
setCurrentSlide(newSlideIndex);
isScrollingRef.current = true;
const targetScroll =
(newSlideIndex / (totalSlides - 1)) *
(isLargeScreen ? containerRef.current!.scrollHeight : containerRef.current!.scrollWidth);

lenisRef.current?.scrollTo(targetScroll, {
immediate: false,
duration: 600, // 800에서 600으로 변경
easing: (t: number) => t * (2 - t),
});

lastScrollTime = currentTime;

setTimeout(() => {
isScrollingRef.current = false;
}, 600); // 800에서 600으로 변경
}, 200);
}
}
lastScrollTime = currentTime;
});

document.documentElement.style.scrollbarWidth = "none";
Expand Down Expand Up @@ -151,26 +153,28 @@ export default function LandingPage() {
className={`h-[400vh] min-h-[768px] overflow-hidden bg-gradient-to-br from-[#1a1a1a] to-[#2a2a2a] ${
isLargeScreen ? "" : "flex flex-col"
}`}
style={{
scrollbarWidth: "thin",
scrollbarColor: "#108b2d transparent",
}}
>
<div className={`fixed inset-0 ${isLargeScreen ? "flex" : "flex flex-col"}`}>
<motion.div
className={`relative ${isLargeScreen ? "w-1/2" : "flex h-1/2 w-full items-center justify-center overflow-hidden"}`}
className={`relative ${
isLargeScreen ? "w-1/2" : "flex h-1/2 w-full items-center justify-center overflow-hidden"
}`}
animate={{
width: currentSlide === 0 ? "100%" : isLargeScreen ? "50%" : "100%",
height: currentSlide === 0 ? "100%" : isLargeScreen ? "100%" : "50%",
}}
transition={{ duration: 0.8, ease: "easeInOut" }}
>
<motion.div
className="absolute inset-0 flex items-center justify-center"
initial={{ opacity: 0 }}
className="relative flex h-full w-full items-center justify-center"
animate={{
opacity: 1,
}}
transition={{
duration: 0.8, // Updated transition duration
ease: "easeInOut",
scale: currentSlide === 0 ? 1 : 0.8,
}}
transition={{ duration: 0.8, ease: "easeInOut" }}
>
{currentSlide === 0 ? (
<Image
Expand All @@ -179,6 +183,7 @@ export default function LandingPage() {
width={800}
height={800}
className="h-full max-h-[800px] w-full max-w-[800px] object-contain"
priority
/>
) : currentSlide === 4 || currentSlide === 5 ? (
<motion.div
Expand All @@ -187,20 +192,20 @@ export default function LandingPage() {
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 1.2, ease: "easeInOut" }} // Update 1
transition={{ duration: 1.2, ease: "easeInOut" }}
>
<motion.h2
className="mb-2 mt-0 text-center text-xl font-semibold text-gray-100 max-[640px]:mb-1 max-[640px]:px-4 md:mb-4 md:mt-0 md:text-3xl"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.3, duration: 0.6 }} // Update 2
transition={{ delay: 0.3, duration: 0.6 }}
>
{slides[currentSlide].blackAreaTitle}
</motion.h2>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.4, duration: 0.6 }} // Update 2
transition={{ delay: 0.4, duration: 0.6 }}
className="mb-2 w-full max-w-[600px] max-[640px]:max-w-[75%] max-[640px]:px-4 md:mb-4"
style={{ maxHeight: "calc(100% - 12rem)" }}
>
Expand All @@ -221,28 +226,27 @@ export default function LandingPage() {
className="mb-0 max-w-[600px] whitespace-pre-wrap text-center text-sm text-gray-200 max-[640px]:mt-1 max-[640px]:px-4 md:text-xl"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.5, duration: 0.6 }} // Update 2
transition={{ delay: 0.5, duration: 0.6 }}
>
{slides[currentSlide].blackAreaContent}
</motion.p>
</motion.div>
) : (
<motion.div
className="absolute inset-0 flex items-center justify-center"
className="relative h-full max-h-[600px] w-full max-w-[600px]"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.8 }} // Update 3
transition={{ duration: 0.8 }}
>
<div className="relative h-full max-h-[600px] w-full max-w-[600px]">
<Image
src="/brand.png"
alt="Brand Logo"
fill
className="object-contain"
sizes="(max-width: 600px) 100vw, 600px"
/>
</div>
<Image
src="/brand.png"
alt="Brand Logo"
fill
className="object-contain"
sizes="(max-width: 600px) 100vw, 600px"
priority
/>
</motion.div>
)}
</motion.div>
Expand All @@ -267,75 +271,105 @@ export default function LandingPage() {
<AnimatePresence mode="wait">
{currentSlide > 0 && (
<motion.div
key={currentSlide}
className={`relative z-40 flex ${
isLargeScreen ? "w-1/2" : "h-1/2 w-full"
} flex-col items-center justify-center p-4 pb-6 pt-4 max-[640px]:px-12 max-[640px]:py-3 md:p-6 md:pb-8 md:pt-6`}
className={`relative z-40 flex ${isLargeScreen ? "w-1/2" : "h-1/2 w-full"}`}
style={{
background: "linear-gradient(135deg, #71db77 0%, #56c45d 100%)",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
height: isLargeScreen ? "100%" : "50%",
overflow: "hidden",
}}
initial={{ opacity: 0, [isLargeScreen ? "y" : "x"]: isLargeScreen ? "100%" : "100%" }}
animate={{ opacity: 1, [isLargeScreen ? "y" : "x"]: 0 }}
exit={{ opacity: 0, [isLargeScreen ? "y" : "x"]: isLargeScreen ? "-100%" : "-100%" }}
transition={{ duration: 0.4, ease: "easeInOut" }} // Updated transition duration
initial={{ width: 0 }}
animate={{ width: isLargeScreen ? "50%" : "100%" }}
transition={{ duration: 0.8, ease: "easeInOut" }}
>
<motion.h2
className="mb-2 mt-0 text-center text-xl font-semibold text-[#1a1a1a] max-[640px]:mb-1 max-[640px]:px-4 md:mb-4 md:mt-0 md:text-3xl"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.05, duration: 0.3 }} // Updated transition
>
{slides[currentSlide].title}
</motion.h2>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.1, duration: 0.3 }} // Updated transition
className="mb-2 w-full max-w-[600px] max-[640px]:max-w-[75%] max-[640px]:px-4 md:mb-4"
style={{ maxHeight: "calc(100% - 12rem)" }}
>
<div
className="relative w-full overflow-hidden rounded-lg shadow-lg"
style={{ paddingBottom: "56.25%" }}
<AnimatePresence mode="wait">
<motion.div
key={currentSlide}
className="flex h-full w-full flex-col items-center justify-center p-4 pb-6 pt-4 max-[640px]:px-12 max-[640px]:py-3 md:p-6 md:pb-8 md:pt-6"
initial={{ y: "100%" }}
animate={{ y: 0 }}
exit={{ y: "-100%" }}
transition={{ duration: 0.4, ease: "easeInOut" }}
>
<Image
src={slides[currentSlide].image || ""}
alt={slides[currentSlide].title || ""}
fill
style={{ objectFit: "cover" }}
sizes="(max-width: 768px) 100vw, 600px"
/>
</div>
</motion.div>
<motion.p
className="mb-0 max-w-[600px] whitespace-pre-wrap text-center text-sm text-[#1a1a1a] max-[640px]:mt-1 max-[640px]:px-4 md:text-xl"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.15, duration: 0.3 }} // Updated transition
>
{slides[currentSlide].content}
</motion.p>
<motion.h2
className="mb-2 mt-0 text-center text-xl font-semibold text-[#1a1a1a] max-[640px]:mb-1 max-[640px]:px-4 md:mb-4 md:mt-0 md:text-3xl"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.05, duration: 0.3 }}
>
{slides[currentSlide].title}
</motion.h2>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.1, duration: 0.3 }}
className="mb-2 w-full max-w-[600px] max-[640px]:max-w-[75%] max-[640px]:px-4 md:mb-4"
style={{ maxHeight: "calc(100% - 12rem)" }}
>
<div
className="relative w-full overflow-hidden rounded-lg shadow-lg"
style={{ paddingBottom: "56.25%" }}
>
<Image
src={slides[currentSlide].image || ""}
alt={slides[currentSlide].title || ""}
fill
style={{ objectFit: "cover" }}
sizes="(max-width: 768px) 100vw, 600px"
/>
</div>
</motion.div>
<motion.p
className="mb-0 max-w-[600px] whitespace-pre-wrap text-center text-sm text-[#1a1a1a] max-[640px]:mt-1 max-[640px]:px-4 md:text-xl"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.15, duration: 0.3 }}
>
{slides[currentSlide].content}
</motion.p>
</motion.div>
</AnimatePresence>
</motion.div>
)}
</AnimatePresence>
</div>

{currentSlide > 0 && (
<div
className={`fixed ${isLargeScreen ? "right-4 top-1/2 -translate-y-1/2 space-y-2" : "bottom-4 left-1/2 flex -translate-x-1/2 space-x-2"}`}
<motion.div
className={`fixed ${
isLargeScreen
? "right-4 top-1/2 -translate-y-1/2 space-y-2"
: "bottom-4 left-1/2 flex -translate-x-1/2 space-x-2"
}`}
>
{slides.slice(1).map((_, index) => (
<div
<motion.div
key={index + 1}
className={`h-4 w-4 rounded-full ${index + 1 === currentSlide ? "bg-[#108b2d]" : "bg-[#f8fff8]"}`}
className="h-4 w-4 cursor-pointer rounded-full"
animate={{
backgroundColor: index + 1 === currentSlide ? "#108b2d" : "#f8fff8",
scale: index + 1 === currentSlide ? 1.2 : 1,
}}
transition={{
duration: 0.3,
ease: "easeInOut",
}}
onClick={() => {
if (!isScrollingRef.current) {
const targetScroll =
((index + 1) / (slides.length - 1)) * (containerRef.current?.scrollHeight || 0);
lenisRef.current?.scrollTo(targetScroll, {
duration: 1.2,
easing: (t) => t * (2 - t),
});
}
}}
/>
))}
</div>
</motion.div>
)}
</motion.div>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use client";
import BaseInput from "@/app/components/input/text/BaseInput";
import BaseTextArea from "@/app/components/input/textarea/BaseTextArea";
import ImageInput from "@/app/components/input/file/ImageInput/ImageInput";
import DatePickerInput from "@/app/components/input/dateTimeDaypicker/DatePickerInput";
import { cn } from "@/lib/tailwindUtil";
import { useFormContext } from "react-hook-form";
Expand All @@ -12,6 +11,7 @@ import useUploadImages from "@/hooks/queries/user/me/useImageUpload";
import { formatToLocaleDate } from "@/utils/formatters";
import DotLoadingSpinner from "@/app/components/loading-spinner/DotLoadingSpinner";
import { isDirty } from "zod";
import ImageInput from "@/app/components/input/file/ImageInput/ImageInput";

// 워크폼 만들기 - 사장님 - 1-모집내용

Expand Down
Loading
Loading