前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Fluid -11- 封面视频背景顺滑加载

Fluid -11- 封面视频背景顺滑加载

作者头像
为为为什么
发布2022-08-06 09:42:36
发布2022-08-06 09:42:36
83600
代码可运行
举报
文章被收录于专栏:又见苍岚又见苍岚
运行总次数:0
代码可运行

Fluid -2- 随机视频背景切换 中记录了 Fluid 主题背景随机切换的实现方法,但存在加载视频覆盖原始图像背景的情况,本文记录顺滑加载解决方案 。

当前问题

  • 当前问题为背景图像加载较快,视频稍慢
  • 导致背景加载时会有先出现图像,再覆盖另一个视频的尴尬场景

解决思路

放弃图像加载
  • 放弃图像加载是一种解决方案,这样就只会加载视频,没有图像的闪动
  • 但手机端需要加载图像,不能放弃图像背景
  • 更重要的原因是图像加载快,用户可以更早地感受到网页在加载
  • 因此不能放弃加载图像
加载更小的视频第一帧图像
  • 又需要图像,同时又让视频覆盖起来顺滑
  • 于是就有了使用视频第一帧图像作为背景图像加载的思路

实现思路

  • 实现思路为在加载视频路径json时顺带加载相应的第一帧图像
  • 动态替换原始背景的 style background 链接地址,实现顺滑加载
  • 该方案不会影响手机端的原始背景图像正常加载

解决方案

实现动态背景视频加载
获取视频图像第一帧

保存质量可以低一些,使得图像文件小,更快加载

  • 上传图像,获取和视频对应的图像链接
修改 video_url.json
  • 修改 video_url.json 文件
  • 之前的视频链接改为 [视频链接, 图像链接]
  • 示例:
