๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป ํ”„๋กœ์ ํŠธ/๐Ÿฐํ† ๋ผ์™€ ๊ฑฐ๋ถ์ด ๊ฒฝ์ฃผ๊ฒŒ์ž„๐Ÿข

[Vue.js] Vue.js๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ ํ† ๋ผ์™€ ๊ฑฐ๋ถ์ด ๊ฒฝ์ฃผ๊ฒŒ์ž„ ๋งŒ๋“ค๊ธฐ.

by ._.sori 2025. 8. 11.

 

 

 

 

์ฐธ๊ณ ๋กœ Vue.js์— ๋Œ€ํ•ด์„œ ์ž˜ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.

์•„๋ฌด๊ฑฐ๋‚˜ ๋ง‰ ํ•ด๋ณด๋Š” ์ค‘์ด๊ณ  ์˜ณ์€ ์ •๋ณด์ธ์ง€ ์ €๋„ ๋ชจ๋ฆ…๋‹ˆ๋‹ค!

 

 

 

 

ํ† ๋ผ์™€ ๊ฑฐ๋ถ์ด
๊ฒฝ์ฃผ๊ฒŒ์ž„์„
๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค์–ด๋ณด์ž.

 

 

 

 

1. ํ™˜๊ฒฝ

โ–ก WebStrom

: HTML ํŽธ์ง‘๊ธฐ๊ฐ€ ํฌํ•จ๋œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ IDE(Intergrated Development Environment)๋กœ IntelliJ IDEA ํ”Œ๋žซํผ ์œ„์— ๊ตฌ์ถ•๋˜์—ˆ๊ณ  ๋น„์ฃผ์–ผ ์ŠคํŠœ๋””์˜ค๋‚˜ ์ดํด๋ฆฝ์Šค์™€ ๊ฐ™์€ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์— ์ตœ์ ํ™”๋œ ํ†ตํ•ฉ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ ์ œ๊ณตํ•œ๋‹ค.

 

WebStorm

 

WebStorm: The JavaScript and TypeScript IDE, by JetBrains

Make development more productive and enjoyable with WebStorm, the IDE for JavaScript and related technologies.

www.jetbrains.com

 

 

โ–ก Vue.js

: ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•œ JavaScript ํ”„๋ก ํŠธ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ Evan You๊ฐ€ ๊ฐœ๋ฐœํ•œ Vue.js๋Š” ์ตœ์‹  ์›น ๊ฐœ๋ฐœ ํŠธ๋ Œ๋“œ์— ๋งž์ถฐ ๊ฒฝ๋Ÿ‰ํ™”๋œ ๊ตฌ์กฐ์™€ ๊ฐ€์ƒ ๋”(Virtual DOM) ๊ธฐ๋ฐ˜์˜ ์„ฑ๋Šฅ ํ–ฅ์ƒ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

 

Vue.js

 

Vue.js

Vue.js - The Progressive JavaScript Framework

vuejs.org

 

 

โ–ก Vite

: ๋น ๋ฅด๊ณ  ๊ฐ„๊ฒฐํ•œ ๋ชจ๋˜ ์›น ํ”„๋กœ์ ํŠธ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์— ์ดˆ์ ์„ ๋งž์ถฐ ํƒ„์ƒํ•œ ๋นŒ๋“œ ํˆด์ด๋‹ค. Vite๋Š” ํ•ฉ๋ฆฌ์ ์ธ ๊ธฐ๋ณธ ์„ค์ •์„ ์ œ๊ณตํ•œ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ ์ง€์›์ด๋‚˜ ๋‹ค๋ฅธ ๋„๊ตฌ์™€์˜ ํ†ตํ•ฉ์€ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

 

Vite

 

Vite

Vite, ํ”„๋ŸฐํŠธ์—”๋“œ ๊ฐœ๋ฐœ์˜ ์ƒˆ๋กœ์šด ๊ธฐ์ค€

ko.vite.dev

 

 

 

 

 


 

 

 

 

 

2. ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค๊นŒ?

 

โ–ก ํ™”๋ฉด ๊ตฌ์„ฑ

