周杰伦读心术背后的技术实现
前言
在技术细节的内容开始之前,您可以先通过下方的二维码再次体验这个魔术。
一、HTML
1.设置meta
<meta name="viewport" content="width=320, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
2.配置CSS
添加了video标签,可能会出现video标签默认置顶的情况,通过以下的样式设置可以解决这个问题。
<style>
.compatibleStyle {
backface-visibility:hidden;
-webkit-backface-visibility:hidden; /* Chrome 和 Safari */
-moz-backface-visibility:hidden; /* Firefox */
-ms-backface-visibility:hidden; /* Internet Explorer */
-webkit-perspective: 0;
-webkit-transform: translate3d(0,0,0);
visibility:visible;
}
body{margin:0 auto;background:#000;}
</style>
二、屏幕自适应组件
1.引入JS
<script src="//ossweb-img.qq.com/images/js/mmdPlugin/mmd-plugin.min.1.0.2.js"></script>
组件作者:lennylin
2.初始化
<div view-mode="v" view-rotation="auto" view-scale="noborder" view-width="750" view-height="1332" view-align="">
<div style="position: absolute;">
<video id="canvasVideo" style="position:absolute; display:none;"></video>
<canvas id="canvas" width="750px" height="1332px" style="position:absolute"></canvas>
</div>
</div>
3.横竖屏配置
3.1.view-mode
自适应组件的view-mode属性定义了H5是以横屏显示还是以竖屏显示。属性值为“v”表示竖屏,为“h”表示横屏。本项目使用“v”。
3.2.view-rotation
自适应组件的view-rotation属性定义了移动设备旋转后H5画面是否可见。属性值为“v”表示仅竖屏时可见,为“h”表示仅横屏时可见,为“auto”则表示横竖屏均可以看到画面。本项目使用“auto”。
4.屏幕缩放方式
自适应组件的view-scale属性定义了屏幕的缩放方式,目前一共有以下6种缩放方式。
参数值 |
缩放方式 |
---|---|
exactfit |
宽度等于屏幕宽度,高度等于屏幕高度,会改变原始宽高比 |
noborder |
裁剪宽高后铺满屏幕,不改变原始宽高比 |
noscale |
不进行任何缩放,不改变原始宽高比 |
showall |
整体进行等比例缩放后在屏幕中显示全部内容,不改变原始宽高比 |
width |
仅让宽度等于屏幕宽度,高度会等比例缩放,不改变原始宽高比 |
height |
仅让高度等于屏幕高度,宽度会等比例缩放,不改变原始宽高比 |
4.1.宽高比例
以上6种缩放方式中,仅exactfit方式会改变原始画布的宽高比,其他方式都是以等比例进行整体缩放的。
4.2.画布可能铺不满整个屏幕
exactfit和noborder这两种缩放方式始终都能让画面铺满整个屏幕,不过代价就是画布可能会被裁剪掉一部分边界。而showall、width、height这三种缩放方式在进行屏幕自适应之后可能会使得画布的尺寸小于屏幕尺寸,此时会导致画布铺不满整个屏幕的情况发生。
三、视频组件
1.引入JS
<script src="//ossweb-img.qq.com/images/js/mmdVideoPlayer/mmd.videoplayer.min.1.0.2.js"></script>
组件作者:quanchen
本文仅从项目使用角度出发讲解那些用到的视频组件的功能,关于视频组件更详尽的内容可以查阅以下文章:
2.初始化
var mp4Video = new MMD.VideoPlayer(
{
videoElement:document.getElementById("canvasVideo"),//[必填],video元素
src:"视频URL地址",//[必填],video src
loop:false,//[可选],是否循环,默认false,true为循环
muted:false,//[可选],是否静音,默认false,IOS下只有IOS10生效,安卓生效
poster:"",//[可选],video默认图片
timesParam: [],//[可选],video currenttime时间点
onTimes:function(name)
{
},//[可选],video currenttime回调
onStart:function()
{
},//[可选],video第一个画面出现回调
onEnd:function()
{
}//[可选],video播放完成回调
});mp4Video.play();//播放视频
3.切换视频
3.1.更换视频源
通过视频组件的src属性可以很方便地更换视频源。
3.2.视频提示点
如果想要在视频播放到某个位置时触发某个动作以便可以进行其他的逻辑处理,可以通过给视频组件的timesParam属性传递一个数组,并通过onTimes回调来实现此功能。
mp4Video.timesParam = [{name:"testName", time:15.5}];
以上代码的含义是:在视频播放到第15.5秒时发出一个带有name属性值的回调,视频组件的onTimes可以接收并处理这个回调。以下是包含有两个视频提示点的用法,想要配置更多视频提示点的使用方法可以依此类推。
var mp4Video = new MMD.VideoPlayer(
{
videoElement:document.getElementById("canvasVideo"),//[必填],video元素
src:"视频URL地址",//[必填],video src
loop:false,//[可选],是否循环,默认false,true为循环
muted:false,//[可选],是否静音,默认false,IOS下只有IOS10生效,安卓生效
poster:"",//[可选],video默认图片
timesParam: [{name:"testNameA", time:15.5}, {name:"testNameB", time:19}],//两个视频提示点
onTimes:function(name)
{
switch(name)
{
case "testNameA"://第1个视频提示点
//播放到了第15.5秒
break;
case "testNameB"://第2个视频提示点
//播放到了第19秒
break;
}
},//[可选],video currenttime回调
onStart:function()
{
},//[可选],video第一个画面出现回调
onEnd:function()
{
}//[可选],video播放完成回调
});
特别提醒:在更换视频的src属性后,视频原来的timesParam属性依旧存在,可以通过重新给timesParam属性赋值来覆盖之前设置的视频提示点,或者直接传递一个空数组来清空所有的视频提示点。
3.3.让视频跳到新位置播放或暂停
视频组件的currentTimeAndPlay属性可以让视频跳到某个时间点并从该位置开始播放,类似的另外一个属性是currentTimeAndPause,后者可以让视频跳到某个时间点并停在该时间点。
mp4Video.currentTimeAndPlay = 23;//让视频从第23秒开始播放
mp4Video.currentTimeAndPause = 30;//让视频跳到第30秒并停在第30秒
四、周杰伦读心术交互处理
1.视频分段
考虑到视频的总长度和玩家在一次体验中并不需要看完视频的全部内容,所以整个长达5分06秒的视频最终被拆分为多段子视频,并通过用户的交互来确定应该加载哪一段。除了开头的第一段,其他的分支视频都是在用户选择了相应的牌色、花色、单双点数之后才去动态加载并播放的。
2.视频提示点
通过视频组件的timesParam埋好选牌交互的提示点,然后就可以在onTimes回调触发后显示选牌交互动画。
mp4Video.timesParam = [{name:"showInteract", time:10}];
onTimes:function(name)
{
switch (name)
{
case "showInteract"://视频播放到第10秒 //展示选牌互动动画
break;
}
}
3.切换新视频
在用户点击了某个分支之后,通过替换src的属性值来切换视频源。
mp4Video.src = "新视频URL";
4.新视频就绪
在新视频开始播放并且画面的第一帧出现后会触发onStart回调,在onStart回调中移除选牌交互动画,这样可以让视频切换得更加平滑。
onStart:function()
{
//移除选牌交互动画
}
五、结尾
以上就是本次周杰伦读心术H5的核心代码以及自适应组件和视频组件在实际项目中的用法介绍,希望对您有所帮助。
- Leetcode-Easy 72. Edit Distance
- React第三方组件4(状态管理之Reflux的使用③TodoList中)
- Leetcode-Easy21. Merge Two Sorted ListsDefinition for singly-linked list.class ListNode:def init(sel
- Burp Suite详细使用教程-Intruder模块详解
- 逆元的三种解法(附详细证明)
- JavaScript设计模式与开发实践 - 单例模式
- Leetcode-Easy 141. Linked List Cycle
- 【DataMagic】如何在万亿级别规模的数据量上使用Spark
- 51nod1004 n^n的末位数字
- Leetcode-Easy 20. Valid Parentheses
- Leetcode-Easy 234. Palindrome Linked List
- 为什么是link-visited-hover-active
- 51Nod 1051 最大子矩阵和
- Javascript之创建对象
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【Rust日报】2020-08-29 生产环境 Rust 序列化库的选择
- 【投稿】刀哥:Rust学习笔记 5
- Python测试开发django3.视图和URL配置
- 【Rust日报】2020-08-31 easy_rust 正式完成了
- Python测试开发django4.templates模板配置
- Python测试开发django5.templates模板变量传参
- 在 CLion 中创建基于 CubeMX 的 STM32 工程
- 【Rust日报】 2020-09-03 Google - XLS 加速硬件合成
- 算法篇:栈之常见题型
- 算法篇:栈之字符串相关题目
- redis的安装与启动以及注意事项
- 算法篇:利用map求数组交集
- 分布式锁:一、基础知识
- 钓鱼城杯2020 部分WriteUp
- setbit的实际应用