直播系统网页如何实现类似app的页面切换动画?

前言

直播系统app打开一个页面时,有时会看到这么一种动画:当前页的某些元素跳到下一个页面上。

那么直播系统网页端有没有办法实现这种类似于直播系统app端页面切换的动画效果呢?经过探索,发现谷歌浏览器已经提供了这么一个实验性API:

documentTransition

它是一种新的脚本API的提议,允许在单页应用程序(SPA)和多页应用程序(MPAs)中使用一组简单的过渡动画。这个特性的灵感来自于Material Design原则中列出的过渡。其目的是支持类似于Android Activity transitions的过渡动画效果。

浏览器开启该功能API

由于该特性是实验功能,需要手动开启。在浏览器中输入

chrome://flags/#document-transition

然后将documentTransition设置为Enabled启用。
在这里插入图片描述

设置完之后我们重启下浏览器,然后打开控制台输入:

'documentTransition' in document

结果打印为true的话,说明我们浏览器已经成功开启该实验功能API。
在这里插入图片描述

如何理解该API

该API提案可以分为两部分:根转换(root transition)和共享元素转换(shared element transition)。
根转换(root transition)
根转换可以理解为直播系统"页面“在载入时的动画过渡效果,如直播系统iOS端点击跳转下一个页面时,下一个页面是从右到左推入的。下面代码实现该效果(注意:效果跟直播系统APP差异较大,总体效果是能看出“页面”是从右到左推入的,请自行运行代码在浏览器中查看效果):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>rootTransition示例</title>
  </head>
  <style>
    .list {
      height: 100vh;
    }
    .details {
      height: 100vh;
      background-color: aquamarine;
    }
    .hide {
      display: none;
    }
  </style>
  <body>
    <div class="list">
      列表页
      <button id="btn">点击去详情页</button>
    </div>
    <div class="details hide">详情页</div>
    <script>
      const btn = document.querySelector('#btn')
      const details = document.querySelector('.details')
      const list = document.querySelector('.list')
      btn.addEventListener('click', () => {
        navigateToDetailsPage()
      })
      async function navigateToDetailsPage() {
        await document.documentTransition.prepare({
          rootTransition: "cover-left",
        });
        details.classList.remove('hide')
        list.classList.add('hide')
        document.documentTransition.start();
      }
    </script>
  </body>
</html>

以上就是一个root transition的例子,它的使用模型可以概括如下:

// 用户点击按钮切换页面时执行
async function navigateToSettingsPage() {
  // 捕捉当前页面状态,进行动画准备
  await document.documentTransition.prepare({
    rootTransition: 'cover-left', // “页面”切换效果
  });

  // 执行更新DOM操作,显示下一页的内容
  updateDOMForNextPage();

  // 调用start开始执行动画
  await document.documentTransition.start();
  // 动画结束
}

支持的动画效果
rootTransition支持以下属性:

  • reveal-left: 旧内容从中心向指定方向滑动,显示新内容。
  • reveal-right
  • reveal-up
  • reveal-down
  • cover-left: 新内容沿指定方向从边缘滑动,覆盖旧内容。
  • cover-right
  • cover-up
  • cover-down
  • explode: 旧内容通过成长和变得更加透明而“爆炸”,并揭示出新的内容。
  • implode: 新内容会“内爆”,从大的一面收缩,变得不透明,转换旧内容。

共享元素转换(shared element transition)
共享元素就是用户头像及名字,可以看到这两个元素从直播系统当前页到下一页加载完时是一直处于可视状态的,并且从直播系统当前页显示位置大小到下一页显示位置大小有一个平滑过渡的效果。

如何使用shared element

async function navigateToSettingsPage() {

  await document.documentTransition.prepare({
    rootTransition: 'cover-up',
    sharedElements: [element1, element2, element3],
  });

  // updateDOM

  await document.documentTransition.start({
    sharedElements: [element1, element4, element5],
  });

}

sharedElements是一个数组,里面存放“跨页”共享的元素,对应动图的例子来说就是存放用户的头像及名字的dom。
需要注意的是:

1、在prepare及start方法中都要设置sharedElements属性,并且是一一对应的关系。例如element2在切换到“下一页”时,对应过渡到的就是element4所在位置。
2、需要配合css的contain属性才能正常工作,通常设置为contain: paint;该属性的作用是如果一个元素在视窗外或因其他原因导致不可见,则同样保证它的子孙节点不会被显示。详见:contain