ํ™”๋ฉด์€ ํ™ˆํ™”๋ฉด๊ณผ ๊ฒŒ์ž„์„ ์ง„ํ–‰ํ•˜๋Š” ๊ฒŒ์ž„ํ™”๋ฉด์œผ๋กœ ๊ตฌ์„ฑํ–ˆ๋‹ค. ์‹œ์ž‘ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๊ฒŒ์ž„ ํ™”๋ฉด์œผ๋กœ ๋“ค์–ด๊ฐ€์ง€๋ฉด์„œ ๋ฐ”๋กœ ๊ฒฝ์ฃผ ๊ฒŒ์ž„์ด ์‹œ์ž‘๋˜๋„๋ก ๊ตฌ์ƒํ–ˆ๋‹ค.

์ฒซ๋ฒˆ์งธ ํ™”๋ฉด
๋‘๋ฒˆ์งธ ํ™”๋ฉด

 

 

 

โ–ก ๋™์ž‘ ๊ณผ์ • ๊ตฌ์„ฑ 

์ดˆ๊ธฐ ๊ตฌ์ƒ์—์„œ๋Š” ์ดˆ(second)๊ฐ€ ์•„๋‹ˆ๋ผ ๋ถ„(minute)์„ ๋ฐ›์•„์˜ค๋ คํ–ˆ๋‹ค. ๋ง‰์ƒ ๊ตฌํ˜„ํ•˜๋‹ˆ ๋‚ด๊ธฐ ํ˜•์‹์˜ ๊ฒŒ์ž„์ธ๋ฐ 1๋ถ„ ๋‚ด๋‚ด ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒŒ ๋ชฉ์ ๊ณผ ๋ถ€์ ํ•ฉํ•˜๋‹ค๊ณ  ๋А๊ผˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ดˆ๋กœ ๋ฐ”๊ฟ” ๋žœ๋ค์ฒ˜๋Ÿผ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ”๋€Œ๋„๋ก ํ–ˆ๋‹ค.

์›๋ž˜ ํ† ๋ผ๊ฐ€ ์Šน๋ฆฌํ•˜๋Š” ๋ฒ„์ „์€ ํ† ๋ผ๊ฐ€ ์‰ฌ์ง€ ์•Š๊ณ  ๋‹ฌ๋ ค๊ฐ€๋Š” ๊ฒƒ์ด์—ˆ๋‹ค. ๊ฑฐ๋ถ์ด๋ณด๋‹ค ํ† ๋ผ๊ฐ€ ์†๋ ฅ์ด ๋น ๋ฅด๋‹ค๋ณด๋‹ˆ, ์ค‘๊ฐ„์— ์‰ฌ์ง€ ์•Š๊ณ  ๋‹ฌ๋ฆฌ๋ฉด ๋ˆ„๊ฐ€ ์Šน๋ฆฌํ• ์ง€ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์•„ ๊ธด์žฅ๊ฐ์ด ๋„ˆ๋ฌด ์—†์–ด๋ณด์˜€๋‹ค.  ๊ทธ๋ž˜์„œ ํ† ๊ธฐ๊ฐ€ ์Šน๋ฆฌํ•˜๋Š” ๋ฒ„์ „์—๋„ ์‰ฌ๋Š” ๊ตฌ๊ฐ„์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์–ด๋–ค ๋™๋ฌผ์ด ์Šน๋ฆฌํ• ์ง€ ๋งˆ์ง€๋ง‰๊นŒ์ง€ ๊ฐ€์•ผ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ์กฐ์ •ํ–ˆ๋‹ค.

 

 

 

 

 

 


 

 

 

 

 

3. ์‹ค์ œ ๋™์ž‘ ์žฅ๋ฉด

 

 

 

ํ™ˆ ํ™”๋ฉด

 

 

๊ฒŒ์ž„ ํ™”๋ฉด

 

 

 

 


 

 

 

 

 

4. ๊นƒํ—ˆ๋ธŒ

 

 

 

 

 

 


 

 

 

 

 

