Переход на страницу - дождитесь выполнения запроса ajax - PullRequest
0 голосов
/ 22 февраля 2019

Я пытаюсь воспроизвести эту анимацию в проекте - 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 голосов
/ 01 марта 2019

Как насчет разделения анимации на две разные анимации - startLoadingAnimation и stopLoadingAnimation.Где первая анимация будет просто отображать черный оверлей и загрузочный текст, а вторая скрывает их.

Проверьте мой фрагмент и реализуйте HTML-выборку в функции getPageAsync().

По существу, там3 обещания, которые мы должны выполнить при запросе HTML новой страницы.

  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>
...