Posted in Javascript onApril 16, 2012
这个东西让我想起了俄罗斯方块,这个实现起来很简单,容器里面所有的块元素用绝对定位排列,如果能放的下就放在这里,如果放不下了,在队列中找到能放得下的元素放置,
实在找不到,则换行排列下一行,具体思路是这样。代码里有详细的注释直接看代码吧。
下面是一个demo:
http://demo.3water.com/js/2012/sortRect/
代码打包下载 sortRect.rar
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> <title>不规则宽高排列</title> <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.js"> </script> <script type="text/javascript" src="http://code.jquery.com/ui/1.8.18/jquery-ui.min.js"> </script> <style type="text/css"> .box { position: absolute; width: 100px; height: 100px; border: 1px solid #ffffff; display: none; background: url(img/1.jpg); /*margin-left: 4px; margin-top: 4px;*/ } .box2 { position: absolute; width: 100px; height: 202px; border: 1px solid #ffffff; display: none; background: url(img/2.jpg); /*margin-left: 4px; margin-top: 4px;*/ } .box3 { position: absolute; width: 202px; height: 100px; border: 1px solid #ffffff; display: none; background: url(img/3.jpg); /*margin-left: 4px; margin-top: 4px;*/ } .box4 { position: absolute; width: 202px; height: 202px; border: 1px solid red; background: url(img/4.jpg); display: none; } </style> </head> <body> <!-- 排列好下面20个方块 --> <div id="pannel" style=" position:relative; width:1500px; height:800px; border:1px solid red; overflow:hidden;"> <div class="box"> </div> <div class="box"> </div> <div class="box3"> </div> <div class="box"> </div> <div class="box3"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box2"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box2"> </div> <div class="box"> </div> <div class="box4"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box2"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box3"> </div> <div class="box"> </div> <div class="box4"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box3"> </div> <div class="box"> </div> <div class="box2"> </div> <div class="box"> </div> <div class="box4"> </div> <div class="box2"> </div> <div class="box"> </div> <div class="box2"> </div> <div class="box"> </div> <div class="box4"> </div> <div class="box"> </div> <div class="box3"> </div> <div class="box"> </div> <div class="box4"> </div> <div class="box"> </div> <div class="box3"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box3"> </div> <div class="box2"> </div> <div class="box"> </div> <div class="box2"> </div> <div class="box"> </div> <div class="box4"> </div> <div class="box"> </div> <div class="box"> </div> </div> <div id="con"> </div> <script type="text/javascript"> //初始化矩阵 var initMatrix = function(x, y){ if (!x || !y) { return; } x = ~ ~ x; y = ~ ~ y; var mt = []; var i = 0; var getX = function(xl){ var i = 0; var matrixX = []; for (; i < xl; i++) { matrixX[i] = 0; } return { mt: matrixX, isComplete: false, spaces: [{ index: 0, len: matrixX.length }] }; } for (; i < y; i++) { mt[i] = getX(x); } return mt; } //生成元素相应的队列 var getQuene = function(eleColl, base){ if (!eleColl) { return; } var quene = []; var i = 0; var len = eleColl.length; var getEleMatrix = function(ele, base){ var ht = ele.outerHeight() / base.height; var wt = ele.outerWidth() / base.width; return { ele: ele, ht: ht, wt: wt } } for (; i < len; i++) { quene[i] = getEleMatrix($(eleColl[i]), base); } return quene; } //以行为单位扫描矩阵 var sortEveryEle = function(pannelMatrix, sortQuene, unitEle, callback){ if (!pannelMatrix || !sortQuene) { return; } unitEle = unitEle || { width: 0, height: 0 }; var checkSpace = function(line){ var i = 0; var len = line.mt.length; var tmpWt = 0; var tmpidx = 0; var tmpQuene = []; var isSetIdx = false; for (; i < len; i++) { if (line.mt[i] == 0) { if (!isSetIdx) { tmpidx = i; isSetIdx = true; } tmpWt++; } if ((line.mt[i] == 1) || (i == len - 1)) { //保存space信息到里面队列 if (tmpWt > 0) { tmpQuene.push({ index: tmpidx, len: tmpWt }); } //清空临时信息 tmpidx = 0; tmpWt = 0; } } if (tmpQuene.length <= 0) { line.isComplete = true; } line.spaces = tmpQuene; return; } var updateMartix = function(curLine, mt, ele, spidx, lineNum){ var i = j = 0; //获取当前空白信息 var sp = curLine.spaces[spidx]; //如果占用多行则更新所有占用行的空间 if (ele.ht > 1) { j = 0; for (; j < ele.ht; j++) { i = 0; for (; i < ele.wt; i++) { mt[lineNum + j].mt[sp.index + i] = 1; } //更新空白空间 checkSpace(mt[lineNum + j]); } } else {//如果是单行的话只要更新第一个本行 for (; i < ele.wt; i++) { curLine.mt[sp.index + i] = 1; } //更新模块 checkSpace(curLine); } }; //获取合适的元素 var getRightEle = function(stQu, wd){ var i = 0; var len = stQu.length; for (; i < len; i++) { if (stQu[i].wt <= wd) { return stQu.splice(i, 1); } } return; } //扫描单行 var scanLine = function(oneLine, sortQuene, mt, lineNum){ var i = 0; var len = oneLine.spaces.length; //填充 var theWt = oneLine.spaces[i].len; var mtLeft = mtTop = 0; //判断能容纳的宽是多少 var rtEle = getRightEle(sortQuene, theWt); if (rtEle) { //放置元素 //rtEle[0].ele.css("left", oneLine.spaces[i].index * 102);//base width //rtEle[0].ele.css("top", lineNum * 102);//base height; mtLeft = oneLine.spaces[i].index * (unitEle.width || 0); mtTop = lineNum * (unitEle.height || 0); if (callback) { callback({ left: mtLeft, top: mtTop, rect: rtEle[0] }); } //更新矩阵 updateMartix(oneLine, mt, rtEle[0], i, lineNum); //返回位置队列 return { left: mtLeft, top: mtTop, rect: rtEle[0] } } } var i = j = 0; var pmLen = pannelMatrix.length; var completeLine = 0; var thePosQuene = [], pos; for (; i < pmLen; i++) { while (!pannelMatrix[i].isComplete && (sortQuene.length > 0)) { pos = scanLine(pannelMatrix[i], sortQuene, pannelMatrix, i); if (pos) { thePosQuene.push(pos); } } } return thePosQuene; } var con = $("#con"); //生成相关的二维数组 var baseWidth = 102; var baseHeight = 102; var base = { width: baseWidth, height: baseHeight } var pannel = $("#pannel"); var thePannelSize = { width: pannel.width(), height: pannel.height() }; var pannelMatrix = initMatrix(thePannelSize.width / baseWidth, thePannelSize.height / baseHeight); //得到要排序的不规则宽高的方块队列 var sortQuene = getQuene(pannel.find("div"), base); //遍历matrix var theQu = sortEveryEle(pannelMatrix, sortQuene, base); var theQuOne = theQu.shift(); var selfCall = function(){ if (!theQuOne) { return; } var my = arguments.callee; theQuOne.rect.ele.show().animate({ left: "+" + theQuOne.left, top: "+" + theQuOne.top }, { duration: 1000, easing: "easeOutBounce", complete: function(){ theQuOne = theQu.shift(); my.call(); } }); } selfCall(); </script> </body> </html>
基于jquery的不规则矩形的排列实现代码
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@