5. ์ž‘์„ฑ ์ฝ”๋“œ ๋ณด๊ธฐ_  ํ™ˆํ™”๋ฉด_ HomeView.vue

<template>
  <div class="home-view">
    <img src="@/assets/winnerturtle.png" alt="์ด๊ธด๊ฑฐ๋ถ์ด" class="winner-turtle"/>
    <img src="@/assets/winnerrabbit.png" alt="์ด๊ธดํ† ๋ผ" class="winner-rabbit"/>

    <div class="rabbit-container">
      <img src="../assets/speech1.png" alt="๋งํ’์„ 1" class="speech-bubble1"/>
      <p class="rabbit-text"> ์ œ๊ฐ€ ๋” ์ž˜ํ•ด์šฅ! </p>
    </div>

    <div class="turtle-container">
      <img src="../assets/speech2.png" alt="๋งํ’์„ 2" class="speech-bubble2"/>
      <p class="turtle-text"> ๋‚˜๋ฅผ ๋ฝ‘์•„์ค˜์ž‰~ </p>
    </div>

    <div class="banner">
      <div class="banner1">
        <p class="banner-text1"> ํ† ๋ผ์™€ ๊ฑฐ๋ถ์ด </p>
      </div>

      <div class="banner2">
        <img src="../assets/red.png" alt="๋ฆฌ๋ณธ" class="ribbon1"/>
        <p class="banner-text2"> ํ† ๋ผ์™€ ๊ฑฐ๋ถ์ด ๊ตญ์ œ๋Œ€ํšŒ์— ์˜ค์‹ ๊ฑธ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.</p>
        <p class="banner-text3"> ์ด๋ฒˆ ๋Œ€ํšŒ์—์„œ ํ† ๋ผ์™€ ๊ฑฐ๋ถ์ด ์ค‘ ๋ˆ„๊ฐ€ ์ด๊ธธ์ง€</p>
        <p class="banner-text4"> ์นœ๊ตฌ๋“ค๊ณผ ๋‚ด๊ธฐํ•ด๋ณด์„ธ์š”.</p>
      </div>
    </div>

    <div class="btn-container">
      <button class="main-button" @click="$router.push({ path:'/game' })"> ๋ณด๋Ÿฌ๊ฐ€๊ธฐ </button>
    </div>

  </div>

</template>
ํŠน๋ณ„ํ•œ ์ฝ”๋“œ๋Š” ์—†๋‹ค. ์ด๋ฏธ์ง€ ๋ฐฐ์น˜๋งŒ ํ•˜๊ณ , ๋ฒ„ํŠผ๋งŒ ๋งŒ๋“  ํ™”๋ฉด์ด๋ผ ์–ด๋ ค์šด ๊ฒƒ๋„ ์—†์—ˆ๋‹ค. ์ฒ˜์Œ์—” ์š”์†Œ๋“ค์„ <div ></div>๋กœ ์•ˆ๊ฐ์‹ธ๊ณ , ๊ฐ€์žฅ ์ƒ์œ„ ํด๋ž˜์Šค์ธ <div class="home-view></div>์— ๋ชจ๋“  ์š”์†Œ๋“ค์„ ๋ฐฐ์น˜ํ–ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ๊ฐ€, ํ™”๋ฉด์˜ ๋น„์œจ์ด ๋‹ฌ๋ผ์งˆ ๋•Œ๋งˆ๋‹ค ๋ฐฐ์น˜ํ•ด ๋‘” ์œ„์น˜๊ฐ€ ๊ดด์ƒํ•˜๊ฒŒ ๋ณ€๊ฒฝ๋๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋ฌธ์ œ์ ์„ ์ฐพ๋А๋ผ, ํ•˜๋ฃจ์ข…์ผ ์†Œ๋น„ํ–ˆ๋‹ค. ํ•ด๋‹ต์„ ์ฐพ์ง€ ๋ชปํ•˜๊ณ  ๊ทธ๋™์•ˆ ํ–ˆ๋˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด์—ˆ๋‹ค. ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ๋„ ์–ด๋–ค ํ™”๋ฉด์€ ํ™”๋ฉด ๋น„์œจ์ด ๋‹ฌ๋ผ์ ธ๋„ ๋ฐฐ์น˜๊ฐ€ ํฌ๊ฒŒ ๋ฐ”๋€Œ์ง€ ์•Š์•˜์ง€๋งŒ, ์–ด๋–ค ํ™”๋ฉด์€ ๋ฐฐ์น˜๊ฐ€ ์ด์ƒํ•˜๊ฒŒ ๋ณ€ํ–ˆ๋‹ค. ๋‘ ์ฝ”๋“œ๋ฅผ ๋‘๊ณ  ์ฐจ์ด๋ฅผ ์ฐพ์•˜๋”๋‹ˆ, ๊ทธ์ œ์•ผ ๋ฌธ์ œ์ ์ด ๋ณด์ด๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

