作者:张鑫旭
1、爆款H5中的炫酷场景的技术实现
每年都会迸出一些爆款H5,这些H5通常会有一些酷酷的场景变换。
例如网易Julia H5。创意很棒,传播效果很广,其技术实现就相当简单粗暴,直接一个3分多钟的不带停顿的视频:
类似使用视频的爆款H5还有很多,确实是一个非常不错的解决方案。
但是,视频的实现也有局限:
iOS下不能自动播放,需要至少touch一次屏幕,这个有时候还挺烦人的,例如我们想做一个H5 app闪屏的时候就蛋疼了。
不能在中间穿插棒棒的交互效果,例如,需要视频某一帧暂停,鼠标hover或者touch的时候,当前画面有交互效果,就很不好处理。
播放的速率不能随心所欲控制,视频完成也就定死了。
如果有些信息是动态的,需要与用户信息关联,则视频方案也会面临很大的调整,因为总不可能每一个用户生成一个不一样的视频,需要辅助额外手段满足需求(例如CSS覆盖定位)。
此时又当如何处理呢?
我们可以使用序列图片,通过JS脚本,来模拟视频播放效果,以上所有局限将通通可以规避。
2、序列图片视频化技术实现方法很多
序列图片视频化技术实现方法很多,例如:
合在一张大图上,使用CSS3
animation
控制background-position
实现播放效果。此方法优点是方便快捷,但是,background-position
定位性能不怎么样,只适用于小元素小动画,例如一些loading效果,如果是全屏的大图切换,则在移动设备上可以明显感觉到卡顿;合在一张大图上,
transform
定位。性能还是撑不住;图片一次性在页面上,依次控制显隐。性能有所提高,但如果图片序列上百帧,图片尺寸较大,性能还是撑不住,客户端说不定会直接闪退。
页面上一个
<img>
元素,然后不断改变src
地址,不好意思,也不是很快。
总而言之,上面各种方法都是理论上可行,但实践下来的性能总不尽如人意。
那有没有什么高性能的实现方法呢?
有,一种是使用canvas绘图,但如果想要动态插入其他UI丰富的DOM结构(如登录模块),就比较麻烦;还有一种就是下面这个方法,实践下来性能可以,体验比较好,实现成本也不高。
3、序列图片视频化技术高性能实现方法
实现原理如下:
图片DOM对象预加载,放在内存中;
播放开始,页面append当前图片DOM,同时移除上一帧DOM图片(如果有),保证页面中仅有一个图片序列元素;
对,很简单,没什么高超的技巧,但就是这种实现策略,对页面的开销是上面几种方法中最小的,最终运行体验是最好的。
眼见为实,您可以狠狠地点击这里:序列图片实现视频播放效果demo
loading完毕,就可以看到一段播放效果——本人飞吻一枚:
效果之流畅,体验之良好,十有八九都会认为是视频,其实不是,就是图片,不断的图片DOM增删实现的类似视频效果。
核心JS代码如下(完整代码见demo),假设container
是容器元素,我们的图片已经预加载到store
对象中,结构如下:
var store = { length: 47, 1: img1, 2: img2, ... 47: img47 };
则有:
var index = 1; container.innerHTML = ''; // 依次append图片对象 var step = function () { if (store[index - 1]) { container.removeChild(store[index - 1]); } container.append(store[index]); // 序列增加 index++; // 如果不超过最大限制,播放下一帧 if (index <= 47) { // 42是按照每秒24帧计算的值 setTimeout(step, 42); } }; step();
上面代码红色高亮是实现的关键,container.removeChild(store[index - 1])
移除之前一帧图片DOM,container.append(store[index])
则是插入当前一帧DOM,人的肉眼习惯连续性感知事物,因此,这种删除和添加,用户是无感知的,于是一个流程的播放效果即达成,根据实践,就算每帧图片在几百K大小主流设备也能hold住。
由于本质上播放的是DOM对象,因此,我们不仅可以播放图片DOM,还可以是有着丰富HTML结构的<div>
元素,于是,什么样的交互实现都不在话下,比方说视频中要出现用户的姓名,怎么办,很简单啊,<div>
元素中定位下就好了。
现在,技术实现已经对设计没有任何限制啦,剩下的就是产品和设计的创意,下一个爆款H5就是你了!
4、番外技能:如何把视频变成序列图片?
如果贵厂有设计师,让设计师处理,基本上,AE之类软件应该都了解。
如果没有设计师,要前端小伙伴自己处理,怎么办?
拿本文的序列图片举例,我是这么处理的:
手机视频QQ传到自己电脑;
打开Photoshop,然后:文件-导入-视频帧到图层,会出现一个窗口,可以剪切需要导入的视频范围;
如果导入视频很长,建议先剪辑,再导入,除非你的电脑是iMac Pro这种级别的。
不做任何处理,直接:“文件-脚本-将图层导出到文件”;
node.js小工具批量重命名了下(导出图片名称后面序号是准确序号),工具使用的JavaScript代码如下:
var fs = require("fs"); fs.readdir('./', function(err, files) { files.forEach(function(filename) { if (/jpg$/.test(filename) == false) { return; } // 确定新旧文件名称 var oldPath = './' + filename, newPath = './' + filename.split(' ')[1]; // 重命名走起 fs.rename(oldPath, newPath, function() { console.log(filename + '重命名成功!'); }) }); })
5、关于性能其他需要注意的
人眼的跟踪能力要比大猩猩之类要弱的,因此,实际开发,并不一定需要每秒24帧的播放速率,你每秒18帧,对于一个H5运营活动而言,用户是无感知的。每秒18帧的播放可以节约不少请求和加载数据量,性能上也能有所提高,权衡来看,是推荐的,毕竟我们不是去参加动画比赛,是一个在线的web产品。
设计师喜欢使用非常高清的图片,实际上,没有必要,注意度,2倍尺寸,30%~40%的图片质量足够了,效果也非常好,这也是经过实践的,大家如果和设计师意见不一致,就可以让她看我写的这段话。有效降低不必要的图片尺寸,可以大大节约内存的开销,也是可以提高播放的性能和品质的。
于是,三管齐下:高性能技术实现策略,适当降低帧率,优化图片尺寸,必定助你H5炫酷效果流畅至极,好评如潮,boss交口称赞!
以上就是本文内容,感谢阅读,如果文中有表述不准确的地方,欢迎指正!