代码语言:javascript
代码运行次数:0
复制
"https://101.43.39.125/HexoFiles/vvd-dell-2021-win-10/20210808220318.mp4"
# 改为
["https://101.43.39.125/HexoFiles/vvd-dell-2021-win-10/20210808220318.mp4", "https://101.43.39.125/HexoFiles/vvd-dell-2021-win-10/20210808220318.jpg"]
修改 layout.ejs 文件
  • 修改 Hexo -> themes -> fluid -> layout -> layout.ejs文件:
  • 将之前的 <% if(banner_video){ %> 段改为:
代码语言:javascript
代码运行次数:0
复制
<% if(banner_video){ %>
    <script>
        var ua = navigator.userAgent;
        var ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
            isIphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
            isAndroid = ua.match(/(Android)\s+([\d.]+)/),
            isMobile = isIphone || isAndroid;

        function set_video_attr(id){
            var height = document.body.children[0].clientHeight
            var width = document.body.children[0].clientWidth
            var video_item = document.getElementById(id);

            if (height / width < 0.56){
                video_item.setAttribute('width', '100%');
                video_item.setAttribute('height', 'auto');
            } else {
                video_item.setAttribute('height', '100%');
                video_item.setAttribute('width', 'auto');
            }
        }

        $.getJSON('/vvd_js/video_url.json', function(data){
            if (!isMobile){
                var video_list_length = data.length
                var seed = Math.random()
                index = Math.floor(seed * video_list_length)

                video_url = data[index][0]
                pre_show_image_url = data[index][1]

                banner_obj = document.getElementById("banner")
                banner_obj.style.cssText = "background: url('" + pre_show_image_url + "') no-repeat; background-size: cover;"

                video_html_res = "<video id='video_item' style='position: absolute;' muted='muted' src=" + video_url + " autoplay='autoplay' loop='loop'></video>"

                document.getElementById("banner_video_insert").innerHTML = video_html_res;
                set_video_attr('video_item')

            }

        });
        if (!isMobile){
            window.onresize = function(){
                set_video_attr('video_item')
            }
        }
	</script>
<% } %>

  • 完整的 layout.ejs 文件
代码语言:javascript
代码运行次数:0
复制
<%
var subtitle = page.subtitle || page.title
var banner_img = page.banner_img || theme.index.banner_img
var banner_img_height = page.banner_img_height || theme.index.banner_img_height
var banner_mask_alpha = page.banner_mask_alpha || theme.index.banner_mask_alpha
var colorSchema = theme.dark_mode && theme.dark_mode.enable && theme.dark_mode.default ? theme.dark_mode.default : ''
var banner_video = theme.index.banner_video
%>

<!DOCTYPE html>

<html lang="<%= config.language %>" <%= colorSchema ? `data-default-color-scheme=${colorSchema}` : '' %>>
<script type="text/javascript" src="/vvd_js/jquery.js"></script>

<%- partial('_partial/head') %>

<body>
		
  <header style="height: <%- banner_img_height %>vh;">
    <%- partial('_partial/nav') %>
	
	<div class="banner" id="banner" <%- theme.banner && theme.banner.parallax && 'parallax=true' %>
		style="background: url('<%- url_for(banner_img) %>') no-repeat center center;
		background-size: cover;">

		<div class="full-bg-img" >
			<div id="banner_video_insert">
			</div>	
			<% if(banner_video){ %>
				<script>
					var ua = navigator.userAgent;
					var ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
						isIphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
						isAndroid = ua.match(/(Android)\s+([\d.]+)/),
						isMobile = isIphone || isAndroid;

					function set_video_attr(id){
						var height = document.body.children[0].clientHeight
						var width = document.body.children[0].clientWidth
						var video_item = document.getElementById(id);

						if (height / width < 0.56){
							video_item.setAttribute('width', '100%');
							video_item.setAttribute('height', 'auto');
						} else {
							video_item.setAttribute('height', '100%');
							video_item.setAttribute('width', 'auto');
						}
					}

					$.getJSON('/vvd_js/video_url.json', function(data){
						if (!isMobile){
							var video_list_length = data.length
							var seed = Math.random()
							index = Math.floor(seed * video_list_length)
							
							video_url = data[index][0]
							pre_show_image_url = data[index][1]
							
							banner_obj = document.getElementById("banner")
							banner_obj.style.cssText = "background: url('" + pre_show_image_url + "') no-repeat; background-size: cover;"

							video_html_res = "<video id='video_item' style='position: absolute;' muted='muted' src=" + video_url + " autoplay='autoplay' loop='loop'></video>"

							document.getElementById("banner_video_insert").innerHTML = video_html_res;
							set_video_attr('video_item')

						}

					});

					if (!isMobile){
						window.onresize = function(){
							set_video_attr('video_item')
							}
						}
				</script>
			<% } %>

			<div class="mask flex-center" style="background-color: rgba(0, 0, 0, <%= parseFloat(banner_mask_alpha) %>)">
			  <div class="page-header text-center fade-in-up">
				<span class="h2" id="subtitle" title="<%= subtitle %>">
				  <% if(!theme.fun_features.typing.enable) { %>
					<%- subtitle %>
				  <% } %>
				</span>

				<% if(is_post() && page.meta !== false) { %>
				  <%- partial('_partial/post-meta') %>
				<% } %>
			  </div>

			  <% if (theme.scroll_down_arrow.enable && theme.scroll_down_arrow.banner_height_limit <= banner_img_height && page.layout !== '404') { %>
				<div class="scroll-down-bar">
				  <i class="iconfont icon-arrowdown"></i>
				</div>
			  <% } %>
			</div>
		</div>
    </div>
  </header>

  <main>
    <% if(is_post() || page.layout === '404') { %>
      <%- body %>
    <% } else { %>
      <div class="container nopadding-x-md">
        <div class="py-5" id="board"
          <%- banner_img_height >= 100 && theme.banner && theme.banner.parallax ? 'style=margin-top:0' : '' %>>
          <% if(page.layout === 'about') { %>
            <div class="about-avatar">
              <img src="<%= url_for(theme.about.avatar) %>"
                   class="img-fluid" alt="avatar">
            </div>
          <% } %>
          <div class="container">
            <div class="row">
              <div class="col-12 col-md-10 m-auto">
                <%- body %>
              </div>
            </div>
          </div>
        </div>
      </div>
    <% } %>

    <% if (theme.scroll_top_arrow.enable) { %>
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    <% } %>

    <% if (theme.search.enable) { %>
      <%- partial('_partial/search') %>
    <% } %>

    <% if (theme.custom_html) { %>
      <div class="col-lg-7 mx-auto nopadding-x-md">
        <div class="container custom mx-auto">
          <%- theme.custom_html %>
        </div>
      </div>
    <% } %>
  </main>

  <%- partial('_partial/footer', { params: { subtitle: subtitle } }) %>

  <!-- SCRIPTS -->
  <%- partial('_partial/scripts') %>

</body>
</html>

效果展示

参考资料

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年9月16日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 当前问题
  • 解决思路
    • 放弃图像加载
    • 加载更小的视频第一帧图像
  • 实现思路
  • 解决方案
    • 实现动态背景视频加载
    • 获取视频图像第一帧
    • 修改 video_url.json
    • 修改 layout.ejs 文件
  • 效果展示
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档