๋น„์Šทํ•œ ์œ„์น˜์˜ ์š”์†Œ๋“ค ํ˜น์€ ๋™๋–จ์–ด์ ธ ์žˆ๋Š” ์š”์†Œ๋“ค์€ <div class></div>๋กœ ๋ฌถ์–ด์ค˜์•ผ ์œ„์น˜๊ฐ€ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ๊ฐ€๋Š” ๊ฑธ ๋ง‰์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋˜, ๋‚ด๊ฐ€ ํ–ˆ๋˜ ์ž˜๋ชป๋œ ์ ์€ ๊ณผํ•˜๊ฒŒ position์„ ์‚ฌ์šฉํ–ˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ ๋น„์Šทํ•œ ์œ„์น˜์— ์žˆ๋Š” ์š”์†Œ๋“ค์„ ์ƒ์œ„ ํด๋ž˜์Šค๋กœ ๋ฌถ์–ด ์ƒ์œ„ ํด๋ž˜์Šค์—๋งŒ position์— "absolute"๋ฅผ ์ ์šฉํ–ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ๋ฐ”๊พธ๋‹ˆ ํ™”๋ฉด ๋น„์œจ์— ๋”ฐ๋ผ ์œ„์น˜๊ฐ€ ์™„์ „ํžˆ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ๋ฐ”๋€Œ๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

 

<style> ์ฝ”๋“œ

.winner-rabbit {
  position: absolute;
  width: 28%;
  height: 60%;
  top: -5%;
  left: -2%;
  z-index: 10;
  transform: rotate(20deg);
  transition: transform 0.75s ease;
}
.winner-rabbit:hover {
  transform: rotate(10deg);
}

.winner-turtle {
  position: absolute;
  width: 55%;
  height: 80%;
  top: 18%;
  left: 60%;
  z-index: 10;
  transform: rotate(5deg);
  transition: transform 0.75s ease-in-out;
}
.winner-turtle:hover {
  transform: rotate(13deg);
}
ํ† ๋ผ์™€ ๊ฑฐ๋ถ์ด ๊ทธ๋ฆผ์„ ํฌ๊ฒŒ ๋ฐฐ์น˜ํ–ˆ๋‹ค. :hover๋กœ ์ปค์„œ๋ฅผ ๋Œ€๋ฉด ๊ฐ๋„๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ท€์—ฌ์šด ๋ชจ์…˜๋„ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

