50 天学习 50 个项目 - HTMLCSS and JavaScript
day34-Animated Countdown(动画倒计时)
效果
index.html
<! DOCTYPE html >
< html lang = " en" > < head> < meta charset = " UTF-8" /> < meta name = " viewport" content = " width=device-width, initial-scale=1.0" /> < title> Animated Countdown</ title> < link rel = " stylesheet" href = " style.css" />
</ head> < body> < div class = " counter" > < div class = " nums" > < span class = " in" > 3</ span> < span> 2</ span> < span> 1</ span> < span> 0</ span> </ div> < h4> 准备</ h4> </ div> < div class = " final" > < h1> GO</ h1> < button id = " replay" > 重播</ button> </ div> < script src = " script.js" > </ script>
</ body> </ html>
style.css
@import url ( 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap' ) ; * { box-sizing : border-box;
} body { background : url ( 'https://source.unsplash.com/random/1000x600' ) no-repeat center/100% 100%; font-family : 'Roboto' , sans-serif; margin : 0; height : 100vh; overflow : hidden;
}
h4 { font-size : 20px; margin : 5px;
}
.counter { position : fixed; top : 50%; left : 50%; transform : translate ( -50%, -50%) ; text-align : center;
}
.counter.hide { transform : translate ( -50%, -50%) scale ( 0) ; animation : hide 0.2s ease-out;
}
@keyframes hide { 0% { transform : translate ( -50%, -50%) scale ( 1) ; } 100% { transform : translate ( -50%, -50%) scale ( 0) ; }
}
.final { position : fixed; top : 50%; left : 50%; transform : translate ( -50%, -50%) scale ( 0) ; text-align : center;
}
.final.show { transform : translate ( -50%, -50%) scale ( 1) ; animation : show 0.2s ease-out;
}
@keyframes show { 0% { transform : translate ( -50%, -50%) scale ( 0) ; } 30% { transform : translate ( -50%, -50%) scale ( 1.4) ; } 100% { transform : translate ( -50%, -50%) scale ( 1) ; }
} .nums { color : red; font-size : 50px; position : relative; overflow : hidden; width : 250px; height : 50px;
}
.nums span { position : absolute; top : 50%; left : 50%; transform : translate ( -50%, -50%) rotate ( 120deg) ; transform-origin : bottom center;
}
.nums span.in { transform : translate ( -50%, -50%) rotate ( 0deg) ; animation : goIn 0.5s ease-in-out;
}
.nums span.out { animation : goOut 0.5s ease-in-out;
}
@keyframes goIn { 0% { transform : translate ( -50%, -50%) rotate ( 120deg) ; } 30% { transform : translate ( -50%, -50%) rotate ( -20deg) ; } 60% { transform : translate ( -50%, -50%) rotate ( 10deg) ; } 100% { transform : translate ( -50%, -50%) rotate ( 0deg) ; }
}
@keyframes goOut { 0% { transform : translate ( -50%, -50%) rotate ( 0deg) ; } 60% { transform : translate ( -50%, -50%) rotate ( 20deg) ; } 100% { transform : translate ( -50%, -50%) rotate ( -120deg) ; }
}
script.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) { console. log ( idx) ; num. classList. remove ( 'in' ) num. classList. add ( 'out' ) } else if ( e. animationName === 'goOut' && num. nextElementSibling) { console. log ( idx) ; num. nextElementSibling. classList. add ( 'in' ) } else { counter. classList. add ( 'hide' ) finalMessage. classList. add ( 'show' ) } } ) } )
}
replay. addEventListener ( 'click' , ( ) => { resetDOM ( ) runAnimation ( )
} )