完整代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>rootTransition示例</title>
</head>
<style>
body{margin:0}.flex-center{display:flex;align-items:center;justify-content:center}.list{height:100vh}.details{height:100vh}.hide{display:none!important}.card{display:flex;align-items:center;margin:0 20px;box-shadow:0 0 50px #ccc;border-radius:12px;overflow:hidden}.card .desc{font-size:18px;color:#333;font-weight:bold;margin-left:20px}.details-desc{font-size:22px;color:limegreen}.list{display:flex;flex-direction:column;justify-content:center}.button-wrap{margin-top:20px;text-align:center}.back-btn{display:inline-block;width:100px;height:40px}.details-cover{display:block;width:100%}.details-desc{position:absolute;right:20px;top:20px}.cover,.details-cover,.desc,.details-desc{contain:paint}
</style>

<body>
    <div class="list">
        <div class="card">
            <img class="cover"
                src="http://p1-q.mafengwo.net/s18/M00/52/27/CoUBYGDMNO-AOlK4AAVHKFDW8_Y808.jpg?imageMogr2%2Fthumbnail%2F%21220x150r%2Fstrip%2Fgravity%2FCenter%2Fcrop%2F%21220x150%2Fquality%2F90" />
            <span class="desc">人生海海</span>
        </div>
        <div class="button-wrap">
            <button id="btn">点击去详情页</button>
        </div>
    </div>
    <div class="details hide">
        <div>
            <div style="position: relative;">
                <img class="details-cover"
                    src="http://p1-q.mafengwo.net/s18/M00/52/27/CoUBYGDMNO-AOlK4AAVHKFDW8_Y808.jpg?imageMogr2%2Fthumbnail%2F%21220x150r%2Fstrip%2Fgravity%2FCenter%2Fcrop%2F%21220x150%2Fquality%2F90" />
                <div class="details-desc">人生海海</div>
            </div>
            <div class="button-wrap">
                <button class="back-btn">返回</button>
            </div>
        </div>
    </div>
    <script>
        const btn = document.querySelector('#btn')
        const details = document.querySelector('.details')
        const list = document.querySelector('.list')
        const backBtn = document.querySelector('.back-btn')
        const cover = document.querySelector('.cover')
        const desc = document.querySelector('.desc')
        const detailsCover = document.querySelector('.details-cover')
        const detailsDesc = document.querySelector('.details-desc')

        btn.addEventListener('click', () => {
            navigateToDetailsPage()
        }, false)
        backBtn.addEventListener('click', () => {
            showList()
        }, false)

        async function navigateToDetailsPage() {
            await document.documentTransition.prepare({
                rootTransition: "cover-up",
                sharedElements: [
                    cover,
                    desc
                ]
            });
            details.classList.remove('hide')
            list.classList.add('hide')
            document.documentTransition.start({
                sharedElements: [
                    detailsCover,
                    detailsDesc
                ]
            });
        }

        async function showList() {
            await document.documentTransition.prepare({
                rootTransition: "implode",
                sharedElements: [
                    detailsCover,
                    detailsDesc
                ]
            });

            details.classList.add("hide");
            list.classList.remove("hide");

            await document.documentTransition.start({
                sharedElements: [
                    cover,
                    desc
                ]
            });

        }
    </script>
</body>

</html>

以上就是“直播系统网页如何实现类似app的页面切换动画?”的全部内容,在直播哦系统开发时需要我们注意的细节点有很多,希望以上内容能对大家有帮助。

概述: iShow是一套基于P2P技术的在线视频直播系统,iShow依存于web网页,无需下载插件,可实现低延时高清的视频语音直播体验。现已广泛应用于教育、娱乐、客服等各个行业,随着国内带宽的提升和各类新技术的加入,视频直播技术已经逐渐成为下一代互联网的主流,多媒体在线直播体验势必将会涵盖各类终端,成为全民参与的新一代互联网主旋律。 随着国家网络带宽的升级,民用宽带的价格逐渐降低以及微博等即时交流的网络媒体的兴盛,视频多媒体将将成为下一代网络的主流力量,iShow作为国内第一个也是唯一一个使用点对点视频技术开发的网站应用,正在引领一股新的流媒体平民化浪潮。 功能列表: 1、即时视频语音直播 2、视频状态检测 3、局域网内的P2P直播,不消耗任何外网带宽 4、可设置的视频清晰度和缓冲时间 5、无延时的即时文字和表情传输 6、礼物/消费/主播结算/房间类型等功能 7、播放录像功能 iShow的技术优势: 1、直播低延时、文本数据即时传输 2、多媒体直播不耗费任何服务器资源,对服务器无负载 3、带宽占用低 4、视频高清,采用高清编码,影响更清晰,传输更流畅 5、无需架设额外的视频流媒体服务器,节省60%~90%的运营开支 6、可扩展,可跨平台同步直播 7、兼容任何开发语言,简单几步可与任何网站进行对接整合 8、智能识别用户的在线状态 9、可脱离动态程序和数据库独立运行,如:无需任何架设,即可直接集成到任何网站,进行直播或文字沟通 目前同行业唯一一款成熟产品,处于行业绝对领跑者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值