基于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五图轮播切换实用版
Aug 17 Javascript
js不能获取隐藏的div的宽度只能先显示后获取
Sep 04 Javascript
让IE8浏览器支持function.bind()方法
Oct 16 Javascript
浅谈javascript 函数属性和方法
Jan 21 Javascript
js实现的黑背景灰色二级导航菜单效果代码
Aug 24 Javascript
JavaScript知识点整理
Dec 09 Javascript
基于Bootstrap实现的下拉菜单手机端不能选择菜单项的原因附解决办法
Jul 22 Javascript
用Vue.extend构建消息提示组件的方法实例
Aug 08 Javascript
微信小程序之swiper轮播图中的图片自适应高度的方法
Apr 23 Javascript
Babel 入门教程学习笔记
Jun 13 Javascript
js中apply()和call()的区别与用法实例分析
Aug 14 Javascript
Vue页面渲染中key的应用实例教程
Jan 12 Vue.js
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
解决phpmyadmin中缺少mysqli扩展问题的方法
2013/05/06 PHP
thinkPHP5.0框架验证码调用及点击图片刷新简单实现方法
2018/09/07 PHP
PHP常见过waf webshell以及最简单的检测方法
2019/05/21 PHP
让您的菜单不离网站
2006/10/03 Javascript
用倒置滤镜把div倒置,再把table倒置。
2007/07/31 Javascript
extjs 学习笔记 四 带分页的grid
2009/10/20 Javascript
javascript中xml操作实现代码
2011/11/21 Javascript
js对table的td进行相同内容合并示例详解
2013/12/27 Javascript
javascript的BOM汇总
2015/07/16 Javascript
jquery mobile开发常见问题分析
2016/01/21 Javascript
基于vuejs+webpack的日期选择插件
2020/05/21 Javascript
js仿搜狐视频记录片列表展示效果
2020/05/30 Javascript
Vue实现动态响应数据变化
2017/04/28 Javascript
微信小程序表单验证错误提示效果
2017/05/19 Javascript
angularjs2中父子组件的数据传递的实例代码
2017/07/05 Javascript
详解vue-router 命名路由和命名视图
2018/06/01 Javascript
4个顶级开源JavaScript图表库
2018/09/29 Javascript
python 捕获 shell/bash 脚本的输出结果实例
2017/01/04 Python
Python实现图片滑动式验证识别方法
2017/11/09 Python
python 分离文件名和路径以及分离文件名和后缀的方法
2018/10/21 Python
解决win7操作系统Python3.7.1安装后启动提示缺少.dll文件问题
2019/07/15 Python
基于Tensorflow:CPU性能分析
2020/02/10 Python
Python开发企业微信机器人每天定时发消息实例
2020/03/17 Python
Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作
2020/06/06 Python
CSS3 选择器 属性选择器介绍
2012/01/21 HTML / CSS
澳大利亚在线百货商店:Real Smart
2017/08/13 全球购物
奶茶专卖店创业计划书
2014/01/18 职场文书
主持人婚宴答谢词
2014/01/28 职场文书
质量月活动策划方案
2014/03/10 职场文书
幼儿园中班上学期评语
2014/04/18 职场文书
让世界充满爱演讲稿
2014/05/24 职场文书
节约用水的口号
2014/06/20 职场文书
创建绿色学校先进个人材料
2014/08/20 职场文书
2015年体育部工作总结
2015/04/02 职场文书
解决Golang中goroutine执行速度的问题
2021/05/02 Golang
MySQL的Query Cache图文详解
2021/07/01 MySQL