• [模仿]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      '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

  • 相关阅读:
    Mysql常用sql&索引失效场景
    Linux命令demo
    js中浮点数的精度问题
    Linux运行程序出现Cannot execute binary file
    我的第一篇博客文(抽象类练习)
    关于MyEclipse中build path和compiler的jre不匹配
    jQuery操作单选框、多选框是否选中问题
    oracle索引操作
    JS组件多选下拉框Bootstrap之select2 使用心得
    MyEclipse10——java项目clean重新编译
  • 原文地址:https://www.cnblogs.com/wangxinsheng/p/3800710.html
Copyright © 2020-2023  润新知