Skip to content

Commit 55766eb

Browse files
committed
(fix) 애니메이션 추가
1 parent 128e012 commit 55766eb

3 files changed

Lines changed: 133 additions & 2 deletions

File tree

src/pages/BattleAnimation.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import "../styles/cannon.css";
2+
3+
interface BattleProps {
4+
fire: boolean;
5+
explode: boolean;
6+
result: string | null;
7+
}
8+
9+
export default function Battle({ fire, explode, result }: BattleProps) {
10+
// 아무 상태도 아니면 렌더링 안 함
11+
if (!fire && !explode) return null;
12+
13+
return (
14+
<div className="battle-field">
15+
{/* 대포 */}
16+
<div className={`cannon ${fire ? "fire" : ""}`}>🧨</div>
17+
18+
{/* 포탄 */}
19+
{fire && <div className="bullet" />}
20+
21+
{/* 폭발 */}
22+
{explode && (
23+
<div className="explosion">
24+
💥
25+
<div className="result-text">{result}</div>
26+
</div>
27+
)}
28+
</div>
29+
);
30+
}

src/pages/EventMainPage.tsx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { apiFetch } from "../utils/apiFetch";
2222
import axios from 'axios';
2323
import SockJS from 'sockjs-client';
2424
import Stomp from 'stompjs';
25+
import Battle from "./BattleAnimation";
2526

2627
type Comment = {
2728
id: string;
@@ -136,6 +137,11 @@ export default function EventMainPage() {
136137
});
137138
const [cannonLoading, setCannonLoading] = useState(false);
138139

140+
//대포
141+
const [fire, setFire] = useState(false);
142+
const [explode, setExplode] = useState(false);
143+
const [result, setResult] = useState<string | null>(null);
144+
139145
const formatDateOnly = (isoString: string) => {
140146
if (!isoString) return "";
141147

@@ -192,8 +198,21 @@ export default function EventMainPage() {
192198
const client = Stomp.over(socket);
193199
client.connect({}, () => {
194200
client.subscribe(`/sub/game/${eventId}/result`, (msg: any) => {
195-
console.log('💥 결과:', msg.body);
196-
alert(msg.body);
201+
setResult(msg.body);
202+
203+
// 1. 발사 시작
204+
setFire(true);
205+
206+
// 2. 날아간 뒤 폭발
207+
setTimeout(() => {
208+
setExplode(true);
209+
}, 800);
210+
211+
// 3. 전체 종료
212+
setTimeout(() => {
213+
setFire(false);
214+
setExplode(false);
215+
}, 2500);
197216
});
198217
});
199218
setStompClient(client);
@@ -1581,6 +1600,11 @@ export default function EventMainPage() {
15811600
</div>
15821601
</DialogContent>
15831602
</Dialog>
1603+
<Battle
1604+
fire={fire}
1605+
explode={explode}
1606+
result={result}
1607+
/>
15841608
</div>
15851609
);
15861610
}

src/styles/cannon.css

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
.battle-field {
2+
position: fixed;
3+
inset: 0;
4+
background: radial-gradient(circle at bottom left, #111, #000);
5+
overflow: hidden;
6+
z-index: 9999;
7+
}
8+
9+
.cannon {
10+
position: absolute;
11+
bottom: 60px;
12+
left: 60px;
13+
font-size: 64px;
14+
transform-origin: center;
15+
}
16+
17+
.cannon.fire {
18+
animation: recoil 0.3s ease-out;
19+
}
20+
21+
@keyframes recoil {
22+
0% { transform: translateX(0); }
23+
50% { transform: translateX(-15px); }
24+
100% { transform: translateX(0); }
25+
}
26+
27+
.bullet {
28+
position: absolute;
29+
bottom: 90px;
30+
left: 110px;
31+
width: 18px;
32+
height: 18px;
33+
background: orange;
34+
border-radius: 50%;
35+
box-shadow: 0 0 12px orange;
36+
animation: fly 0.8s linear forwards;
37+
}
38+
39+
@keyframes fly {
40+
0% {
41+
transform: translate(0, 0);
42+
}
43+
100% {
44+
transform: translate(calc(100vw - 200px), -300px);
45+
}
46+
}
47+
48+
.explosion {
49+
position: absolute;
50+
top: 35%;
51+
right: 20%;
52+
font-size: 80px;
53+
animation: explode 0.4s ease-out;
54+
text-align: center;
55+
}
56+
57+
@keyframes explode {
58+
0% {
59+
transform: scale(0.3);
60+
opacity: 0;
61+
}
62+
60% {
63+
transform: scale(1.4);
64+
opacity: 1;
65+
}
66+
100% {
67+
transform: scale(1);
68+
}
69+
}
70+
71+
.result-text {
72+
margin-top: 16px;
73+
font-size: 36px;
74+
font-weight: bold;
75+
color: #fff;
76+
text-shadow: 0 0 10px red;
77+
}

0 commit comments

Comments
 (0)