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"
λ΄μ©μ΄ μμμ κ²½κ³λ₯Ό λμ΄κ° κ²½μ°μλ§ μ€ν¬λ‘€ λ§λλ₯Ό μΆκ°νλ€.
λ΄μ©μ΄ μμμ κ²½κ³λ₯Ό λμ§ μμΌλ©΄ μ€ν¬λ‘€ λ§λκ° νμλμ§ μλλ€.
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μ μ¬μ©νμ¬ μμμ λ³ν κΈ°μ€μ μ μ‘°μ ν¨μΌλ‘μ¨, νμ μΆμ΄λ ν¬κΈ° λ³νμ κΈ°μ€μ μ μνλ μμΉλ‘ μ΄λμν¬ μ μλ€. μ΄λ₯Ό ν΅ν΄ μμκ° μνλ λ°©ν₯μ΄λ μμΉμμ λ³νλλλ‘ μ‘°μ ν μ μλ€.