Skip to content

Commit

Permalink
refactor:ResultLoading.tsx를 EmojiAnimation.tsx와 TypingAnimation.tsx로 …
Browse files Browse the repository at this point in the history
…분리시킴
  • Loading branch information
parknew0 committed Aug 28, 2024
1 parent da0e6a1 commit 3a64b3a
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 74 deletions.
20 changes: 20 additions & 0 deletions src/components/display/EmojiAnimation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { useState, useEffect } from "react";
import { ZoomAnimation } from "@/pages/ResultLoading.style";


const EmojiAnimation: React.FC = () => {
const emojis = ["🐶", "🏃‍♂️", "🏋️", "🏓", "🎤", "⚽", "🎸"];
const [currentEmojiIndex, setCurrentEmojiIndex] = useState(0);

useEffect(() => {
const emojiInterval = setInterval(() => {
setCurrentEmojiIndex((prevIndex) => (prevIndex + 1) % emojis.length);
}, 1000); // 1초마다 이모지를 변경

return () => clearInterval(emojiInterval);
}, []);

return <ZoomAnimation>{emojis[currentEmojiIndex]}</ZoomAnimation>;
};

export default EmojiAnimation;
77 changes: 77 additions & 0 deletions src/components/display/TypingAnimation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { useState, useEffect } from "react";
import Hangul from "hangul-js";
import { TypingText } from "@/pages/ResultLoading.style";

interface TypingAnimationProps {
texts: string[];
typingInterval: number;
deleteInterval: number;
waitInterval: number;
}

const TypingAnimation: React.FC<TypingAnimationProps> = ({
texts,
typingInterval,
deleteInterval,
waitInterval,
}) => {
const [displayedText, setDisplayedText] = useState("");
const [currentTextIndex, setCurrentTextIndex] = useState(0);
const [isCursorBlinking, setIsCursorBlinking] = useState(false);

useEffect(() => {
const disassembled = Hangul.disassemble(texts[currentTextIndex]);
let index = 0;
let isDeleting = false;
let typeTimeout: NodeJS.Timeout;

const handleTyping = () => {
if (!isDeleting) {
setIsCursorBlinking(false); // 타이핑 중에는 커서 깜빡임 비활성화

if (index <= disassembled.length) {
const nextText = Hangul.assemble(disassembled.slice(0, index));
setDisplayedText(nextText);
index++;
} else {
setIsCursorBlinking(true); // 모든 텍스트가 타이핑되면 커서 깜빡임 활성화
setTimeout(() => {
isDeleting = true;
index = texts[currentTextIndex].length;
setIsCursorBlinking(false); // 삭제 중에도 커서 깜빡임 비활성화
handleTyping();
}, waitInterval);
return;
}
} else {
if (index > 0) {
setDisplayedText((prevText) => prevText.slice(0, index - 1));
index--;
} else {
setCurrentTextIndex((prevIndex) => (prevIndex + 1) % texts.length);
isDeleting = false;
setDisplayedText("");
clearTimeout(typeTimeout);
setIsCursorBlinking(true); // 다음 텍스트로 이동하기 전 깜빡임 활성화
return;
}
}

typeTimeout = setTimeout(handleTyping, isDeleting ? deleteInterval : typingInterval);
};

typeTimeout = setTimeout(handleTyping, typingInterval);

return () => clearTimeout(typeTimeout);
}, [currentTextIndex]);

return (
<TypingText isCursorBlinking={isCursorBlinking}>
<h1 css={{ fontFamily: "NanumSquareNeo", fontSize: "25px", fontWeight: 100 }}>
{displayedText}
</h1>
</TypingText>
);
};

