源代碼思路分析:
【一】如何生成圖片網格,我想到兩種方法:
(1)把這張大圖切成16張小圖,然後用img標簽的src
(2)只有一張大圖,然後每個元素的背景圖用css的background-position進行切割定位,這樣就需要16個數組[0,0],[-150,0],[-300,0]..........(我采用這種)
【二】圖片背景定位數組與布局定位數組
在選擇了使用CSS定位切圖,就需要生成數據。
需要的css背景 定位數組為:[0,0],[-150,0],[-300,0],[-450,0],
[0,-150],[-150,-150],[-300,-150],[-450,-150],
[0,-300],[-150,-300],[-300,-300],[-450,-300],
[0,-450],[-150,-450],[-300,-450],[-450,-450]
它們當中都用到了[0,-150,-300,-450]其中的值(就是我定義圖片高,寬150的倍數值),所以就利用這個值通過for(){}自動生成數組
代碼如下:
//this.nCol在這裡是4 --- 因為我的拼圖是4*4
// this.nArea是150,是每張圖片的寬,高(600px/4)--大圖是600*600
var l = [],
p = [];
for(var n=0;n<this.nCol;n++){
l.push(n*(this.nArea+1)); //生成[0,151,302,453] 網格的布局定位數組,因為我的效果需要邊框(圖中的綠色邊框),所以與css背景定位數組就不一樣了
p.push(-n*this.nArea); // 生成了[0,-150,-300,-450]就是上面說的,CSS背景定位值
}
for(var i=0;i<this.nLen;i++){ // this.nLen 是為 16
var t = parseInt(i/this.nCol),
k = i - this.nCol*t,
aP = [],
aL = [];
aP.push(p[k],p[t],i); //這裡我給css背景定位數組額外加了i,是為第3步判斷用的,不需要拿來設置css屬性的,我把它設置為標簽的屬性裡[bg-i]
aL.push(l[k],l[t]);
this.aBgp[i] = aP;
this.aLayout[i] = aL;
}
【三】判斷是否完成
第二個元素(div)應用了css背景定位 this.aBgp[1] (值為[-150,0,1]) ,而隨機分配的布局定位假如是this.aLayout[3] (這裡的3是隨機生成的)(值為[453,0]),那麼left:453px,top:0;
挪動這個元素,改變的是它的letf,top值,而不是本身結構的順序,獲取這個元素的left,top的值(假如是挪到left:151px,top:0),然後拿來與this.aLayout[1]的值[151,0](裡面的1索引,就是本身標簽屬性的[bg-i]=1也是this.aBgp[1] 的索引)判斷,相等就說明這個元素挪動後的位置是正確。
詳細代碼:
代碼如下:
/*
version:2.0
*/
function GyPuzzleGame(option){
this.target = $(option.target);
this.data = option.data; //圖片數據
this.opt = option;
this.nLen = option.count; //多少張拼圖
this.aColLayout = option.aColLayout || [0,151,302,453];//布局橫向數組
this.aRowLayout = option.aRowLayout || [0,151];//布局豎向數組
this.aColBgp = option.aColBgp || [0,-150,-300,-450];//布局橫向數組
this.aRowBgp = option.aRowBgp || [0,-150];//布局豎向數組
this.nCol = this.aColLayout.length;
this.nRow = this.aRowLayout.length;
this.aLayout = []; //布局數組
this.aBgp = []; //css背景定位數組
this.init();
}
GyPuzzleGame.prototype = {
getRand:function(a,r){
var arry = a.slice(0),
newArry = [];
for(var n=0;n<r;n++){
var nR = parseInt(Math.random()*arry.length);
newArry.push(arry[nR]);
arry.splice(nR,1);
}
return newArry;
},
setPos:function(){
for(var i=0;i<this.nLen;i++){
var t = parseInt(i/this.nCol),
l = i - this.nCol*t,
aP = [],
aL = [];
aP.push(this.aColBgp[l],this.aRowBgp[t],i);
aL.push(this.aColLayout[l],this.aRowLayout[t]);
this.aBgp[i] = aP;
this.aLayout[i] = aL;
}
},
isPass:function(item){
var _that = this,
is = 0;
item.each(function(){
var l = parseInt($(this).css('left')),
t = parseInt($(this).css('top')),
i = parseInt($(this).attr('data-bgi'));
if(l==_that.aLayout[i][0]&&t==_that.aLayout[i][1]){
is ++;
}
});
return is;
},
createDom:function(){
var layout = this.getRand(this.aLayout,this.nLen);
// console.log(layout);
for(var n=0;n<this.nLen;n++){
var t = parseInt(n/this.nCol),
l = n - this.nCol*t;
var html = $('<div data-bgi="'+this.aBgp[n][2]+'" class="puzzle_list"></div>').
css({'left':layout[n][0]+'px',
'top':layout[n][1]+'px',
'background-image':'url('+this.data+')',
'background-position':this.aBgp[n][0]+'px'+' '+this.aBgp[n][1]+'px'
});
this.target.append(html);
}
},
move:function(){
var $div = this.target.find('.puzzle_list'),
_that = this;
var hasElem = function(){
var t = false;
$div.each(function(){
if($(this).hasClass("on")){
t = true;
}
});
return t;
};
// click
$div.click(function(){
var $this = $(this);
if(hasElem()&&!$this.hasClass("on")){
var index = $('.on').index();
if($div.eq(index).is(':animated')||$this.is(':animated')){
return false;
}
var l = $div.eq(index).position().left,
t = $div.eq(index).position().top,
myl = $this.position().left,
myt = $this.position().top;
$(this).animate({'left':l,'top':t});
$div.eq(index).css({'z-index':'1'}).animate({'left':myl,'top':myt},function(){
$(this).removeClass("on");
$(this).find('span').remove();
$(this).css({'z-index':'0'});
if(_that.isPass($div) == _that.nLen){
if(typeof _that.opt.success == 'function'){
_that.opt.success({target:_that.target});
}
}
});
}
else {
if($this.hasClass("on")){
$this.removeClass("on");
$this.find('span').remove();
}
else {
$this.addClass("on").append("<span></span>");
}
}
});
},
init:function(){
// 設置CSS背景定位與元素布局數組
this.setPos();
// 創建元素
this.createDom();
// 挪動圖片
this.move();
}
}
//實例調用
new GyPuzzleGame({
'data':'images/03.jpg',
'target':'#pA',
'count':8,
'success':function(opt){
opt.target.append('<div class="puzzle_mask"></div><div class="puzzle_pass">恭喜過關</div>');
}
});