为什么HTML5滚动视频在Safari更流畅?其他浏览器如何优化?
滚动同步视频动画跨浏览器流畅度差异问题
我和合作者正在开发滚动同步视频动画效果,要求页面向下滚动时视频能够同步播放。我们经过多轮视频压缩迭代优化播放流畅度,过程中发现哪怕是体积最大的视频在桌面端和移动端Safari上都播放流畅,但最小体积的视频在其他浏览器上仍存在明显卡顿。我们的目标是让视频达到滚动控制HTML5视频示例的流畅度。
为什么Safari上的播放表现要流畅得多?我们希望在其他浏览器上也达到同等流畅度,目前推测enter-view.js所依赖的requestAnimationFrame函数在Safari上的优化程度更高,不确定是否应当更换其他动画策略。
实现代码
JavaScript 代码
const container = d3.select('#scrolly-overlay'); const stepSel = container.selectAll('.step'); const progressCounter = d3.select('#progress'); let vid = document.getElementById('v0'); const containerHeightMultiplier = 300; const vidUrls = [{ format: 'webm', name: '10FPS_CQ_35', file: 'TestVidLowRes_VP8_10FPS_CQ35', size: "6.5MB" }, { format: 'webm', name: '10FPS_CQ_45', file: 'TestVidLowRes_VP8_10FPS_CQ45', size: "4.8MB" }, { format: 'mp4', name: '10FPS_RF_27', file: 'TestVidLowRes_H264_10FPS_RF27', size: "4.7MB" }, { format: 'mp4', name: '10FPS_RF_40', file: 'TestVidLowRes_H264_10FPS_RF40', size: "0.5MB" }, { format: 'webm', name: '5FPS_RF_40', file: 'testVidLowRes_VP8_5FPS_CQ35', size: '3.4MB' } ] d3.select('#vid-selection').selectAll('button').data(vidUrls).join('button') .text(d => d.name + '.' + d.format + '-' + d.size) .on('click', (event, d) => { d3.select('#vid-source') .attr('type', 'video/' + d.format) .attr('src', "https://s3.us-west-1.amazonaws.com/tao.mo.2021/" + d.file + '.' + d.format) d3.select('#selected-vid') .text(d.format + ': ' + d.name + ' (' + d.size + ')') vid.load() vid.addEventListener('loadedmetadata', function() { console.log(vid.fileSize) d3.select('#scrolly-overlay .scrolly article .step').style('min-height', Math.floor(vid.duration) * containerHeightMultiplier + "px") }); }) function updateChart(index) { stepSel.classed('is-active', (d, i) => i === index); } function updateVid(progress) { progressCounter.text(progress); } function init() { Stickyfill.add(d3.select('.sticky').node()); enterView({ selector: stepSel.nodes(), offset: 0.5, enter: el => { const index = +d3.select(el).attr('data-index'); updateChart(index); }, progress: (el, progress) => { progressCounter.text(progress); vid.currentTime = progress * vid.duration }, exit: el => { let index = +d3.select(el).attr('data-index'); index = Math.max(0, index - 1); updateChart(index); } }) } init();
CSS 代码
.filler { height: 20rem; text-align: center; } #scrolly-overlay .scrolly { max-width: 60rem; margin: 3rem auto; background-color: #f4f4f4; padding: 1rem; } #scrolly-overlay .scrolly article { padding: 0; max-width: 30rem; margin: 0 auto; position: relative; } #scrolly-overlay .scrolly article .step { margin-bottom: 1rem; } #scrolly-overlay .scrolly article .step:last-of-type { margin-bottom: 0; } #scrolly-overlay .scrolly article .step.is-active p { background-color: #008080; } #scrolly-overlay .scrolly article .step p { margin: 0; padding: 1rem; text-align: center; font-weight: 400; background-color: #5b5b5b; transition: background-color 250ms ease-in-out; color: #f4f4f4; } #scrolly-overlay .scrolly figure.sticky { position: sticky; width: 100%; height: 75vh; margin: 0; top: 3vh; left: 0; } #scrolly-overlay .scrolly figure.sticky video { position: absolute; top: 1%; left: 0.5%; width: 99%; background-color: #fff; } #scrolly-overlay .scrolly figure.sticky #progress { position: absolute; background-color: #fff; }
HTML 代码
<section class='filler'> <p> Scroll </p> <div id='vid-selection'></div> <h2 style='margin-top:10px;font-weight:bold;' id='selected-vid'></h2> </section> <section id='scrolly-overlay'> <div class='scrolly'> <figure class='sticky'> <video id="v0" playsinline tabindex="0" autobuffer="autobuffer" preload="preload"> <source id='vid-source'></source> </video> <div id='progress'>0</div> </figure> <article> <div class='step' data-width='10%' data-index='0'> <p>Text to Trigger Scroll</p> </div> </article> </div> </section> <section class='filler'> <p> End </p> </section>
内容的提问来源于stack exchange,提问作者ibrand。
相关产品推荐
相关产品推荐

