上一篇中介绍了一个简单的拼图。缺点是图片只要放对位置,就不会再被拖动。现在我们可以把这个拼图的代码稍加修改,给它增加一些难度。(改动的代码我会用注释的方式作为比较和参考。这篇博文写了很久但是我一直忘了发出来。后来我还有小小地优化过代码,所以下面的都是旧代码了,仅供学习参考用。新版代码地址: https://github.com/JennieJi/jquery-jigsaw
- 继续沿用上一篇中的HTML结构,小修CSS:
这么做完全是因为jQuery UI会在元素dropped之后自动给元素加上position:relative属性。而在此我们需要的是absolute属性,在#jigsaw这个DIV中给每一块图片定位。#jigsaw IMG.dropped{ position:absolute !important;}
- 依旧先声明一些常用的变量。
这个版本中我们不但需要match来计算放对位置的图片数,而是用.dropped这个class直接来判断。var jigsaw = $('#jigsaw'), imgs = jigsaw.find("IMG"); var col = 3, row = 3, //match = col * row, width = imgs.width(), height = imgs.height(), order = new Array();
- 写一个给图片定位的方法。
上面代码中有两个参数。index是将图片定位在所在格子的索引号,img是需要被定位的图片对象。function setPosition( index, img ){ var nowCol = index % col, nowRow = parseInt( index / col ); img.css({ 'left': nowCol * width, 'top': nowRow * height }); }
首先根据index来计算这个格子所在的行列,然后用行列计算图片相对于整个拼图的位置,并给它加上CSS。 - 打乱图片的顺序。可以看到,算法是同上一篇中一模一样的,但是省去了许多行的代码。并且因为我去掉了match这个量,所以代码需要稍加修改。最后,同样用
imgs.each(function(i){ $(this).attr('id','jigsaw' + i); $(this).addClass("ready"); }); //for( match; match>0; match-- ){ for( var i = 0; i<9; i++ ){ $("<div/>").appendTo(jigsaw); //var now = col * row - match, // nowCol = now % col, // nowRow = parseInt( now / col ); //var selectImg = imgs.filter(".ready").eq( parseInt( Math.random() * 10 ) % match ); var selectImg = imgs.filter(".ready").eq( parseInt( Math.random() * 10 ) % ( col * row - i ) ); // selectImg.css({ // 'left': nowCol * width, // 'top': nowRow * height //}); setPosition(i, selectImg);selectImg.removeClass("ready"); order[/*now*/ i] = selectImg.attr('id').replace(/jigsaw/i,""); }
- 给图片添加拖动效果。
imgs.draggable({ containment: "#jigsaw-wrapper", scroll:false });
- 同上篇相同,也利用打乱顺序时顺便插入的DIV来辅助判断图片的插入位置是否对。
思路是,通过比对drop的图片ID号,并由一个变量存储比对通过的图片数量,如果数量达到9则拼图完成
$('DIV', jigsaw).each( function(i){ var obj = $( "#jigsaw" + order[i] ); if( obj.attr('id') == 'jigsaw' + i ){ obj.addClass("dropped"); } $(this).droppable({ drop:function( event, ui ){ if( ui.draggable.attr('id')== 'jigsaw' + i ){ ui.draggable.addClass("dropped"); setPosition( i , ui.draggable ); if( jigsaw.find("IMG.dropped").length == 9 ){ alert("Complete!"); } } }, activate:function( event,ui ){ setPosition( i , ui.draggable ); }, out:function( event,ui ){ ui.draggable.removeClass("dropped"); } }); });