[模仿]canvas视频拼图

好久以前的了,那时html5刚出来不久吧,国外有人做了个用canvas来拼视频的游戏,觉得挺好玩的,就模仿了一下(模仿也是好久以前的事了)

---------------------

用到的东西:

1. html5 canvas标签

   drawImage (视频源)

2. html5 video标签

  source属性(为了浏览器兼容,需要多个视频来源)

3. JQuery

  选择器

  事件

4. js对象方法

----------------------

效果图:

------------------------

以下为乱七八糟的代码

1. html文件:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 5     <meta charset="utf-8">
 6     <meta http-equiv="charset" content="utf-8">
 7     <meta http-equiv="content-language" content="utf-8">
 8     <title>视频拼图</title>
 9     <meta name="keywords" content="视频拼图">
10     <meta name="description" content="视频拼图">
11     <!--<link rel="shortcut icon" href="imgs/favicon.ico">-->
12     <!-- 外部css -->
13     <link rel="stylesheet" href="css/guess_style.css">
14     <!-- 引用JQuery 库 -->
15     <script type="text/javascript" src="js/libs/jquery.js"></script>
16 </head>
17 <body>
18     <!-- html5 video Tag (hidden) -->
19     <div id="video">
20     </div>
21     <!-- import the js file -->
22     <script type="text/javascript" src="js/me/guessWXS.js"></script>
23     <!-- import the paramater file -->
24     <script type="text/javascript" src="js/me/guessParmsWXS.js"></script>
25     <script type="text/javascript">
26         //start the game
27         $(function () {
28             new guessWXS(options);
29         });
30     </script>
31 </body>
32 </html>    

 