์‚ฌ์‹ค ๋Œ€์ถฉ ๋งŒ๋“ค ์ƒ๊ฐ์ด์—ˆ๋Š”๋ฐ, ํ•˜๋‹ค ๋ณด๋‹ˆ ์š•์‹ฌ์ด... ์ƒ๊ฒผ๋‹ค. 3์ฃผ ์ „์— ๋ณธ ๊ฐ€์œ„์†์ด ์ƒ๊ฐ๋‚˜์„œ ์ƒ‰์ƒ๋„ ๋น„์Šทํ•œ ๊ณ„์—ด๋กœ ๋ฐฐ์น˜ํ–ˆ๊ณ , ์กฐ๊ธˆ์€ ์›ƒ๊ธฐ๊ณ  ์‹ถ๊ธฐ๋„ ํ–ˆ๊ณ  ์กฐ๊ธˆ์€ ๊ท€์—ฌ์›Œ ๋ณด์ด๊ณ  ์‹ถ์–ด์„œ ๋‚˜๋ฆ„ ๋””์ž์ธ์— ์‹ ๊ฒฝ์„ ์ผ๋‹ค.(์•„๋ฌด๋„ ์•ˆ ๋А๋‚„์ง€๋„)

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋ฉด์„œ ๋˜ ํ•˜๋‚˜ ๊นจ๋‹ฌ์€ ์‚ฌ์‹ค์€ transition์˜ ์œ„์น˜์ด๋‹ค. ๋‚˜๋Š” ๊ทธ๋™์•ˆ :hover๊ฐ€ ๋ถ™์€ ํด๋ž˜์Šค ๋‚ด์— transition์„ ๋ฐฐ์น˜ํ–ˆ๋‹ค. ์ปค์„œ๋ฅผ ๋Œ€๋ฉด ์›€์ง์ž„์ด ์ƒ๊ธฐ๊ธธ ์›ํ•˜๋‹ˆ, ๋‹น์—ฐํžˆ ๊ทธ๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š” ์ค„ ์•Œ์•˜๋‹ค.

์ด๋ ‡๊ฒŒ ๋งŒ๋“ค๋ฉด ์ปค์„œ๋ฅผ ๋Œ”์„ ๋•Œ๋งŒ ์†๋„๊ฐ€ ์กฐ์ ˆ๋˜์–ด ์›€์ง์ž„์ด ๋ฐœ์ƒํ•˜๊ณ , ๋–ผ๋Š” ์ˆœ๊ฐ„ transition์€ :hover ์•ˆ์— ์žˆ์œผ๋‹ˆ ์†๋„๊ฐ€ ์กฐ์ ˆ๋˜์ง€ ์•Š๊ณ  ์›๋ž˜์˜ ๋ชจ์Šต์œผ๋กœ ๋Œ์•„๊ฐ”๋‹ค. ์–‘๋ฐฉํ–ฅ์œผ๋กœ ์†๋„ ์กฐ์ ˆ๊ณผ ์›€์ง์ž„์ด ๋ฐœ์ƒ๋˜๊ธธ ์›ํ•˜๋ฉด, :hover๊ฐ€ ๋ถ™์€ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ์›๋ž˜์˜ ํด๋ž˜์Šค์— transition์„ ๋ฐฐ์น˜ํ•ด์•ผ ํ•œ๋‹ค. 

์ง์ ‘ ํ•˜๋‚˜ํ•˜๋‚˜ ์ฐพ์•„์„œ ๋ˆŒ๋Ÿฌ์„œ ํ•˜๋‹ค ๋ณด๋‹ˆ, ์ด๋ ‡๊ฒŒ ๋„˜๊ฒจ์งš๋Š” ๋ถ€๋ถ„์ด ์ƒ๊ธด ๊ฒƒ ๊ฐ™๋‹ค. ์ด๋Ÿฐ ๋ถ€๋ถ„์€ ๋ฐ˜์„ฑํ•ด์•ผ๊ฒ ๋‹ค. ์ข€ ์ œ๋Œ€๋กœ ์ฐพ์•„๋ณด๊ธฐ๋กœ.

 

 

<style> ์ฝ”๋“œ

.btn-container{
  position: absolute;
  width: 100%;
  height: 20%;
  top: 90%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
}
.main-button {
  width: 20%;
  height: 38%;
  font-size: 1.7rem;
  font-weight:  bold;
  font-family: Danjo-bold-Regular;
  border:  white solid 4px;
  border-radius: 40px;
  color: #b1791c;
  background: #89f8b4;
  cursor: pointer;
  transition: background 0.4s ease, border 0.4s ease, color 0.4s ease;
}
.main-button:hover {
  background: #b1791c;
  color: #89f8b4;
  border:  white solid 7px;
}
.btn-container๋กœ ๋ฒ„ํŠผ์„ ๊ฐ์‹ผ ๋’ค, ๋ฒ„ํŠผ์„ ๋งŒ๋“ค์—ˆ๋‹ค. ํ™”๋ฉด ๋น„์œจ์ด ๋‹ฌ๋ผ์ง€๋ฉด ๋ฒ„ํŠผ์ด ์œ„๋กœ ํŠ€์–ด๋ฒ„๋ฆฌ๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ–ˆ๋Š”๋ฐ, ์ด๋ ‡๊ฒŒ ๋งŒ๋“œ๋‹ˆ ์ ์–ด๋„ ๋ง๋„ ์•ˆ๋˜๋Š” ๊ณณ์— ๋ฒ„ํŠผ์ด ์žˆ์ง„ ์•Š๊ฒŒ ๋๋‹ค. 

 

 

 

 

 


 

 

 

 

 

