用jQuery UI做简单九宫格拼图

最近在搞一个很复杂的页面,搞得脑子有点疲劳。。。抽空把前段时间用jQuery UI写的一个非常简单的九宫格拼图重新分析一下,转换一下心情。

Github URL: https://github.com/JennieJi/jquery-jigsaw

jQuery UI提供了许多非常有用的工具,如draggable、droppable等。这可以让我们用很少的代码实现复杂的功能,并且做到多浏览器兼容。

这个九宫格拼图根据需求的不同,我做了两个版本。由于两个版本的JS代码变化还是比较大的,所以我准备分开来讲。先讲最初也是最简单的版本。一步步来。

  1. 首先建好HTML文件,把你的9张切割好的图片都扔进去:
    <!doctype>
    <html>
    <head>

     

    </head>
    <body>
    <div id="jigsaw">
    	<img src="images/puzzle_r1_c1.gif" width="150" height="100" alt="Puzzle Piece"/>
    	<img src="images/puzzle_r1_c2.gif" width="150" height="100" alt="Puzzle Piece"/>
    	<img src="images/puzzle_r1_c3.gif" width="150" height="100" alt="Puzzle Piece"/>
    	<img src="images/puzzle_r2_c1.gif" width="150" height="100" alt="Puzzle Piece"/>
    	<img src="images/puzzle_r2_c2.gif" width="150" height="100" alt="Puzzle Piece"/>
    	<img src="images/puzzle_r2_c3.gif" width="150" height="100" alt="Puzzle Piece"/>
    	<img src="images/puzzle_r3_c1.gif" width="150" height="100" alt="Puzzle Piece"/>
    	<img src="images/puzzle_r3_c2.gif" width="150" height="100" alt="Puzzle Piece"/>
    	<img src="images/puzzle_r3_c3.gif" width="150" height="100" alt="Puzzle Piece"/>
    </div>
    <script type="text/javascript" src="scripts/jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="scripts/jquery-ui-1.8.21.custom.min.js"></script>
    <script type="text/javascript" src="scripts/jigsaw.js"></script>
    </body>
    </html>
    注意:图片插入顺序需要为正确顺序。稍后会用JS来打乱图片的顺序。
  2. 加上CSS使图片呈九宫格分布:
    #jigsaw{float:left;width:450px;}
    #jigsaw IMG{float:left;width:150px;height:100px;}
    
  3. 开始编写我的jigsaw.js。首先记录一下我们经常需要用到的量:
    var jigsaw = $('#jigsaw'),
        imgs = jigsaw.find("IMG");
    var col = 3,
        row = 3,
       match = col * row,
       width = imgs.width(),
       height = imgs.height(),
       order =  new Array();
    
  4. 接着,做一些准备工作。在这里,我为了便于判断图片的顺序,将正确的顺序写入图片的ID中。
    imgs.each(function(i){
    	$(this).attr('id','jigsaw' + i);
    	$(this).addClass("ready");
    });
    然后,打乱图片的顺序。
    这里用到了上面一段代码中,给图片加的"ready"类。
    思路是:在有"ready"这个class的图片中,随机选择一张图片,按从左到右、从上到下的顺序依次插入九宫格的相应位置,然后去掉它的"ready"类,直至9张图片位置都调整完成,match这个变量减为0。同时,在图片下面插入9个用于吸附图片的DIV。
    for( match; match>0; match-- ){
    	$("<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 );
    	selectImg.css({
    		'left': nowCol * width,
    		'top': nowRow * height
    	});
    	selectImg.removeClass("ready");
    	order[now] =  selectImg.attr('id').replace(/jigsaw/i,"");
    }
    如上,我用imgs.filter(".ready")先选出带有"ready"这个类的图片,然后用随机数选出第parseInt(Math.random()*10)%match张图片,将图片放到相应位置。
    改变位置后,我将目前的位置顺序记录到数组order中。
    做这步之后,还要将CSS做一些改动。如下:
    #jigsaw{float:left; width:450px; margin:103px 0 0 150px; position:relative; z-index:1;}
    #jigsaw DIV{float:left; width:150px; height:100px; padding:0;}
    #jigsaw IMG{float:left; width:150px; height:100px; font-size:3em; color:#fff; background:#ccc; position:absolute; z-index:2;}
  5. 接下来就要用神奇的jQuery UI来实现图片的拖放功能了。
    思路:图片拖到对应位置附近,就会被“吸附”进对应的DIV中,并且不能再被拖动。
    $('DIV', jigsaw).each( function(i){
    	var obj = $( "#jigsaw" + order[i] );
    	if( obj.attr('id') == 'jigsaw' + i ){
    		match++;
    		obj.appendTo( $(this) ).addClass("dropped");
    	}
    	else{
    		obj.draggable();
    		$(this).droppable({
    			drop:function( event, ui ){
    				if( ui.draggable.attr('id')== 'jigsaw' + i ){
    					ui.draggable.appendTo($(this)).addClass("dropped");
    					match++;
    					ui.draggable.draggable("disable");
    					$(this).droppable("disable");
    					if( match == 9 ){alert("Match!");}
    				}
    			}
    		});
    	}
    });
    
    如上,首先按排列顺序检查每张图片,是否正好分布在对应的位置。如果已经在对应的位置,则将它挪入对应的DIV中,给它一个class为"dropped",match数加1。
    dropped的CSS:
    #jigsaw IMG.dropped{ position:static !important;}
    
    将图片插入对应的div中后,需要将position属性更改为static,则图片会自动与DIV对齐。如果图片没有在对应位置,使用jQuery UI的Draggable方法使图片可以被拖动,并且使用Droppable方法使对应的DIV可以吸附图片。
    在DIV吸附图片的时候判断这张图片是不是被吸附在对应的DIV上,是的话给它加上"dropped"类,match数加1,并且禁掉这个DIV的可吸附性。
    当match为9的时候,即为9张图片都已经拖到对应位置,给出已经拼图完成的提示就大功告成啦!

另外一个版本比这个稍微高级一点。图片拖对位置之后,还可以重新被拖出去。虽说是在这个版本的基础上改的,但是基本上面目全非了T-T。

posted @ 2012-07-25 13:53  Jennie Ji  阅读(629)  评论(2编辑  收藏  举报