页面过渡-等待ajax请求发出

时间:2019-02-22 12:54:16

标签: javascript animation gsap tweenmax

我正在尝试在项目中复制此动画-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();

}

顺便说一句,除了转换超时以外,还有什么方法可以只在过渡动画结束时插入新页面的内容?

1 个答案:

答案 0 :(得分:1)

如何将动画分为两个不同的动画-startLoadingAnimationstopLoadingAnimation。第一个动画将只显示黑色叠加层和正在加载的文本,第二个动画将隐藏它们。

检查我的代码段,并在getPageAsync()函数中实现HTML提取。

基本上,当请求新页面HTML时,我们需要履行3个诺言。

  1. 开始制作动画。
  2. 完整获取新页面的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>