Created
November 30, 2016 15:22
-
-
Save aprilandjan/e96880ba96182ebf1d9d87f133487943 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by Merlin on 16/11/30. | |
*/ | |
const map = new Map() | |
function getElement (el) { | |
if (typeof el === 'string') { | |
el = document.querySelector(el) | |
} | |
return el | |
} | |
function getColumnDistribution (num) { | |
var arr = [] | |
for (var i = 0; i < num; i++) { | |
arr.push(Math.floor(100 * i / num).toFixed(3) + '%') | |
} | |
return arr | |
} | |
function getHeightDistribution (num) { | |
var arr = [] | |
for (var i = 0; i < num; i++) { | |
arr.push(0) | |
} | |
return arr | |
} | |
/** | |
* 实现 masonry layout | |
*/ | |
class Masonry { | |
static init (box, config) { | |
box = getElement(box) | |
var instance = map.get(box) | |
if (!instance) { | |
instance = new Masonry(box, config) | |
map.set(box, instance) | |
} | |
return instance | |
} | |
/** | |
* | |
* slot: 槽选择器 | |
* columnCount: 列数 | |
* columnDistribution: 列分布 | |
* | |
* @param config | |
*/ | |
constructor (box, config) { | |
// 容器 | |
this.box = box | |
// 槽选择器 | |
this.slotSelector = config.slot | |
// 列数 | |
this.columnCount = config.columnCount | |
// 列分布 | |
this.columnDistribution = config.columnDistribution || getColumnDistribution(this.columnCount) | |
// 高度分布 | |
this.heightDistribution = getHeightDistribution(this.columnCount) | |
// 当前最低的那个槽的序号 | |
this.minIndex = 0 | |
// 当前处理了的序号 | |
this.arragedIndex = 0 | |
} | |
/** | |
* 重新布局 | |
*/ | |
resetLayout () { | |
this.arragedIndex = 0 | |
this.heightDistribution = getHeightDistribution(this.columnCount) | |
this.minIndex = 0 | |
this.updateLayout() | |
} | |
/** | |
* 如果 slots 数量变化了, 只布局新增的 slot | |
*/ | |
updateLayout () { | |
var slots = this.box.querySelectorAll(this.slotSelector) | |
console.log(slots) | |
var total = slots.length | |
for (var i = this.arragedIndex; i < total; i++) { | |
let slot = slots[i] | |
let rect = slot.getBoundingClientRect() | |
slot.style.cssText = `left: ${this.columnDistribution[this.minIndex]}; top: ${this.heightDistribution[this.minIndex]}px;` | |
this.heightDistribution[this.minIndex] += rect.height | |
let min = Math.min.apply(Math, this.heightDistribution) | |
this.minIndex = this.heightDistribution.indexOf(min) | |
this.arragedIndex ++ | |
} | |
let max = Math.max.apply(Math, this.heights) | |
this.box.style.cssText = `height:${max}px;` | |
} | |
} | |
export default Masonry |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment