@@ -21,10 +21,8 @@ import androidx.compose.foundation.layout.offset
2121import androidx.compose.foundation.layout.padding
2222import androidx.compose.foundation.layout.size
2323import androidx.compose.foundation.shape.CircleShape
24- import androidx.compose.foundation.shape.RoundedCornerShape
2524import androidx.compose.material3.Button
2625import androidx.compose.material3.CircularProgressIndicator
27- import androidx.compose.material3.Surface
2826import androidx.compose.material3.Text
2927import androidx.compose.runtime.Composable
3028import androidx.compose.runtime.LaunchedEffect
@@ -38,8 +36,6 @@ import androidx.compose.ui.Modifier
3836import androidx.compose.ui.draw.clip
3937import androidx.compose.ui.graphics.Color
4038import androidx.compose.ui.layout.ContentScale
41- import androidx.compose.ui.text.style.TextAlign
42- import androidx.compose.ui.unit.IntOffset
4339import androidx.compose.ui.unit.dp
4440import androidx.compose.ui.unit.sp
4541import com.nexters.emotia.core.designsystem.component.TypingAnimatedSpeechBubble
@@ -54,6 +50,7 @@ import emotia.core.designsystem.generated.resources.seven
5450import emotia.core.designsystem.generated.resources.six
5551import emotia.core.designsystem.generated.resources.ten
5652import emotia.core.designsystem.generated.resources.third
53+ import org.jetbrains.compose.resources.DrawableResource
5754import org.jetbrains.compose.resources.painterResource
5855import org.koin.compose.viewmodel.koinViewModel
5956
@@ -134,6 +131,23 @@ private fun StoryContent(
134131 val totalSteps = 12
135132 var currentStep by remember { mutableStateOf(0 ) }
136133
134+ // --- 리팩토링된 부분: 각 스텝에 해당하는 이미지를 리스트로 관리 ---
135+ val storyImages: List <DrawableResource > = remember {
136+ listOf (
137+ // 0~2단계는 애니메이션이 복잡하여 별도 처리
138+ Res .drawable.four, // 3단계 (인덱스 0)
139+ Res .drawable.five, // 4단계 (인덱스 1)
140+ Res .drawable.six, // 5단계 (인덱스 2)
141+ Res .drawable.six, // 6단계 (인덱스 3)
142+ Res .drawable.seven, // 7단계 (인덱스 4)
143+ Res .drawable.eight, // 8단계 (인덱스 5)
144+ Res .drawable.nine, // 9단계 (인덱스 6)
145+ Res .drawable.ten, // 10단계 (인덱스 7)
146+ )
147+ }
148+ // 단순 이미지 전환이 일어나는 스텝의 범위
149+ val simpleImageTransitionSteps = 3 .. 10
150+
137151 BoxWithConstraints (
138152 modifier = Modifier
139153 .fillMaxSize()
@@ -152,9 +166,10 @@ private fun StoryContent(
152166
153167 // --- 애니메이션 상태 값 정의 ---
154168 val animationSpecFloat = tween<Float >(durationMillis = 600 )
155- val animationSpecIntOffset = tween<IntOffset >(durationMillis = 600 )
156169
157- // first 이미지 애니메이션 (위로 이동 및 크기 축소)
170+ // --- 각 스텝 별 UI 구성 (복잡한 애니메이션은 기존 로직 유지) ---
171+
172+ // Step 1 & 2: first 이미지 (위로 이동 및 크기 축소)
158173 val firstImageOffsetY by animateDpAsState(
159174 targetValue = if (currentStep >= 1 ) - (screenHeight / 4 ) else 0 .dp,
160175 animationSpec = tween(600 )
@@ -164,17 +179,8 @@ private fun StoryContent(
164179 animationSpec = tween(600 )
165180 )
166181
167- // second 이미지 애니메이션 (위로 이동)
168- val secondImageOffsetY by animateDpAsState(
169- targetValue = if (currentStep == 2 ) - (screenHeight / 2 ) else 0 .dp,
170- animationSpec = tween(600 )
171- )
172-
173- // --- 각 스텝 별 UI 구성 ---
174-
175- // Step 1 & 2: first 이미지
176182 AnimatedVisibility (
177- visible = currentStep <= 1 , // Step 1과 2에서만 보임
183+ visible = currentStep <= 1 ,
178184 exit = fadeOut(animationSpecFloat)
179185 ) {
180186 Image (
@@ -191,8 +197,8 @@ private fun StoryContent(
191197
192198 // Step 2: second 이미지 (하단)
193199 AnimatedVisibility (
194- visible = currentStep == 1 , // Step 2에서만 보임
195- enter = slideInVertically(animationSpecIntOffset ) { it / 2 } + fadeIn(animationSpecFloat),
200+ visible = currentStep == 1 ,
201+ enter = slideInVertically(tween( 600 ) ) { it / 2 } + fadeIn(animationSpecFloat),
196202 exit = fadeOut(animationSpecFloat)
197203 ) {
198204 Image (
@@ -206,157 +212,44 @@ private fun StoryContent(
206212 )
207213 }
208214
209- // Step 3: third(하단) + second(상단) 스택
215+ // Step 3: third(하단) + second(상단) 스택
210216 AnimatedVisibility (
211- visible = currentStep == 2 , // Step 3에서만 보임
217+ visible = currentStep == 2 ,
212218 enter = fadeIn(animationSpecFloat),
213219 exit = fadeOut(animationSpecFloat)
214220 ) {
215221 Column (modifier = Modifier .fillMaxSize()) {
216- // 상단 절반 - second 이미지 (투명도 50%)
217222 Image (
218223 painter = painterResource(Res .drawable.second),
219224 contentDescription = " Second screen (top half)" ,
220- modifier = Modifier
221- .fillMaxWidth()
222- .weight(1f ), // 절반 차지
225+ modifier = Modifier .fillMaxWidth().weight(1f ),
223226 contentScale = ContentScale .Crop ,
224227 alpha = 0.5f
225228 )
226-
227- // 하단 절반 - third 이미지
228229 Image (
229230 painter = painterResource(Res .drawable.third),
230231 contentDescription = " Third screen (bottom half)" ,
231- modifier = Modifier
232- .fillMaxWidth()
233- .weight(1f ), // 절반 차지
232+ modifier = Modifier .fillMaxWidth().weight(1f ),
234233 contentScale = ContentScale .Crop
235234 )
236235 }
237236 }
238237
239-
240- // Step 4: four 이미지로 전환
241- AnimatedVisibility (
242- visible = currentStep == 3 ,
243- enter = fadeIn(animationSpecFloat),
244- exit = fadeOut(animationSpecFloat)
245- ) {
246- Image (
247- painter = painterResource(Res .drawable.four),
248- contentDescription = " Fourth screen" ,
249- modifier = Modifier .fillMaxSize(),
250- contentScale = ContentScale .Crop
251- )
252- }
253-
254- // Step 4
255- AnimatedVisibility (
256- visible = currentStep == 4 ,
257- enter = fadeIn(animationSpecFloat),
258- exit = fadeOut(animationSpecFloat)
259- ) {
260- Image (
261- painter = painterResource(Res .drawable.five),
262- contentDescription = " Fifth screen" ,
263- modifier = Modifier .fillMaxSize(),
264- contentScale = ContentScale .Crop
265- )
266- }
267-
268- // Step 5
238+ // --- 리팩토링된 부분: 3~10단계의 단순 이미지 전환을 하나의 블록으로 처리 ---
269239 AnimatedVisibility (
270- visible = currentStep == 5 ,
240+ visible = currentStep in simpleImageTransitionSteps ,
271241 enter = fadeIn(animationSpecFloat),
272242 exit = fadeOut(animationSpecFloat)
273243 ) {
244+ val imageIndex = (currentStep - simpleImageTransitionSteps.first).coerceIn(storyImages.indices)
274245 Image (
275- painter = painterResource(Res .drawable.six),
276- contentDescription = " Fifth screen" ,
277- modifier = Modifier .fillMaxSize(),
278- contentScale = ContentScale .Crop
279- )
280- }
281- // Step 6
282- AnimatedVisibility (
283- visible = currentStep == 6 ,
284- enter = fadeIn(animationSpecFloat),
285- exit = fadeOut(animationSpecFloat)
286- ) {
287- Image (
288- painter = painterResource(Res .drawable.six),
289- contentDescription = " Fifth screen" ,
246+ painter = painterResource(storyImages[imageIndex]),
247+ contentDescription = " Story image for step ${currentStep + 1 } " ,
290248 modifier = Modifier .fillMaxSize(),
291249 contentScale = ContentScale .Crop
292250 )
293251 }
294252
295- // Step 7
296- AnimatedVisibility (
297- visible = currentStep == 7 ,
298- enter = fadeIn(animationSpecFloat),
299- exit = fadeOut(animationSpecFloat)
300- ) {
301- Image (
302- painter = painterResource(Res .drawable.seven),
303- contentDescription = " Fifth screen" ,
304- modifier = Modifier .fillMaxSize(),
305- contentScale = ContentScale .Crop
306- )
307- }
308-
309- AnimatedVisibility (
310- visible = currentStep == 8 ,
311- enter = fadeIn(animationSpecFloat),
312- exit = fadeOut(animationSpecFloat)
313- ) {
314- Image (
315- painter = painterResource(Res .drawable.eight),
316- contentDescription = " Sixth screen" ,
317- modifier = Modifier .fillMaxSize(),
318- contentScale = ContentScale .Crop
319- )
320- }
321-
322- AnimatedVisibility (
323- visible = currentStep == 9 ,
324- enter = fadeIn(animationSpecFloat),
325- exit = fadeOut(animationSpecFloat)
326- ) {
327- Image (
328- painter = painterResource(Res .drawable.nine),
329- contentDescription = " Sixth screen" ,
330- modifier = Modifier .fillMaxSize(),
331- contentScale = ContentScale .Crop
332- )
333- }
334-
335- AnimatedVisibility (
336- visible = currentStep == 10 ,
337- enter = fadeIn(animationSpecFloat),
338- exit = fadeOut(animationSpecFloat)
339- ) {
340- Image (
341- painter = painterResource(Res .drawable.ten),
342- contentDescription = " Sixth screen" ,
343- modifier = Modifier .fillMaxSize(),
344- contentScale = ContentScale .Crop
345- )
346- }
347-
348- AnimatedVisibility (
349- visible = currentStep == 11 ,
350- enter = fadeIn(animationSpecFloat),
351- exit = fadeOut(animationSpecFloat)
352- ) {
353- Image (
354- painter = painterResource(Res .drawable.ten),
355- contentDescription = " Sixth screen" ,
356- modifier = Modifier .fillMaxSize(),
357- contentScale = ContentScale .Crop
358- )
359- }
360253
361254 // 말풍선
362255 val (speechBubbleText, useAlternativeBackground) = when (currentStep) {
@@ -380,7 +273,6 @@ private fun StoryContent(
380273 exit = fadeOut(tween(300 )),
381274 modifier = Modifier .align(Alignment .BottomCenter )
382275 ) {
383- // 커스텀 말풍선 컴포넌트 호출 및 파라미터 전달
384276 TypingAnimatedSpeechBubble (
385277 fullText = speechBubbleText,
386278 useAlternativeBackground = useAlternativeBackground
@@ -396,18 +288,18 @@ private fun StoryContent(
396288 Box (
397289 modifier = Modifier
398290 .fillMaxSize()
399- .background(Color .Black ), // 전체 배경 어둡게
291+ .background(Color .Black ),
400292 contentAlignment = Alignment .Center
401293 ) {
402294 // 원형 뷰포트
403295 Box (
404296 modifier = Modifier
405- .size(150 .dp) // 원 크기
406- .clip(CircleShape ) // 동그랗게 자름
407- .background(Color .Transparent ) // 원 안은 배경이 그대로 보이도록
297+ .size(150 .dp)
298+ .clip(CircleShape )
299+ .background(Color .Transparent )
408300 ) {
409301 Image (
410- painter = painterResource(Res .drawable.ten), // 보여줄 이미지
302+ painter = painterResource(Res .drawable.ten),
411303 contentDescription = " 마지막 배경" ,
412304 modifier = Modifier .fillMaxSize(),
413305 contentScale = ContentScale .Crop
@@ -439,25 +331,4 @@ private fun StoryContent(
439331 )
440332 }
441333 }
442- }
443-
444- @Composable
445- private fun SpeechBubble (
446- text : String ,
447- modifier : Modifier = Modifier
448- ) {
449- Surface (
450- modifier = modifier.padding(start = 24 .dp, end = 24 .dp, bottom = 100 .dp),
451- color = Color .Black .copy(alpha = 0.7f ),
452- shape = RoundedCornerShape (16 .dp)
453- ) {
454- Text (
455- text = text,
456- color = Color .White ,
457- fontSize = 16 .sp,
458- textAlign = TextAlign .Center ,
459- modifier = Modifier .padding(horizontal = 24 .dp, vertical = 16 .dp),
460- lineHeight = 24 .sp
461- )
462- }
463- }
334+ }
0 commit comments