基于jquery的不规则矩形的排列实现代码


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>
Javascript 相关文章推荐
脚本合并提升javascript性能示例
Feb 24 Javascript
jQuery中:password选择器用法实例
Jan 03 Javascript
jquery validate和jquery form 插件组合实现验证表单后AJAX提交
Aug 26 Javascript
JavaScript DOM 学习总结(五)
Nov 24 Javascript
使用jQuery制作基础的Web图片轮播效果
Apr 22 Javascript
基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)
Nov 17 Javascript
利用jQuery插件imgAreaSelect实现图片上传裁剪(同步显示图像位置信息)
Dec 02 Javascript
javascript读取文本节点方法小结
Dec 15 Javascript
Angular5给组件本身的标签添加样式class的方法
Apr 07 Javascript
详解js创建对象的几种方法及继承
Apr 12 Javascript
详解javascript中的Error对象
Apr 25 Javascript
微信小程序 冒泡事件原理解析
Sep 27 Javascript
JavaScript打开word文档的实现代码(c#)
Apr 16 #Javascript
jQuery UI Autocomplete 1.8.16 中文输入修正代码
Apr 16 #Javascript
Moment.js 不容错过的超棒Javascript日期处理类库
Apr 15 #Javascript
5个最佳的Javascript日期处理类库分享
Apr 15 #Javascript
你需要知道的10个最佳javascript开发实践小结
Apr 15 #Javascript
javascript针对DOM的应用分析(四)
Apr 15 #Javascript
javascript针对DOM的应用分析(三)
Apr 15 #Javascript
You might like
使用GD库生成带阴影文字的图片
2015/03/27 PHP
PHP实现的简单网络硬盘
2015/07/29 PHP
php+flash+jQuery多图片上传源码分享
2020/07/27 PHP
PHP CURL post数据报错 failed creating formpost data
2016/10/16 PHP
PHP asXML()函数讲解
2019/02/03 PHP
HTTP头隐藏PHP版本号实现过程解析
2020/12/09 PHP
给Function做的OOP扩展
2009/05/07 Javascript
DLL+ ActiveX控件+WEB页面调用例子
2010/08/07 Javascript
JavaScript 继承使用分析
2011/05/12 Javascript
禁用键盘上的(全局)指定键兼容iE、Chrome、火狐
2013/05/14 Javascript
js中的hasOwnProperty和isPrototypeOf方法使用实例
2014/06/06 Javascript
js图片闪动特效可以控制间隔时间如几分钟闪动一下
2014/08/12 Javascript
原生js配合cookie制作保存路径的拖拽
2015/12/29 Javascript
JS三级可折叠菜单实现方法
2016/02/29 Javascript
JavaScript BASE64算法实现(完美解决中文乱码)
2017/01/10 Javascript
Javascript实现从小到大的数组转换成二叉搜索树
2017/06/13 Javascript
js实现图片懒加载效果
2017/07/17 Javascript
JS数组操作中的经典算法实例讲解
2017/07/26 Javascript
基于js中的原型(全面讲解)
2017/09/19 Javascript
图片加载完成再执行事件的实例
2017/11/16 Javascript
angular1配合gulp和bower的使用教程
2018/01/19 Javascript
微信小程序手机号码验证功能的实例代码
2018/08/28 Javascript
深入剖析JavaScript instanceof 运算符
2019/06/14 Javascript
高性能web服务器框架Tornado简单实现restful接口及开发实例
2014/07/16 Python
python多重继承实例
2014/10/11 Python
解决Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
2017/10/01 Python
Python2包含中文报错的解决方法
2018/07/09 Python
服务器端jupyter notebook映射到本地浏览器的操作
2020/04/14 Python
HTML5之SVG 2D入门7—SVG元素的重用与引用
2013/01/30 HTML / CSS
.NET remoting的两种通道是什么
2016/05/31 面试题
试用期自我鉴定范文
2014/03/20 职场文书
英文自荐信常用句子
2014/03/26 职场文书
百家讲坛观后感
2015/06/12 职场文书
2016春季运动会前导词
2015/11/25 职场文书
nginx配置虚拟主机的详细步骤
2021/07/21 Servers
Python+Selenium实现抖音、快手、B站、小红书、微视、百度好看视频、西瓜视频、微信视频号、搜狐视频、一点号、大风号、趣头条等短视频自动发布
2022/04/13 Python