抖音多帧延迟教你前端实现方式

最近在学习WebAssembly,因为是提升性能,所以一直在使用canvas 做一些尝试。今天就突发奇想以前看见的抖音多帧延迟的装饰,今天就来分析实现下。

在这里插入图片描述

多帧延迟

先简单分析下这个效果,假设咱们有一个视频是宽400300, 分为100个4030的小方格,用固定的时间间隔播放格子。

  • 视频顺序播放
async function initVideo() {
		const stream = await navigator.mediaDevices.getUserMedia({
				video: {
					width:400,
					height:300
				}
			});
		video = document.querySelector('video');
		video.srcObject = stream;
		video.addEventListener('loadeddata', function(){
			video.play()
			cs.width = video.videoWidth;
			cs.height = video.videoHeight;
			drawCanvas(video);
		}, false);
		});
}
  • 创建数组Array(100);
let w = Math.floor(cs.width/obj.w);
let h = Math.floor(cs.height/obj.h);
list = new Array(w*h);
  • 每个时间间隔往数组里添加视频画面的区域 imageData
function getBlock () {
	let w = Math.floor(cs.width/obj.w);
	let h = Math.floor(cs.height/obj.h);
	let total = w*h;
	for(let i =0; i<w; i++){
		for(let j =0; j<h; j++) {
			if(j*w+i === index) {
				list[index] = {
					data: ctx.getImageData(i*obj.w,j*obj.h, obj.w,obj.h),
					x:obj.w*i,
					y:obj.h*j
				};
				break;
			}
		}
	}
	index ++;
	if(total === index) {
		index =0;
	}
}
  • 把imageData绘制到canvas上 完毕。效果达成
function drawCanvas() {
	ctx.drawImage(video,0,0,cs.width,cs.height);
	getBlock()
	list.forEach((item) => {
	  if(item['data']){
	  	ctx.putImageData(item['data'],item['x'],item['y']);
	  }
	})
	requestAnimationFrame(drawCanvas)
}

体验地址:https://ibeeger.com/demo/keyframe.html

发布了77 篇原创文章 · 获赞 5 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/uk_51/article/details/103721762