Last active
August 30, 2021 09:32
-
-
Save LemonNekoGH/a13bed76cea5321be162da19e63f15f2 to your computer and use it in GitHub Desktop.
尝试用 HTML 、 CSS 和 JS 复刻自己用 AE 做的加载动画
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="zh"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>LemonNeko Loading Demo</title> | |
<style> | |
body { | |
padding: 0; | |
margin: 0; | |
} | |
@keyframes scale-in { | |
0% { | |
transform: scale(0); | |
} | |
100% { | |
transform: scale(1); | |
} | |
} | |
@keyframes scale-x-in { | |
0% { | |
transform: scaleX(0); | |
transform-origin: left; | |
} | |
100% { | |
transform: scaleX(1); | |
transform-origin: left; | |
} | |
} | |
@keyframes fade-out { | |
0% { | |
opacity: 1; | |
} | |
100% { | |
opacity: 0; | |
} | |
} | |
@keyframes fade-in { | |
0% { | |
opacity: 0; | |
} | |
100% { | |
opacity: 1; | |
} | |
} | |
@keyframes scale-x-infinity { | |
0% { | |
transform: scaleX(1); | |
transform-origin: left; | |
} | |
100% { | |
transform: scaleX(8); | |
transform-origin: left; | |
} | |
} | |
.loading-start { | |
animation: cubic-bezier(0, 0, 0.13, 1) scale-in 1000ms forwards; | |
} | |
.fade-out { | |
animation: linear fade-out 250ms forwards; | |
} | |
.fade-in { | |
animation: linear fade-in 250ms forwards; | |
} | |
.scale-0 { | |
transform: scale(0); | |
} | |
.scale-x-0 { | |
transform: scaleX(0); | |
transform-origin: left; | |
} | |
.scale-x-in { | |
animation: cubic-bezier(0, 0, 0.13, 1) scale-x-in 1000ms forwards; | |
} | |
.loading-progress-break { | |
animation: cubic-bezier(1, 0, 1, 0) scale-x-infinity 1000ms forwards; | |
} | |
#loading-page, #loading-page-1, #loading-page-2, #loading-page-3 { | |
z-index: 99999; | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
overflow: hidden; | |
} | |
#loading-page-1 { | |
background-color: #fc7299; | |
} | |
#loading-page-2 { | |
background-color: #5BCEFA; | |
} | |
#loading-page-3 { | |
background-color: white; | |
} | |
#loading-page-content { | |
color: white; | |
font-size: 25px; | |
line-height: 50px; | |
text-align: center; | |
display: flex; | |
flex-direction: column; | |
width: 50%; | |
} | |
#loading-page-progress { | |
height: 20px; | |
border: white 2px solid; | |
background-color: rgba(255,255,255,.5); | |
} | |
#loading-page-progress-bar { | |
position: relative; | |
top: -2px; | |
height: 24px; | |
width: 66.6%; | |
background-color: white; | |
} | |
#loaded-page { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
} | |
#loaded-page-text { | |
font-size: 25px; | |
line-height: 60px; | |
} | |
#loaded-page-reload { | |
background-color: white; | |
border: black 2px solid; | |
padding: 5px; | |
font-size: 15px; | |
transition: all 250ms; | |
} | |
#loaded-page-reload:hover { | |
transition: all 250ms; | |
background-color: black; | |
color: white; | |
} | |
@media screen and (min-width: 1904px) { | |
#loading-page-content { | |
width: 30%; | |
} | |
} | |
@media screen and (min-width: 1264px) and (max-width: 1904px) { | |
#loading-page-content { | |
width: 40%; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div id="loading-page"> | |
<div id="loading-page-1"> | |
<div id="loading-page-content"> | |
<div id="loading-page-text" class="loading-start">Preloading</div> | |
<div id="loading-page-progress" class="scale-0"> | |
<div id="loading-page-progress-bar" class="scale-x-0"></div> | |
</div> | |
</div> | |
</div> | |
<div id="loading-page-2" class="scale-x-0"></div> | |
<div id="loading-page-3" class="scale-x-0"></div> | |
</div> | |
<div id="loaded-page"> | |
<div id="loaded-page-text">动画播放结束啦</div> | |
<button onclick="window.location.reload()" id="loaded-page-reload">重新播放</button> | |
</div> | |
<script> | |
(function () { | |
const loadingPage = document.querySelector('#loading-page') | |
const loadingPage1 = document.querySelector('#loading-page-1') | |
const loadingPage2 = document.querySelector('#loading-page-2') | |
const loadingPage3 = document.querySelector('#loading-page-3') | |
const loadingContent = document.querySelector('#loading-page-content') | |
const loadingText = document.querySelector('#loading-page-text') | |
const loadingProgress = document.querySelector('#loading-page-progress') | |
const loadingProgressBar = document.querySelector('#loading-page-progress-bar') | |
const timeNow = Date.now() | |
const animationDelay = 1500 // ms | |
let loadSpentTime = 0 | |
/** | |
* 第一阶段动画 | |
*/ | |
function animationStep1() { | |
setTimeout(() => { | |
loadingProgress.classList.remove('scale-0') | |
loadingProgress.classList.add('loading-start') | |
}, 250) | |
} | |
/** | |
* 监听网页加载情况 | |
*/ | |
function onReadyStateChange() { | |
if (document.readyState === 'complete') { | |
loadSpentTime = Date.now() - timeNow | |
console.log('load complete: ' + loadSpentTime + 'ms') | |
} | |
} | |
/** | |
* 监听动画结束事件 | |
*/ | |
function onAnimationEnd(event) { | |
const element = event.target | |
const animationName = event.animationName | |
console.log(`elementId: ${element.id}, animationName: ${animationName}`) | |
if (element.id === 'loading-page-text') { | |
// 当加载文字动画结束 | |
// 当出现动画结束时,让文字淡出 | |
if (animationName === 'scale-in') { | |
element.classList.remove('loading-start') | |
element.classList.add('fade-out') | |
} | |
// 当淡出动画结束时,改变文本并重新淡入回来 | |
else if (animationName === 'fade-out') { | |
element.innerText = 'Loading' | |
element.classList.remove('fade-out') | |
element.classList.add('fade-in') | |
} | |
} else if (element.id === 'loading-page-progress') { | |
// 当加载进度条动画结束 | |
if (animationName === 'scale-in') { | |
loadingProgressBar.classList.remove('scale-x-0') | |
loadingProgressBar.classList.add('scale-x-in') | |
} | |
} else if (element.id === 'loading-page-progress-bar') { | |
// 当加载进度条动画第一部分结束 | |
if (animationName === 'scale-x-in') { | |
loadingProgressBar.classList.remove('scale-x-in') | |
loadingProgressBar.classList.add('loading-progress-break') | |
} | |
// 当加载进度条动画第二部分结束 | |
else if (animationName === 'scale-x-infinity') { | |
loadingPage2.classList.remove('scale-x-0') | |
loadingPage2.classList.add('scale-x-in') | |
setTimeout(() => { | |
loadingPage3.classList.remove('scale-x-0') | |
loadingPage3.classList.add('scale-x-in') | |
}, 250) | |
} | |
} else if (element.id === 'loading-page-3') { | |
// 当第二层遮罩把第一层遮住 | |
if (animationName === 'scale-x-in') { | |
loadingPage.removeChild(loadingPage2) | |
loadingPage3.classList.remove('scale-x-in') | |
loadingPage3.classList.add('fade-out') | |
} else if (animationName === 'fade-out') { | |
document.body.removeChild(loadingPage) | |
} | |
} else if (element.id === 'loading-page-2') { | |
// 当第一层遮罩把进度条遮住 | |
if (animationName === 'scale-x-in') { | |
loadingPage.removeChild(loadingPage1) | |
} | |
} | |
} | |
// 开始第一阶段动画 | |
animationStep1() | |
// 设置监听器 | |
document.onreadystatechange = onReadyStateChange | |
document.onanimationend = onAnimationEnd | |
})() | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
完成了