5. ์ž‘์„ฑ ์ฝ”๋“œ ๋ณด๊ธฐ_  ํ™ˆํ™”๋ฉด_ MainView.vue

<template>
  <div class="main-view">

    <button class="game-return" @click="reload"> ๋‹ค์‹œํ•˜๊ธฐ </button>
    <button class="main-return" @click="$router.push('/home')"> ๋ฉ”์ธํ™”๋ฉด </button>
    <button class="game-start" @click="gameStart"> ์‹œ์ž‘ </button>

    <div class="rabbit-ground">
      <div class="rabbit-content">
        <img src="../assets/runrabbit.png" alt="๋‹ฌ๋ฆฌ๋Š”ํ† ๋ผ" class="running-rabbit"
             :class="{run: rabbitRunning, stop: rabbitStopping}"/>
        <div class="rabbit-goalline"/>
        <img src="../assets/biggreen.png" alt="ํ’€๋ฐญ" class="rabbit-green01" />
        <img src="../assets/biggreen.png" alt="ํ’€๋ฐญ" class="rabbit-green02" />
        <img src="../assets/biggreen.png" alt="ํ’€๋ฐญ" class="rabbit-green03" />
      </div>
    </div>

    <div class="turtle-ground">
      <div class="turtle-content">
        <img src="../assets/runturtle.png" alt="๋‹ฌ๋ฆฌ๋Š” ๊ฑฐ๋ถ์ด" class="running-turtle" :class="{run: turtleRunning}"/>
        <div class="turtle-goalline"/>
        <img src="../assets/sea.png" alt="ํŒŒ๋„"  class="turtle-sea01"/>
        <img src="../assets/sea.png" alt="ํŒŒ๋„"  class="turtle-sea02"/>
        <img src="../assets/sea.png" alt="ํŒŒ๋„"  class="turtle-sea03"/>
      </div>
    </div>

  </div>

</template>
์ฝ”๋“œ๋ฅผ ์ „๋ฐ˜์ ์œผ๋กœ ์„ค๋ช… ํ›„, ๋กœ์ง์ด ์–ด๋–ป๊ฒŒ ์ง„ํ–‰๋˜๋Š”์ง€ ๋” ์ž์„ธํ•œ ์„ค๋ช…์€ ๋‹ค์Œ ๋ธ”๋กœ๊ทธ์— ์ ์–ด๋ณด๊ฒ ๋‹ค.

spring์—์„œ๋Š” ๋ฒ„ํŠผ์„ ํ˜„์žฌ ํŽ˜์ด์ง€ ๊ฒฝ๋กœ๋กœ ์—ฐ๊ฒฐํ•˜๋ฉด ์ƒˆ๋กœ๊ณ ์นจ์ด ๋๋‹ค. ๋‹น์—ฐํžˆ Vue์—์„œ๋„ ๊ทธ๋ ‡๊ฒŒ ๋  ์ค„ ์•Œ๊ณ  ์ฒ˜์Œ์—” ๋‹ค์‹œํ•˜๊ธฐ ๋ฒ„ํŠผ์— @click="$router.push('/game')์„ ๋„ฃ์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ทธ๋ƒฅ ๋ฒ„ํŠผ ๋งŒ๋“ค๊ณ  ๋ˆ„๋ฅธ ์‚ฌ๋žŒ ๋๋‹ค. ์ƒˆ๋กœ๊ณ ์นจ์ด ์•ˆ๋˜๋Š” ๊ฑธ ์ฒ˜์Œ ์•Œ์•˜๋‹ค. ๊ทธ๋ž˜์„œ reload๋ฅผ ํ•ด์คฌ๋‹ค. methods์— window.location.reload();๋ฅผ ํ•ด์ฃผ๋ฉด ๋๋‹ค.

