[miniProjects] 34_Animated Countdown

보리·2023λ…„ 6μ›” 23일
0

miniProjects

λͺ©λ‘ 보기
34/47

34_Animated Countdown

πŸ’»μ£Όμ œ : replayμ‹œ 3λΆ€ν„° 0κΉŒμ§€ μ• λ‹ˆλ©”μ΄μ…˜μ΄ λ‚˜νƒ€λ‚¨.

✨JS

const nums = document.querySelectorAll('.nums span')
const counter = document.querySelector('.counter')
const finalMessage = document.querySelector('.final')
const replay = document.querySelector('#replay')

runAnimation()

function resetDOM() {
  counter.classList.remove('hide')
  finalMessage.classList.remove('show')

  nums.forEach((num) => {
    num.classList.value = ''
  })

  nums[0].classList.add('in')
}

function runAnimation() {
  nums.forEach((num, idx) => {
    const nextToLast = nums.length - 1

    num.addEventListener('animationend', (e) => {
      if (e.animationName === 'goIn' && idx !== nextToLast) {
        num.classList.remove('in')
        num.classList.add('out')
      } else if (e.animationName === 'goOut' && num.nextElementSibling) {
        num.nextElementSibling.classList.add('in')
      } else {
        counter.classList.add('hide')
        finalMessage.classList.add('show')
      }
    })
  })
}

replay.addEventListener('click', () => {
  resetDOM()
  runAnimation()
})
  • function resetDOM() { ... }
    DOM μš”μ†Œλ“€μ˜ 초기 μƒνƒœλ₯Ό μž¬μ„€μ •ν•œλ‹€.

  • nums.forEach((num) => { ... })
    nums λ°°μ—΄μ˜ 각 μš”μ†Œμ— λŒ€ν•΄μ„œ λ°˜λ³΅λ¬Έμ„ μ‹€ν–‰ν•œλ‹€. 각 μš”μ†ŒλŠ” num λ³€μˆ˜λ‘œ μ°Έμ‘°λœλ‹€.

  • num.classList.value = ''
    num μš”μ†Œμ˜ classList μ†μ„±μ˜ value 값을 빈 λ¬Έμžμ—΄λ‘œ μ„€μ •ν•œλ‹€.

  • nums[0].classList.add('in')
    nums λ°°μ—΄μ˜ 첫 번째 μš”μ†Œμ— 'in' 클래슀λ₯Ό μΆ”κ°€ν•œλ‹€.

πŸ‘πŸ»nums λ°°μ—΄μ˜ 각 μš”μ†Œμ— λŒ€ν•΄μ„œ λ°˜λ³΅λ¬Έμ„ μ‹€ν–‰ν•˜λ©°, 각 μš”μ†Œμ˜ 클래슀 속성 값을 μ΄ˆκΈ°ν™”ν•˜κ³ , κ·Έ 쀑 첫 번째 μš”μ†Œμ—λŠ” 'in' 클래슀λ₯Ό μΆ”κ°€ν•˜λŠ” 역할을 ν•œλ‹€.

  • runAnimation()
  • nums.forEach((num, idx) => { ... })
    nums λ°°μ—΄μ˜ 각 μš”μ†Œμ— λŒ€ν•΄ λ°˜λ³΅λ¬Έμ„ μ‹€ν–‰ν•œλ‹€. num은 ν˜„μž¬ μš”μ†Œλ₯Ό μ°Έμ‘°ν•˜λŠ” λ³€μˆ˜μ΄κ³ , idxλŠ” ν•΄λ‹Ή μš”μ†Œμ˜ 인덱슀.
  • const nextToLast = nums.length - 1
    nextToLast λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜κ³ , nums λ°°μ—΄μ˜ λ§ˆμ§€λ§‰ μš”μ†Œμ˜ 인덱슀λ₯Ό ν• λ‹Ήν•œλ‹€.
  • num.addEventListener('animationend', (e) => { ... })
    이벀트 λ¦¬μŠ€λ„ˆλŠ” μ• λ‹ˆλ©”μ΄μ…˜μ΄ μ’…λ£Œλ˜μ—ˆμ„ λ•Œ μ‹€ν–‰λœλ‹€. eλŠ” 이벀트 객체λ₯Ό λ‚˜νƒ€λ‚΄λ©°, μ• λ‹ˆλ©”μ΄μ…˜κ³Ό κ΄€λ ¨λœ 정보λ₯Ό ν¬ν•¨ν•œλ‹€.
  • if (e.animationName === 'goIn' && idx !== nextToLast) { ... }
    λ§Œμ•½ ν˜„μž¬ μ• λ‹ˆλ©”μ΄μ…˜μ˜ 이름이 'goIn'이고, ν˜„μž¬ μš”μ†Œκ°€ nums λ°°μ—΄μ˜ λ§ˆμ§€λ§‰ μš”μ†Œκ°€ μ•„λ‹Œ 경우λ₯Ό κ²€μ‚¬ν•œλ‹€.
    -> num.classList.remove('in')
    -> num.classList.add('out')
  • else if (e.animationName === 'goOut' && num.nextElementSibling) { ... }
    λ§Œμ•½ ν˜„μž¬ μ• λ‹ˆλ©”μ΄μ…˜μ˜ 이름이 'goOut'이고, num μš”μ†Œμ˜ λ‹€μŒ ν˜•μ œ μš”μ†Œκ°€ μžˆλŠ” 경우λ₯Ό κ²€μ‚¬ν•œλ‹€.
    -> num.nextElementSibling.classList.add('in')
    num μš”μ†Œμ˜ λ‹€μŒ ν˜•μ œ μš”μ†Œμ— 'in' 클래슀λ₯Ό μΆ”κ°€ν•œλ‹€.
  • else { ... }
    μ• λ‹ˆλ©”μ΄μ…˜μ΄ 'goIn'이 μ•„λ‹ˆκ±°λ‚˜ λ§ˆμ§€λ§‰ μš”μ†ŒμΈ 경우
    -> counter.classList.add('hide')
    -> finalMessage.classList.add('show')
  • function runAnimation() { ... }
    각 숫자 μš”μ†Œμ˜ μ• λ‹ˆλ©”μ΄μ…˜μ„ μ²˜λ¦¬ν•˜κ³ , μ• λ‹ˆλ©”μ΄μ…˜ μ’…λ£Œ μ‹œμ μ— λŒ€ν•œ 이벀트 λ¦¬μŠ€λ„ˆλ₯Ό μΆ”κ°€ν•œλ‹€.
  • replay.addEventListener('click', () => { ... })
    replay 클릭 μ‹œ resetDOM() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ μ΄ˆκΈ°ν™”ν•˜κ³ , runAnimation() ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜μ—¬ μ• λ‹ˆλ©”μ΄μ…˜μ„ λ‹€μ‹œ μ‹œμž‘ν•œλ‹€.

