javascript - 页面转换——等到ajax请求发出

标签 javascript animation gsap

我正在尝试在项目中重现此动画 - https://codepen.io/victorwork/pen/bQPBvQ

目标是在获取新页面的 ajax 请求期间,带有黑色背景和 Logo 的屏幕,只有当 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();

}

请问有什么方法可以在过渡动画结束时插入新页面的内容,而不是超时?

最佳答案

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

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

当请求新页面 HTML 时,基本上有 3 个我们需要实现的 promise 。

  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>

关于javascript - 页面转换——等到ajax请求发出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54827639/

相关文章:

javascript - Javascript 打印出一个空白页

javascript - 为Flot图表配置工具提示,其中数据来自ajax调用

javascript - 装最多水的容器

ios - 有没有办法旋转 UIBarButton SystemItem Refresh 的刷新图标直到刷新完成?

android - 方向更改后反转共享元素转换

javascript - 使用 Greensock 的滚动动画问题

javascript - 将基于文本的 div 放置在圆内的相对位置

android - Android 中的动画矢量资源路径(Line、Arc、...)

javascript - 使用 TweenLite 从中间到边缘径向淡入图像

javascript - fullscreenJS moveTo 方法不正确的 View