基于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 相关文章推荐
基于jQuery的Spin Button自定义文本框数值自增或自减
Jul 17 Javascript
jquery js 获取时间差、时间格式具体代码
Jun 05 Javascript
分享一个自己动手写的jQuery分页插件
Aug 28 Javascript
JSON取值前判断
Dec 23 Javascript
纯js实现仿QQ邮箱弹出确认框
Apr 29 Javascript
js实现网页多级级联菜单代码
Aug 20 Javascript
如何用JavaScript实现动态修改CSS样式表
May 20 Javascript
Jquery基础之事件操作详解
Jun 14 Javascript
深究AngularJS中$sce的使用
Jun 12 Javascript
用js屏蔽被http劫持的浮动广告实现方法
Aug 10 Javascript
vue如何进行动画的封装
Sep 26 Javascript
JavaScript实现10秒后再次获取验证码
Dec 02 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
使用phpQuery采集网页的方法
2013/11/13 PHP
PHP中批量生成静态html(命令行下运行PHP)
2014/04/19 PHP
php上传功能集后缀名判断和随机命名(强力推荐)
2015/09/10 PHP
PHP通过调用新浪API生成t.cn格式短网址链接的方法详解
2019/02/20 PHP
基于PHP+Mysql简单实现了图书购物车系统的实例详解
2020/08/06 PHP
做网页的一些技巧(续)
2007/02/01 Javascript
5个最佳的Javascript日期处理类库分享
2012/04/15 Javascript
简单的两种Extjs formpanel加载数据的方式
2013/11/09 Javascript
Node.js实现在目录中查找某个字符串及所在文件
2014/09/03 Javascript
不想让浏览器运行javascript脚本的方法
2015/11/20 Javascript
Javascript简单实现面向对象编程继承实例代码
2015/11/27 Javascript
BootStrap Table复选框默认选中功能的实现代码(从数据库获取到对应的状态进行判断是否为选中状态)
2017/07/11 Javascript
JavaScript实现二叉树的先序、中序及后序遍历方法详解
2017/10/26 Javascript
使用Vue如何写一个双向数据绑定(面试常见)
2018/04/20 Javascript
vue-cli3脚手架的配置及使用教程
2018/08/28 Javascript
Nodejs实现多文件夹文件同步
2018/10/17 NodeJs
vue实现路由切换改变title功能
2019/05/28 Javascript
vue2之简易的pc端短信验证码的问题及处理方法
2019/06/03 Javascript
vue设置一开始进入的页面教程
2019/10/28 Javascript
python解析json实例方法
2013/11/19 Python
python自定义解析简单xml格式文件的方法
2015/05/11 Python
Python实现学生成绩管理系统
2020/04/05 Python
Python批量合并有合并单元格的Excel文件详解
2018/04/05 Python
python自动发送邮件脚本
2018/06/20 Python
python中logging模块的一些简单用法的使用
2019/02/22 Python
美国男士内衣品牌:Tommy John
2017/12/22 全球购物
大学生自我鉴定范文
2013/12/28 职场文书
公证委托书
2014/08/01 职场文书
个人整改措施落实情况汇报
2014/10/29 职场文书
2016年政治理论学习心得体会
2016/01/25 职场文书
高效课堂教学反思
2016/02/24 职场文书
大学生饮品店创业计划书范文
2019/07/10 职场文书
Jupyter notebook 输出部分显示不全的解决方案
2021/04/24 Python
Vue接口封装的完整步骤记录
2021/05/14 Vue.js
海贼王十大逆天果实 魂魂果实上榜,岩浆果实攻击力最强
2022/03/18 日漫
css之clearfix的用法深入理解(必看篇)
2023/05/21 HTML / CSS