❓❗μ—₯ CSS

❓overflow

  • "visible" : κΈ°λ³Έκ°’
    μš”μ†Œμ˜ λ‚΄μš©μ΄ μš”μ†Œμ˜ 경계λ₯Ό λ„˜μ–΄κ°ˆ κ²½μš°μ—λ„ μˆ¨κΈ°μ§€ μ•Šκ³  보여쀀닀.
  • "hidden"
    μš”μ†Œμ˜ λ‚΄μš©μ΄ μš”μ†Œμ˜ 경계λ₯Ό λ„˜μ–΄κ°€λ©΄ μˆ¨κΈ΄λ‹€.
    λ„˜μΉ˜λŠ” 뢀뢄은 보이지 μ•ŠλŠ”λ‹€.
  • "scroll"
    μš”μ†Œμ— 슀크둀 λ§‰λŒ€λ₯Ό μΆ”κ°€ν•˜μ—¬ λ‚΄μš©μ΄ μš”μ†Œμ˜ 경계λ₯Ό λ„˜μ–΄κ°ˆ λ•Œ μŠ€ν¬λ‘€ν•˜μ—¬ λ³Ό 수 있게 ν•œλ‹€.
  • "auto"
    λ‚΄μš©μ΄ μš”μ†Œμ˜ 경계λ₯Ό λ„˜μ–΄κ°ˆ κ²½μš°μ—λ§Œ 슀크둀 λ§‰λŒ€λ₯Ό μΆ”κ°€ν•œλ‹€.
    λ‚΄μš©μ΄ μš”μ†Œμ˜ 경계λ₯Ό λ„˜μ§€ μ•ŠμœΌλ©΄ 슀크둀 λ§‰λŒ€κ°€ ν‘œμ‹œλ˜μ§€ μ•ŠλŠ”λ‹€.

❓transform-origin

https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin

  • μš”μ†Œμ˜ λ³€ν˜•(트랜슀폼)이 적용될 λ•Œ λ³€ν˜•μ˜ 기쀀점을 μ§€μ •ν•˜λŠ” 역할을 ν•œλ‹€. 이 속성은 μš”μ†Œκ°€ νšŒμ „, 크기 μ‘°μ •, κΈ°μšΈμž„ λ“±μ˜ λ³€ν˜•μ„ 받을 λ•Œ λ³€ν˜•μ˜ 좕을 κ²°μ •ν•œλ‹€.
  • px (ν”½μ…€)
  • % (λ°±λΆ„μœ¨) : 50%λŠ” μš”μ†Œμ˜ 쀑심
  • left, right, center, top, bottom : μš”μ†Œμ˜ κ°€μž₯자리 λ˜λŠ” 쀑앙을 λ‚˜νƒ€λ‚΄λŠ” ν‚€μ›Œλ“œ

    예λ₯Ό λ“€μ–΄,
    transform-origin: 50% 50%;λŠ” μš”μ†Œμ˜ 쀑앙을 κΈ°μ€€μœΌλ‘œ λ³€ν˜•μ„ μ μš©ν•œλ‹€.
    transform-origin: top left;λŠ” μš”μ†Œμ˜ μ™Όμͺ½ 상단 λͺ¨μ„œλ¦¬λ₯Ό κΈ°μ€€μœΌλ‘œ λ³€ν˜•μ„ μ μš©ν•œλ‹€.
  • transform-origin을 μ‚¬μš©ν•˜μ—¬ μš”μ†Œμ˜ λ³€ν˜• 기쀀점을 μ‘°μ •ν•¨μœΌλ‘œμ¨, νšŒμ „ μΆ•μ΄λ‚˜ 크기 λ³€ν™˜μ˜ 기쀀점을 μ›ν•˜λŠ” μœ„μΉ˜λ‘œ μ΄λ™μ‹œν‚¬ 수 μžˆλ‹€. 이λ₯Ό 톡해 μš”μ†Œκ°€ μ›ν•˜λŠ” λ°©ν–₯μ΄λ‚˜ μœ„μΉ˜μ—μ„œ λ³€ν˜•λ˜λ„λ‘ μ‘°μ ˆν•  수 μžˆλ‹€.
profile
μ •μ‹ μ°¨λ € 이 κ°λ°•ν•œ μ„Έμƒμ†μ—μ„œ

0개의 λŒ“κΈ€