rabbit-content๋ฅผ ๋ณด๋ฉด img๊ฐ€ ์žˆ๊ณ  runnig-rabbit ํด๋ž˜์Šค๊ฐ€ ์žˆ๋‹ค. ์ด ํ† ๋ผ ๊ทธ๋ฆผ์ด ์—ด์‹ฌํžˆ ์›€์ง์—ฌ์„œ ๊ฒฐ์Šน์„ ๊นŒ์ง€ ๊ฐˆ ๊ฒƒ์ด๋‹ค. ์ด ํ† ๋ผ์—๊ฒŒ ๋‘๊ฐ€์ง€ ์กฐ๊ฑด์ด ์ฃผ์›Œ์ง„๋‹ค. ํ˜„์žฌ ์‹œ๊ฐ„์„ ๋ฐ›์•„์™€์„œ, ์ง์ˆ˜์ด๋ฉด ํ† ๋ผ๊ฐ€ ๊ฒฐ์Šน์„ ์— ๋จผ์ € ๋„์ฐฉํ•œ๋‹ค. ๋งŒ์•ฝ ํ™€์ˆ˜์ด๋ฉด ํ† ๋ผ๊ฐ€ ๋‚˜๋ฌด ์•„๋ž˜์„œ ๋„ˆ๋ฌด ์˜ค๋ž˜ ์‰ฌ์–ด ๊ฒฐ์Šน์„ ์— ๋Šฆ๊ฒŒ ๋„์ฐฉํ•˜๊ฒŒ ๋œ๋‹ค.

๊ทธ๋ž˜์„œ run์€ ๋œ ์‰ฌ๋Š” ๋กœ์ง์ด ๋“ค์–ด๊ฐ€๊ณ , stop์€ ์˜ค๋ž˜ ์‰ฌ๋Š” ๋กœ์ง์ด ๋“ค์–ด๊ฐ„๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฒŒ์ž„ ์Šคํƒ€ํŠธ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ฆฌ๋ฉด ํ˜„์žฌ ์‹œ๊ฐ์„ ๋ฐ›์•„ ์ง์ˆ˜๋ฉด runningRabbit์ด true๊ฐ€ ๋˜๊ณ , ํ™€์ˆ˜๋ฉด stoppingRabbit์ด true๊ฐ€ ๋œ๋‹ค. 

๊ฑฐ๋ถ์ด๋Š” ์–ธ์ œ๋‚˜ ๊ฐ™์€ ์†๋„๋กœ ์—ด์‹ฌํžˆ ๊ฑธ์–ด๊ฐ„๋‹ค. ๐Ÿข๐Ÿข๐Ÿข

 

 

<style> ์ฝ”๋“œ

@keyframes rabbit-run {
  0% {
    left: -10%;
  }
  40% {
    left: 50%;
  }
  60% {
    left: 50%;
  }
  100% {
    left: 90%;
  }
}

.running-rabbit{
  position: fixed;
  top: 9%;
  left: -10px;
  width:20%;
  z-index: 7;
}
.running-rabbit.run{
  animation: rabbit-run 5s linear forwards;
}
.running-rabbit.stop {
  animation: rabbit-run 7s ease-in-out forwards;
}


@keyframes turtle-run {
  0% {
    left: -10%;
  }
  100% {
    left: 90%;
  }
}
.running-turtle{
  position: absolute;
  bottom: 3.5%;
  left: -10px;
  width:20%;
  z-index: 7;
}
.running-turtle.run {
  animation: turtle-run 6s linear forwards;
}

 

 

animation