export default TypingAnimation;
8 changes: 4 additions & 4 deletions src/pages/ResultLoading.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const TypingText = styled.div<{ isCursorBlinking: boolean }>`
display: inline-flex;
align-items: center;
position: relative;
min-height: 1.5em; /* 타이핑 텍스트 영역의 최소 높이 설정 */
min-height: 1.5em;
&::after {
content: "";
Expand All @@ -36,9 +36,9 @@ export const TypingText = styled.div<{ isCursorBlinking: boolean }>`
height: 1em;
background-color: black;
position: absolute;
right: -8px; /* 오른쪽으로 약간 이동 */
bottom: 5px; /* 아래쪽으로 약간 이동 */
animation: ${({ isCursorBlinking }) => (isCursorBlinking ? 'blink 0.7s steps(1) infinite' : 'none')}; /* 조건에 따라 깜빡임 */
right: -8px;
bottom: 5px;
animation: ${({ isCursorBlinking }) => (isCursorBlinking ? 'blink 0.7s steps(1) infinite' : 'none')};
}
@keyframes blink {
Expand Down
84 changes: 14 additions & 70 deletions src/pages/ResultLoading.tsx
Original file line number Diff line number Diff line change
@@ -1,85 +1,29 @@
import React, { useState, useEffect } from "react";
import Hangul from "hangul-js"; //npm install hangul-js 필요
import { LoadingContainer, ZoomAnimation, TypingText } from "./ResultLoading.style";
import React from "react";
import TypingAnimation from "../components/display/TypingAnimation";
import EmojiAnimation from "../components/display/EmojiAnimation";
import { LoadingContainer } from "./ResultLoading.style";

const ResultLoading: React.FC = () => {
const emojis = ["🐶", "🏃‍♂️", "🏋️", "🏓", "🎤", "⚽", "🎸"];
const [currentEmojiIndex, setCurrentEmojiIndex] = useState(0);
const [displayedText, setDisplayedText] = useState("");
const [currentTextIndex, setCurrentTextIndex] = useState(0);
const [isCursorBlinking, setIsCursorBlinking] = useState(false); // 커서 깜빡임 상태
const texts = [
"당신의 취향을 분석하는 중...",
"잠시만 기다려 주세요...",
"취향 분석 중...",
"곧 당신의 동아리 운명을 공개합니다...!",
"동아리 운명 분석 중... ",
"... 설레지 않나요?",
];

const typingInterval = 30; // 타이핑 속도
const deleteInterval = 300 / texts[currentTextIndex].length; // 삭제 속도
const waitInterval = 1500; // 타이핑 이후 삭제 전까지 대기 시간

useEffect(() => {
const emojiInterval = setInterval(() => {
setCurrentEmojiIndex((prevIndex) => (prevIndex + 1) % emojis.length);
}, 1000); // 1초마다 이모지를 변경

return () => clearInterval(emojiInterval);
}, []);

useEffect(() => {
const disassembled = Hangul.disassemble(texts[currentTextIndex]);
let index = 0;
let isDeleting = false;
let typeTimeout: NodeJS.Timeout;

const handleTyping = () => {
if (!isDeleting) {
setIsCursorBlinking(false); // 타이핑 중에는 커서 깜빡임을 비활성화

if (index <= disassembled.length) {
const nextText = Hangul.assemble(disassembled.slice(0, index));
setDisplayedText(nextText);
index++;
} else {
// 모든 텍스트가 타이핑되면 커서 깜빡임 활성화
setIsCursorBlinking(true);
setTimeout(() => {
isDeleting = true;
index = texts[currentTextIndex].length;
setIsCursorBlinking(false); // 삭제 중에도 커서 깜빡임 비활성화
handleTyping();
}, waitInterval);
return;
}
} else {
if (index > 0) {
setDisplayedText((prevText) => prevText.slice(0, index - 1));
index--;
} else {
setCurrentTextIndex((prevIndex) => (prevIndex + 1) % texts.length);
isDeleting = false;
setDisplayedText("");
clearTimeout(typeTimeout);
setIsCursorBlinking(true); // 다음 텍스트로 이동하기 전 깜빡임 활성화
return;
}
}

typeTimeout = setTimeout(handleTyping, isDeleting ? deleteInterval : typingInterval);
};

typeTimeout = setTimeout(handleTyping, typingInterval);

return () => clearTimeout(typeTimeout);
}, [currentTextIndex]);
const typingInterval = 30;
const deleteInterval = 10;
const waitInterval = 1500;

return (
<LoadingContainer>
<TypingText isCursorBlinking={isCursorBlinking}>{displayedText}</TypingText>
<ZoomAnimation>{emojis[currentEmojiIndex]}</ZoomAnimation>
<TypingAnimation
texts={texts}
typingInterval={typingInterval}
deleteInterval={deleteInterval}
waitInterval={waitInterval}
/>
<EmojiAnimation />
</LoadingContainer>
);
};
Expand Down

0 comments on commit 3a64b3a

Please sign in to comment.