-
- {`영수증으로\nAI 음식 리뷰 남겨요`}
-
+
손쉬운 음식 리뷰 작성
diff --git a/src/components/ui/AnimationText/AnimationText.tsx b/src/components/ui/AnimationText/AnimationText.tsx
new file mode 100644
index 0000000..603baa1
--- /dev/null
+++ b/src/components/ui/AnimationText/AnimationText.tsx
@@ -0,0 +1,94 @@
+import React, { useEffect, useState } from "react";
+
+import classNames from "classnames";
+
+import styles from "@/components/ui/Text/Text.module.scss";
+
+interface Letter {
+ char: string;
+ id: number;
+}
+
+const AnimationText: React.FC = () => {
+ const [firstLineLetters, setFirstLineLetters] = useState
([]);
+ const [secondLineLetters, setSecondLineLetters] = useState([]);
+ const [hasAnimated, setHasAnimated] = useState(false);
+
+ useEffect(() => {
+ if (hasAnimated) return;
+ setHasAnimated(true);
+
+ const firstLine = "영수증으로";
+ const firstLetters = firstLine.split("").map((char, index) => ({
+ char,
+ id: index,
+ }));
+ setFirstLineLetters(firstLetters);
+
+ const firstLineDelay = firstLine.length * 20 + 100;
+ setTimeout(() => {
+ const secondLine = "AI 음식 리뷰 남겨요";
+ const secondLetters = [...secondLine].map((char, index) => ({
+ // split("") 대신 [...string] 사용
+ char,
+ id: index,
+ }));
+ setSecondLineLetters(secondLetters);
+ }, firstLineDelay);
+ }, [hasAnimated]);
+
+ return (
+
+
+ {firstLineLetters.map((letter, index) => (
+
+ {letter.char}
+
+ ))}
+
+
+ {secondLineLetters.map((letter, index) => (
+
+ {letter.char}
+
+ ))}
+
+
+ );
+};
+
+export default AnimationText;
diff --git a/src/components/ui/Text/Text.module.scss b/src/components/ui/Text/Text.module.scss
index e3442af..96fed48 100644
--- a/src/components/ui/Text/Text.module.scss
+++ b/src/components/ui/Text/Text.module.scss
@@ -111,3 +111,48 @@
justify-content: center;
}
}
+
+.TitleWrapper {
+ height: 5.25rem;
+}
+
+.word {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+
+ .letter {
+ display: inline-block;
+ opacity: 0;
+ filter: blur(8px);
+ transform: translateY(20px);
+ transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
+
+ &.appear {
+ opacity: 1;
+ filter: blur(0);
+ transform: translateY(0);
+ }
+ }
+}
+
+@keyframes textBlur {
+ 0% {
+ opacity: 0;
+ filter: blur(8px);
+ transform: translateY(20px);
+ }
+
+ 100% {
+ opacity: 1;
+ filter: blur(0);
+ transform: translateY(0);
+ }
+}
+
+.space {
+ width: 0.4rem;
+ opacity: 1;
+ visibility: visible;
+}