逐帧还是视频,如何选择
前言
最近在做一个游戏技能展示的效果,效果一般都有3s左右,鉴于效果复杂度只能通过逐帧或视频来实现展示。既然有两种实现方式,如何选择呢?先来简单分析下:
逐帧
所谓逐帧,就是把动画帧导出为图片,然后再用代码把没一帧的图片按照一定的频率进行切换,达到动画重组的播放效果。以3s的动画,每秒26帧的速度来计算,需要72张图片才能实现。同理如果帧数要求越高,需要的图片就越多。难度主要涉及到图片素材处理、图片资源加载、逐帧播放不掉帧等等
视频
视频这个没什么好说的,关键是看怎么播放。因为要达到的效果是看起来像一个页面动画而不是视频播放,所以要求是表面上看不出是视频播放即可。最大的难点也在于此,比如ios下是Safari下,页面的视频播放是会自动脱离页面全屏播放的。
视频代替逐帧的尝试
懒于对素材的处理以及确保动画播放更流畅,决定去尝试通过视频来实现,但最终这是一次失败的尝试,既然花时间尝试,也积累一些经验,在这简单分享下:
1、如何解决ios下视频全屏播放的问题
默认video标签实现的视频播放,在ios下都会全屏播放,脱离页面。
发现了webkit-playsinline
这个好东西,只需要在video标签用上这个属性就能实现非全屏下播放视频:
1 2 3 | < video webkit-playsinline = "true" src = "" > < p >请在支持HTML5 video标签的浏览器中</ p > </ video > |
ios微信测试,恩,ok了!但是可悲的是目前Safari不支持该属性,听说ios10会支持...
那么Safari这个能解决吗?继续搜索,又发现一个好东西iphone-inline-video.browser.js
(本次测试的最大惊喜,解决了多年的困惑!!!),已经有大神解决了这个问题。
插件地址:https://github.com/bfred-it/iphone-inline-video
引入插件后,只需要简单调用即可:
1 2 | var video = document.querySelector( 'video' ); makeVideoPlayableInline(video); |
里面还提到用css干掉video默认居中的那个播放按钮:
css代码如下:
1 2 3 4 5 6 | .IIV::-webkit-media-controls-play-button, .IIV::-webkit-media-controls-start-playback-button { opacity: 0 ; pointer-events: none ; width : 5px ; } |
其中上面的IIV是插件给video标签增加的class。
这样在ios基本可以实现完美内联播放视频了(其它什么UC,qq等等这些浏览器没做测试,有需要的自行测试)。
2、安卓下杂乱的表现
在安卓下情况就不乐观了,比如华为荣耀下的自带浏览器(下面没特殊指出都是测试机子的自带浏览器)会强制加上播放控制:
也出现不支持-webkit-media-controls-play-button
的情况,居中的播放按钮无法去除。还有一些手机检测到视频播放直接横屏全屏播放了。所以想保留video完美内联播放,安卓机子很多问题。
还有个致命点是,有些机子在播放视频时会把视频置为层级最高,上面无法再覆盖东西了。
那么可以借助canvas来画视频么?
大概的思路是:通过一个隐藏的video视频播放,然后通过一个按钮控制播放,用canvas来绘制画面出来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | < h2 >video播放</ h2 > < video webkit-playsinline = "true" preload = "auto" id = "myvideo" src = "" > < p >请在支持HTML5 video标签的浏览器中</ p > </ video > < br > < h2 >canvas</ h2 > < canvas id = "mycanvas" width = "400" height = "225" ></ canvas > < a href = "javascript:;" id = "Jplay" >播放</ a > < script > var myvideo=document.getElementById("myvideo"); //获取画布对象 var mycanvas=document.getElementById("mycanvas"); var playbtn=document.getElementById("Jplay"); playbtn.addEventListener('click', function () { if (myvideo.paused) { myvideo.currentTime = 0; myvideo.play(); // requestAnimFrame(p); } else { myvideo.pause(); } }); var fps=30/1000; setInterval(function(){ mycanvas.getContext("2d").drawImage(myvideo,0,0,400,225); },fps); </ script > |
效果截图:
最终还是未能达到预期效果,在ios这种效果结合内联视频播放的处理,是正常的。但是在安卓下有些机子直接不支持canvas绘制视频,有些还是会全屏播放视频等等各种问题。
所以总得来说,这个尝试失败告终,最后还是通过逐帧来解决实际需求。但是Safari的内联解决方案还是收获不少~
手机阅读请扫描下方二维码:
做仅需要在微信中传播的项目时,上述都可用~
1
1
1
1
1
12345678
12345678
12345678
12345678
12345678
12345678
12345678

12345678

lcvenoowhhdthdlidryg
12345678

12345678

1

1

1

1

1

1

1

1

1

1

1

1

1

1
1
1
1
1
1
1
1
1
1
1
1
1