2. guessWXS.js :

  1 ;
  2 var guessWXS = function (options) {
  3 //定义变量,我也忘记那些没有用到,那些用到了,只怪那时不好好写注释!!!现在丢人现眼了。。。
  4     this.options = options; // 接收参数
  5     this.videoCtrlObj;
  6     this.canvasLst = new Array();
  7     this.canvasDivLst = new Array();
  8     this.positionTop = new Array();
  9     this.positionLeft = new Array();
 10     this.eachHeight = 0;
 11     this.eachWidth = 0;
 12     this.wCount = 5;
 13     this.hCount = 4;
 14     this.canvasCount = this.wCount * this.hCount;
 15     this.down = false;
 16     this.befPageX;
 17     this.befPageY;
 18     this.oldLeft;
 19     this.oldTop;
 20     this.oldZIndex;
 21     this.divObj = null;
 22     this.start = false;
 23     this.win = false;
 24     this.wRate = 1;
 25     this.hRate = 1;
 26     this.doInit();  // 调用初期化方法
 27 }
 28 
 29 guessWXS.prototype.doInit = function () {
 30     // 初期化方法
 31     if ($(this.options.container).length > 0) {
 32         var obj = this;
 33         //video html
 34         $(this.options.container).append(this.options.videoHtml);
 35         //video attribute
 36         var videoObj = $(this.options.container).find("video").eq(0);
 37         $(videoObj).attr("id", this.options.id);
 38         var videoObjJs = document.getElementById(this.options.id);
 39         $(videoObj).hide();  // 隐藏video Tag (其实可以在js里处理好后,append 到画面的)
 40         //calculate video and canvas
 41         this.wRate = this.options.width / this.options.videoWidth;
 42         this.hRate = this.options.height / this.options.videoHeight;
 43         //video source
 44         for (var i = 0; i < this.options.videoUrl.length; i++) {
 45             videoObj.append("<source src='" + this.options.videoUrl[i] + "' />");
 46         }
 47         //video control
 48         var videoCtrl = document.getElementById(this.options.id);
 49         this.videoCtrlObj = videoCtrl;
 50         //canvas list 使用多个canvas来显示一个视频的各个部分(切割视频到canvas list)
 51         var top = 0;
 52         var left = 0;
 53         var topStep = this.options.height / this.hCount;
 54         var leftStep = this.options.width / this.wCount;
 55         var c = 0;
 56         var tempObj;
 57         //console.log(topStep, leftStep);
 58         for (var h = 0; h < this.hCount; h++) {
 59             for (var w = 0; w < this.wCount; w++) {
 60                 tempObj = $(this.options.canvasHtml).css({ "position": "absolute", "top": (h % this.hCount) * topStep, "left": (w % this.wCount) * leftStep, "border": "0px red solid", "margin": 0, "overflow": "hidden" });
 61                 tempObj.width(leftStep).height(topStep);
 62                 tempObj.find("canvas").attr("id", "canvasWXS_" + c);
 63                 $(this.options.container).append(tempObj);
 64                 this.canvasLst.push(document.getElementById("canvasWXS_" + c));
 65                 this.canvasDivLst.push(tempObj);
 66                 this.eachHeight = topStep;
 67                 this.eachWidth = leftStep;
 68                 // 保存正确结果,用于判断游戏是否结束
 69                 this.positionTop.push((h % this.hCount) * topStep);
 70                 this.positionLeft.push((w % this.wCount) * leftStep);
 71                 c++;
 72             }
 73         }
 74         // 对canvas 进行事件绑定
 75         for (var i = 0; i < this.canvasDivLst.length; i++) {
 76             this.canvasDivLst[i].bind("mousedown", function () { obj.doCanvasDivMouseDown(this); });
 77             this.canvasDivLst[i].bind("mouseup", function () { obj.doCanvasDivMouseUp(this); });
 78             this.canvasDivLst[i].bind("mousemove", function () { obj.doCanvasDivMouseMove(this); });
 79         }
 80         //videoCtrl.play();
 81         // 绑定视频播放事件,调用doTimeUpdate方法
 82         this.Bind(videoCtrl, "timeupdate", this.doTimeUpdate, this);
 83         $("body").bind("mouseout", function () {
 84             obj.down = false;
 85             if (obj.divObj != null) {
 86                 $(obj.divObj).css({ "z-index": obj.oldZIndex, "box-shadow": "0px 0px 0px 0px #000", "border": "none" });
 87                 $(obj.divObj).css({ "left": obj.oldLeft, "top": obj.oldTop });
 88             }
 89         });
 90         $(this.options.container).bind("click", function () { obj.doPlay(); });
 91         // 一秒后执行,其实可以在视频加载完后或加载一部分后再执行的
 92         setTimeout(function () { $(this.options.container).click();}, 1000);
 93     }
 94 };
 95 
 96 guessWXS.prototype.doTimeUpdate = function () {
 97 // 将当前的video图片,切割更新至canvas list
 98     var context;
 99     var h = 0;
100     var w = 0;
101     var topStep = this.options.height / this.hCount;
102     var leftStep = this.options.width / this.wCount;
103     for (var i = 0; i < this.canvasLst.length; i++) {
104         context = this.canvasLst[i].getContext("2d");
105         context.drawImage(this.videoCtrlObj, (w % this.wCount) * leftStep / this.wRate, (h % this.hCount) * topStep / this.hRate, leftStep / this.wRate, topStep / this.hRate, 0, 0, leftStep, topStep);
106         if ((i + 1) % this.wCount == 0) {
107             w = 0;
108             h++;
109         } else {
110             w++;
111         }
112     }
113 };
114 
115 guessWXS.prototype.doCanvasDivMouseDown = function (thisObj) {
116 // 鼠标按下,醒目标注当前的那块canvas
117     event.preventDefault();
118     if (this.start && !this.down) {
119         this.befPageX = event.pageX;
120         this.befPageY = event.pageY;
121         this.oldTop = parseInt($(thisObj).css("top").replace(/px/g, ""));
122         this.oldLeft = parseInt($(thisObj).css("left").replace(/px/g, ""));
123         this.oldZIndex = $(thisObj).css("z-index");
124         this.divObj = thisObj;
125         this.down = true;
126         $(thisObj).css({ "z-index": "999", "box-shadow": "0px 0px 20px 10px #fff" });
127     }
128     event.stopPropagation();
129 };
130 
131 guessWXS.prototype.doCanvasDivMouseUp = function (thisObj) {
132 // 替换两块canvas的位置
133     event.preventDefault();
134     if (this.start && this.down) {
135         this.befPageX = 0;
136         this.befPageY = 0;
137         this.divObj = null;
138         this.down = false;
139 
140         var tmpTop;
141         var tmpLeft;
142         var curTop = parseInt($(thisObj).css("top").replace(/px/g, "")) + this.eachHeight / 2;
143         var curLeft = parseInt($(thisObj).css("left").replace(/px/g, "")) + this.eachWidth / 2;
144         var backFlg = true;
145         for (var i = 0; i < this.positionTop.length; i++) {
146 
147             if (
148                 (this.positionTop[i] <= curTop && this.positionTop[i] + this.eachHeight >= curTop)
149                 && (this.positionLeft[i] <= curLeft && this.positionLeft[i] + this.eachWidth >= curLeft)
150             ) {
151                 for (var j = 0; j < this.canvasDivLst.length; j++) {
152                     tmpTop = parseInt($(this.canvasDivLst[j]).css("top").replace(/px/g, ""));
153                     tmpLeft = parseInt($(this.canvasDivLst[j]).css("left").replace(/px/g, ""));
154                     if (tmpTop == this.positionTop[i] && tmpLeft == this.positionLeft[i]) {
155                         backFlg = false;
156                         $(this.canvasDivLst[j]).css({ "left": this.oldLeft, "top": this.oldTop });
157                         $(thisObj).css({ "left": tmpLeft, "top": tmpTop });
158                         break;
159                     }
160                 }
161             }
162             if (!backFlg) { break; }
163         }
164         $(thisObj).css({ "z-index": this.oldZIndex, "box-shadow": "0px 0px 0px 0px #fff" });
165         if (backFlg) {
166             $(thisObj).css({ "left": this.oldLeft, "top": this.oldTop });
167         }
168         this.doJudge();
169     }
170     event.stopPropagation();
171 };
172 
173 guessWXS.prototype.doCanvasDivMouseMove = function (thisObj) {
174 // 移动canvas块
175     event.preventDefault();
176     if (this.start && this.down) {
177         $(thisObj).css({ "top": event.pageY - this.befPageY + parseInt($(thisObj).css("top").replace(/px/g, "")), "left": event.pageX - this.befPageX + parseInt($(thisObj).css("left").replace(/px/g, "")) });
178         this.befPageX = event.pageX;
179         this.befPageY = event.pageY;
180     }
181     event.stopPropagation();
182 };
183 
184 guessWXS.prototype.doPlay = function () {
185 // 播放视频
186     if (!this.start || this.win) {
187         if (this.win) {
188             this.win = !this.win;
189         } else {
190             this.doRandom();
191             this.videoCtrlObj.play();
192         }
193     }
194 };
195 
196 guessWXS.prototype.doRandom = function () {
197 // 打乱canvas list 顺序
198     var num1, num2;
199     var tmpPositionT = new Array();
200     var tmpPositionL = new Array();
201     //准备初期化数据
202     for (var i = 0; i < this.canvasDivLst.length; i++) {
203         tmpPositionT.push(parseInt($(this.canvasDivLst[i]).css("top").replace(/px/g, "")));
204         tmpPositionL.push(parseInt($(this.canvasDivLst[i]).css("left").replace(/px/g, "")));
205     }
206     //进行随机 [对换]
207     console.log(tmpPositionT, tmpPositionL);
208     for (var i = 0; i < this.options.randomCount/*this.canvasDivLst.length*/; i++) {
209         num1 = 0;
210         num2 = 0;
211         while (num1 == num2) {
212             num1 = Math.round(Math.random() * (this.canvasDivLst.length - 1));
213             num2 = Math.round(Math.random() * (this.canvasDivLst.length - 1));
214         }
215         tmpPositionT[num1] = tmpPositionT[num1] + tmpPositionT[num2];
216         tmpPositionT[num2] = tmpPositionT[num1] - tmpPositionT[num2];
217         tmpPositionT[num1] = tmpPositionT[num1] - tmpPositionT[num2];
218         tmpPositionL[num1] = tmpPositionL[num1] + tmpPositionL[num2];
219         tmpPositionL[num2] = tmpPositionL[num1] - tmpPositionL[num2];
220         tmpPositionL[num1] = tmpPositionL[num1] - tmpPositionL[num2];
221     }
222     for (var i = 0; i < tmpPositionT.length; i++) {
223         $(this.canvasDivLst[i]).css({ "left": tmpPositionL[i], "top": tmpPositionT[i] });
224     }
225     this.start = true;
226 };
227 
228 guessWXS.prototype.doJudge = function () {
229 // 判断是否正确
230     var winFlg = true;
231     for (var i = 0; i < this.canvasDivLst.length; i++) {
232         if (
233             this.positionTop[i] != parseInt($(this.canvasDivLst[i]).css("top").replace(/px/g, ""))
234             ||
235             this.positionLeft[i] != parseInt($(this.canvasDivLst[i]).css("left").replace(/px/g, ""))
236         ) {
237             winFlg = false;
238         }
239     }
240     if (winFlg) {
241         this.start = false;
242         this.down = false;
243         this.win = true;
244         alert("YOU WIN!,点击视频再玩一次");
245     }
246 };
247 
248 guessWXS.prototype.Bind = function (control, eventName, callBack, scope) {
249     if (!scope) { scope = window; }
250     $(control).bind(eventName, function () {
251         callBack.apply(scope, arguments);
252     });
253 };

 

3. guessParmsWXS.js (这个随意配置) :

 1 var options = {
 2     id: 'video1',
 3     container: '#video',
 4     videoHtml: "<video loop='loop'>Your browser does not support the video tag.</video>", // controls='controls'
 5     canvasHtml: "<div><canvas></canvas></div>",
 6     width: '640',
 7     height: '360',
 8     videoUrl: ['videos/BigBuckBunny_640x360.mp4', 'videos/BigBuckBunny_640x360.ogv'], //['videos/mov_bbb.ogg'],
 9     videoWidth: "640", //320
10     videoHeight: "360", //175
11     randomCount: 20
12 };

 

4. guess_style.css (其实里面没有什么) :

1 body {
2 }
3 #video{width:640px; height:360px; margin:auto; /*background:green;*/ position:relative;}

 

CSDN下载:(可以单机运行,不需要服务器)

http://download.csdn.net/detail/wangxsh42/7530147

posted @ 2014-06-21 11:16  望星辰  阅读(552)  评论(0编辑  收藏  举报