: ํŠธ๋žœ์ง€์…˜๋ณด๋‹ค ํ›จ์”ฌ ๋” ๊ทœ๋ชจ๊ฐ€ ํฌ๊ณ  ๋ณต์žกํ•˜๋ฉฐ ๋‹ค์–‘ํ•œ ๋Šฅ๋ ฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋–„๋ฌธ์— ๋” ์ •๋ฐ€ํ•œ ํšจ๊ณผ๋ฅผ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

@keyframs

: animation์˜ ์†์„ฑ๊ณผ ์ค‘๊ฐ„ ์ƒํƒœ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ฒ˜์Œ์—๋Š” transition์œผ๋กœ ๊ตฌ์ƒํ•  ์ƒ๊ฐ์ด์—ˆ๋‹ค. ์ฒ˜์Œ๋ถ€ํ„ฐ transition ๊ณต๋ถ€ํ•˜๋‹ค ๋งŒ๋“ค์–ด๋ณด๊ณ  ์‹ถ์–ด์ง„ ํ”„๋กœ์ ํŠธ์˜€๋‹ค. ๊ทธ๋Ÿฐ๋ฐ transition์„ ์‚ฌ์šฉํ•˜๋‹ˆ, ์›€์ง์ž„์ด ๋๋‚˜๋ฉด ๋‹ค์‹œ ์›๋ž˜ ์ž๋ฆฌ๋กœ ๋Œ์•„๊ฐ”๋‹ค. ์ „์— vue ๊ณต์‹ ๋ฌธ์„œ์— animation์„ ๋ดค๋˜๊ฒŒ ๊ธฐ์–ต๋‚˜ animation์„ ์ด์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

@keyframs๋กœ rabbit์ด ์›€์ง์ผ ๊ฑฐ๋ฆฌ๋ฅผ ์„ค์ •ํ–ˆ๋‹ค. ํ† ๋ผ๊ฐ€ ๊ฒฐ์Šน์ „์— ๋จผ์ € ๊ณจ์ธํ•˜๋Š” ์‹œ๊ฐ„์€ 5์ดˆ๋กœ ์žก์•˜๊ณ , ๊ณจ์ธํ•˜์ง€ ๋ชปํ•˜๋Š” ์‹œ๊ฐ„์€ 7์ดˆ๋กœ ์žก์•˜๋‹ค. @keyframs์˜ ์ง„ํ–‰๋ฅ ์€ ์„ค์ •ํ•œ ์‹œ๊ฐ„์„ ๋น„์œจ๋กœ ๋งž์ถฐ์ง€๋Š” ๋“ฏ ํ•˜๋‹ค. ์• ๋‹ˆ๋ฉ”์ด์…˜ ์œ„์น˜๊ฐ€ ๋งˆ์ง€๋ง‰ ์œ„์น˜์— ์œ ์ง€๋˜๋„๋ก forwards๋ฅผ ๋ถ™์˜€๋‹ค.

 

 

<script>
import {ref} from "vue";

const currentSeconds = ref(new Date().getSeconds());

export default {
  name: 'MainView',
  data() {
    return {
      rabbitRunning: false,
      rabbitStopping: false,
      turtleRunning: false,
    }
  },
  methods: {
    gameStart() {
      if(currentSeconds.value % 2 === 0) {
        this.rabbitRunning = true;
      } else  {
        this.rabbitStopping = true;
      }
      this.turtleRunning = true;
    },
    reload() {
      window.location.reload();
    }
  }
}

</script>
์ดˆ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„ methods์—์„œ ํ•ด๋‹น ์ดˆ๊ฐ€ ์ง์ˆ˜์ด๋ฉด rabbitRunning์ด true๊ฐ€ ๋˜๋„๋ก ํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  0์œผ๋กœ ๋–จ์–ด์ง€์ง€ ์•Š์€ ๋‚˜๋จธ์ง€ ๊ฐ’์€ rabbitStopping์ด true๊ฐ€ ๋˜๋„๋ก ํ–ˆ๋‹ค. ๊ฑฐ๋ถ์ด๋Š” ์–ธ์ œ๋‚˜ gameStrat๊ฐ€ ๋ˆŒ๋ฆฌ๋ฉด ๋‹ฌ๋ฆฌ๋„๋ก ํ–ˆ๋‹ค.