플로고 Main Flow 구축 기록 (Part 1) - Splash + Onboarding 설계

오병훈·2025년 4월 28일
0

🛤️ Main Flow 설계 시작: Splash ➡️ Onboarding


💡 고민 과정

1. 첫 화면(Splash) 어떻게 구성할까?

  • 후보1: Splash 없이 바로 Onboarding

  • 후보2: 짧은 Splash 화면 → 자연스러운 로딩 → Onboarding 이동

선택: ✅ 후보2

선택 이유:

  • 플로고 프로젝트는 "브랜딩"도 중요했음

  • 첫 인상에서 "Ploggo" 이미지를 보여주는 게 필요했음

  • 짧게라도 브랜드 컬러, 로고를 강조하고 싶었음


2. Splash에서 어떻게 이동할까?

  • 후보1: 서버 사이드에서 리다이렉트

  • 후보2: 클라이언트 사이드 setTimeoutrouter.push

선택: ✅ 후보2

선택 이유:

  • Splash는 "잠시 보여주는" 페이지라 SSR 리다이렉트는 과함

  • 클라이언트에서 자연스럽게 딜레이 후 이동하는 게 UX 좋음

  • framer-motion 애니메이션까지 활용하기 좋음


🚀 구현 흐름

1. Splash 페이지

애니메이션과 함께 2.5초 후 Onboarding으로 이동

// src/app/splash/page.tsx
"use client";

import { motion } from "framer-motion";
import { useEffect } from "react";
import { useRouter } from "next/navigation";

export default function SplashPage() {
  const router = useRouter();

  useEffect(() => {
    const timer = setTimeout(() => {
      router.push("/onboarding");
    }, 2500);
    return () => clearTimeout(timer);
  }, [router]);

  return (
    <div className="flex h-screen items-center justify-center">
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        transition={{ duration: 1 }}
        className="text-center"
      >
        {/* 로고와 텍스트 */}
        <motion.h1 className="text-7xl font-normal text-[#59AC6E]">
          Ploggo
        </motion.h1>
        <motion.p className="text-sm font-bold text-[#59AC6E]">
          동네사람들과 줍깅하기
        </motion.p>
      </motion.div>
    </div>
  );
}

2. Onboarding 페이지

드래그로 이동 가능한 슬라이드 구현 + 마지막에 "시작하기" 버튼

// src/app/onboarding/page.tsx
"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { AnimatePresence } from "framer-motion";
import OnboardingSlide from "@/components/organisms/OnboardingSlide";
import OnboardingControl from "@/components/organisms/OnboardingControl";
import { ONBOARDING_SLIDES } from "@/constants/onboarding";

export default function OnboardingPage() {
  const [page, setPage] = useState(0);
  const [direction, setDirection] = useState(0);
  const router = useRouter();

  const nextPage = () => {
    if (page < ONBOARDING_SLIDES.length - 1) {
      setDirection(1);
      setPage((prev) => prev + 1);
    }
  };

  const prevPage = () => {
    if (page > 0) {
      setDirection(-1);
      setPage((prev) => prev - 1);
    }
  };

  const handleStart = () => {
    router.push("/login");
  };

  return (
    <div className="flex h-screen flex-col items-center justify-between px-4 py-8">
      <div className="flex flex-grow items-center justify-center overflow-hidden">
        <AnimatePresence mode="wait" custom={direction}>
          <OnboardingSlide
            key={page}
            page={page}
            slide={ONBOARDING_SLIDES[page]}
            direction={direction}
            onDragLeft={nextPage}
            onDragRight={prevPage}
          />
        </AnimatePresence>
      </div>

      <OnboardingControl
        total={ONBOARDING_SLIDES.length}
        current={page}
        onDotClick={(idx) => {
          setDirection(idx > page ? 1 : -1);
          setPage(idx);
        }}
        showStart={page === ONBOARDING_SLIDES.length - 1}
        onStartClick={handleStart}
      />
    </div>
  );
}

🔥 고민했던 질문 요약

  • Splash → Onboarding 흐름을 클라이언트에서 자연스럽게 이동시킬까?

    • ✅ 클라이언트 이동 (setTimeout + push)
  • Splash는 "브랜드 노출"용이니까 반드시 짧게라도 필요하다

  • Onboarding은 드래그 UX까지 고려해서 framer-motion을 적극 사용했다

profile
Front-End Developer

0개의 댓글