我正在尝试在项目中复制此动画-https://codepen.io/victorwork/pen/bQPBvQ
目标是在ajax请求获取新页面期间,带有黑色背景和徽标的屏幕以及仅在ajax请求完成后才消失的窗帘。
我已经尝试过使用.pause(),然后使用.resume(),但是在暂停时间它不能很好地工作,并且有时候恢复速度更快。
我已经尝试划分时间线,其中一个函数的开始是动画的开始,而另一个函数的结束是动画的开始,但是第一次出现的效果很好,但是下面的那些没有,我也不太清楚为什么。
>有什么建议吗?
这是代码。
const entryTransitionPage = new TimelineMax( { paused: true });
entryTransitionPage
.fromTo(transitionElementBlue , 1.2, { scaleX: 0 },{ scaleX: 1, transformOrigin:'left', ease: Power4.easeInOut},)
.fromTo(transitionElementBlack , 1.2, {scaleX: 0},{scaleX: 1, transformOrigin:'left', ease: Power4.easeInOut}, .2)
.fromTo(transitionContent , .6, {xPercent: -100, autoAlpha:0 }, {xPercent: 0, autoAlpha:1, ease: Power4.easeInOut}, .7)
.set(transitionElementBlue, { scaleX:0 })
.to(transitionElementBlack , 2, { scaleX: 0, transformOrigin:'right', ease: Power4.easeInOut })
.to(transitionContent , .2, { autoAlpha:0 }, '-=1.2');
const entryPageAnimation = () => {
entryTransitionPage.play(0);
setTimeout(() => { entryTransitionPage.pause()}, 2000);
}
const endPageAnimation = () => {
entryTransitionPage.resume();
}
const changePage = (url) => {
entryPageAnimation();
loadPage(url)
}
const loadPage = (url) => {
const xhr = new XMLHttpRequest();
xhr.onerror = () => { throw 'Request failed. HTTP code ' + xhr.status; };
xhr.onload = () => {
if (!xhr.status || (xhr.status >= 400)) throw 'Request failed. HTTP code ' + xhr.status;
const documentAjax = (new DOMParser()).parseFromString( xhr.response,'text/html');
document.body.className = documentAjax.body.className;
const pageContent = documentAjax.getElementById('pageContent');
const newPage = documentAjax.getElementById('pageSelector');
const page = document.getElementById('pageContent');
exitPageAnimation();
setTimeout( () => {
window.scrollTo(0, 0);
if (newPage) page.innerHTML = newPage.outerHTML;
}, 700);
}
xhr.open('GET', url, true);
xhr.send();
}
顺便说一句,除了转换超时以外,还有什么方法可以只在过渡动画结束时插入新页面的内容?
答案 0 :(得分:1)
如何将动画分为两个不同的动画-startLoadingAnimation
和stopLoadingAnimation
。第一个动画将只显示黑色叠加层和正在加载的文本,第二个动画将隐藏它们。
检查我的代码段,并在getPageAsync()
函数中实现HTML提取。
基本上,当请求新页面HTML时,我们需要履行3个诺言。
var page = document.querySelector('.page');
var loadingText = document.querySelector('.transition__loding');
var frameBlack = document.querySelector('.page-transition__black');
var frameRed = document.querySelector('.page-transition__red');
var button = document.querySelector('#button');
var startLoadingPromise;
var stopLoadingPromise;
var startLoadingAnimation = new TimelineMax({
paused: true,
onComplete: startLoadingComplete
})
.fromTo(frameRed, 2.2, {
scaleX: 0
}, {
scaleX: 1,
transformOrigin: 'left',
ease: Power4.easeInOut
})
.fromTo(frameBlack, 2.2, {
scaleX: 0
}, {
scaleX: 1,
transformOrigin: 'left',
ease: Power4.easeInOut
}, .2)
.fromTo(loadingText, 1.6, {
xPercent: -100,
autoAlpha: 0
}, {
xPercent: 0,
autoAlpha: 1,
ease: Power4.easeInOut
}, .7);
var stopLoadingAnimation = new TimelineMax({
paused: true,
onComplete: stopLoadingComplete
})
.set(frameRed, {
scaleX: 0
})
.to(frameBlack, 2.2, {
scaleX: 0,
transformOrigin: 'right',
ease: Power4.easeInOut
})
.to(loadingText, .2, {
autoAlpha: 0
}, '-=1.2');
button.addEventListener('click', () => {
button.style.display = 'none';
startLoading().then(function() {
return getPageAsync();
}).then(function(html) {
page.innerHTML = html;
return stopLoading();
}).then(function() {
button.style.display = 'initial';
})
});
function getPageAsync() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(getRandomContent());
}, 500);
});
}
function getRandomContent() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 30; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
function startLoadingComplete() {
startLoadingPromise.resolve();
}
function startLoading() {
let res, rej;
startLoadingPromise = new Promise(function(resolve, reject) {
res = resolve;
rej = reject;
});
startLoadingPromise.resolve = res;
startLoadingPromise.reject = rej;
startLoadingAnimation.play(0);
return startLoadingPromise;
}
function stopLoadingComplete() {
stopLoadingPromise.resolve();
}
function stopLoading() {
let res, rej;
stopLoadingPromise = new Promise(function(resolve, reject) {
res = resolve;
rej = reject;
});
stopLoadingPromise.resolve = res;
stopLoadingPromise.reject = rej;
stopLoadingAnimation.play(0);
return stopLoadingPromise;
}
body {
overflow: hidden;
}
.page-transition__black {
position: absolute;
left: 0;
top: 0;
height: 100vh;
width: 100vw;
background: #000;
}
.page {
background-color: green;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
color: white;
font-size: 30px;
text-align: center;
padding-top: 20px;
}
.page-transition__red {
position: absolute;
left: 0;
top: 0;
height: 100vh;
width: 100vw;
background: red;
}
.transition__loding {
text-transform: uppercase;
font-family: sans-serif;
font-size: 32px;
position: absolute;
z-index: 1;
color: #fff;
font-weight: bold;
top: 50vh;
left: 50vw;
transform: translate(-50%, -50%);
}
button {
bottom: 15vh;
left: 5vw;
text-transform: uppercase;
font-family: sans-serif;
font-size: 16px;
position: absolute;
z-index: 1;
color: #fff;
background: transparent;
padding: 20px;
border: 2px solid #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
<div class="page-transition">
<div class="page">
Page 1 content ...
</div>
<div class="page-transition__red"></div>
<div class="page-transition__black"></div>
<div class="transition__loding"> Loading ...</div>
</div>
<button id="button">Next Page</button>