用HTML5制作视频拼图的教程

2022-10-20,,,,

几天前同事给我看了一个特效,是一个拼图游戏,不同的是,拼图里的是动画。他让我看下做个demo,于是就自己整了一会,也确实不难。用canvas很容易做。所以这篇博文不适合高手看。。。。就是随便写来玩玩的。
效果图:

至少我刚看到这个的时候觉得挺新颖的,所以才会想到做出来玩玩,觉得楼主out的哥们请轻喷

  不多说,先上demo:视频拼图  (或许要等一会才能看到效果,我是直接在w3school那里搞了个视频链接过来的,拖动什么的都做的很简单,或许还有些bug,毕竟就只是做一个demo玩玩而已,说说原理就行了),还有一点,直接把视频的当前帧画到canvas中在移动设备上好像还不支持。。。至少我用ipad看了一下,发现画不上去,如果有知道肿么解决这问题的大牛请为小弟解答一下,不甚感激

  原理:每一块拼图就是一个canvas,同时还需要一个离屏canvas。先整一个video标签

复制代码代码如下:</p>
<p><video id="video" src="http://www.w3school.com.cn/example/html5/mov_bbb.mp4" width="600px" height="400px" controls="control" loop="loop" style="display:block;position:absolute;top:-6000px;"></video></p>
<p>

并且把video隐藏掉,然后播放视频的时候把每一帧都画到离屏canvas中(离屏canvas就是隐藏了的canvas,用于保存数据),写法很简单:

复制代码代码如下:ctx.drawimage(video , 0 , 0 , vw , vh);

,直接用drawimage方法画上去就行了。为何要先用离屏canvas呢,因为如果直接把每一帧数据同时画到所有拼图块的canvas中,浏览器会瞬间崩掉。所以用一个离屏canvas作为缓冲。先把当前帧的数据保存到canvas,然后再将canvas画到作为拼图块的canvas中。将canvas画到canvas中也很简单,也是用drawimage就可以搞定:

ctx2.drawimage(cs , -this.cols*this.w , -this.rows*this.h , vw , vh);

然后。。。。原理就这么简单,之后提醒一点,用requestanimationframe循环取帧时,要限一下速,例如下面所写的,我是每30毫秒取一次,推荐30~50毫秒,太低浏览器容易崩溃,太高的话视频出现卡帧现象了:

 
复制代码代码如下:
function animate(){
var newtime = new date();
if(newtime - lasttime > 30){
lasttime = newtime;
ctx.drawimage(video , 0 , 0 , vw , vh);
canvases.foreach(function(){
var ctx2 = this.cas.getcontext('2d');
ctx2.drawimage(cs , -this.cols*this.w , -this.rows*this.h , vw , vh);
});
}
if("requestanimationframe" in window){
requestanimationframe(animate);
}
else if("webkitrequestanimationframe" in window){
webkitrequestanimationframe(animate);
}
else if("msrequestanimationframe" in window){
msrequestanimationframe(animate);
}
else if("mozrequestanimationframe" in window){
mozrequestanimationframe(animate);
}
}

最后贴出所有代码: 
复制代码代码如下:
<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<style>
body{margin:0;padding:0;}
.allcanvas{
position: relative;
margin:50px auto;
width:600px;
}
.vcanvas{
position: absolute;
display: block;
border: 1px solid;
}
</style>
<title>视频拼图</title>
</head>
<body>
<div class="allcanvas">
<canvas id="liping" width="600" height="400" style="display:none"></canvas>
</div>
<video id="video" src="http://www.w3school.com.cn/example/html5/mov_bbb.mp4" width="600px" height="400px" controls="control" loop="loop" style="display:block;position:absolute;top:-6000px;"></video>
<script>
var video = document.getelementbyid("video");
var cs = document.getelementbyid("liping");
var ctx = cs.getcontext('2d')
var rows = 3,
cols = 3,
cb = document.queryselector(".allcanvas"),
vw = 600,
vh = 400,
canvases = [];</p>
<p> function createcanvas(){
var num = rows*cols;
for(var i=0;i<cols;i++){
for(var j=0;j<rows;j++){
var canvas = new vcanvas(math.random()*600, math.random()*600 , vw/rows , vh/cols , j , i);
canvases.push(canvas);
}
}
}</p>
<p> var vcanvas = function(x,y,w,h,cols,rows){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.cols = cols;
this.rows = rows;
this.creat();
this.behavior();
}
vcanvas.prototype = {
creat:function(){
this.cas = document.createelement("canvas");
cb.appendchild(this.cas);
this.cas.classname = "vcanvas";
this.cas.id = "vc_"+(this.cols+1)*(this.rows+1);
this.cas.style.left = this.x+"px";
this.cas.style.top = this.y+"px";
this.cas.width = this.w;
this.cas.height = this.h;
},
behavior:function(){
this.cas.onmousedown = function(e){
e = e || window.event;
var that = this;
var om = {
x:e.clientx,
y:e.clienty
}
window.onmousemove = function(e){
e = e || window.event;
var nm = {
x:e.clientx,
y:e.clienty
}
that.style.left = parseint(that.style.left.replace("px","")) + (nm.x-om.x) + "px";
that.style.top = parseint(that.style.top.replace("px","")) + (nm.y-om.y) + "px";
om = nm;
}
window.onmouseup = function(){
this.onmousemove = null;
}
}
}
}</p>
<p> array.prototype.foreach = function(callback){
for(var i=0;i<this.length;i++){
callback.call(this[i]);
}
}</p>
<p> var lasttime = 0;
function initanimate(){
lasttime = new date();
createcanvas();
animate();
}</p>
<p> function animate(){
var newtime = new date();
if(newtime - lasttime > 30){
lasttime = newtime;
ctx.drawimage(video , 0 , 0 , vw , vh);
canvases.foreach(function(){
var ctx2 = this.cas.getcontext('2d');
ctx2.drawimage(cs , -this.cols*this.w , -this.rows*this.h , vw , vh);
});
}
if("requestanimationframe" in window){
requestanimationframe(animate);
}
else if("webkitrequestanimationframe" in window){
webkitrequestanimationframe(animate);
}
else if("msrequestanimationframe" in window){
msrequestanimationframe(animate);
}
else if("mozrequestanimationframe" in window){
mozrequestanimationframe(animate);
}
}</p>
<p> video.play();
initanimate();
</script>
</body>
</html>

《用HTML5制作视频拼图的教程.doc》

下载本文的Word格式文档,以方便收藏与打印。