-
Notifications
You must be signed in to change notification settings - Fork 96
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(Layout): fixed JustifiedLayout for group (#47)
* feat(Layout): add GoogleLayout * feat(Layout): add GoogleLayout on outline * test(Layout): test GoogleLayout append/prepend * test(Layout): test GoogleLayout - remove Item * chore(Layout): move folder lib * chore(Layout): move dijkstra file * chore(Layout): move Render file to lib * chore(Layout): fixed name GoogleLayout to JustifiedLayout * chore(Layout): fixed JustifiedLayout for group * chore(Layout): add test file
- Loading branch information
Showing
9 changed files
with
526 additions
and
445 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export const APPEND = true; | ||
export const PREPEND = false; | ||
export const VERTICAL = "vertical"; | ||
export const HORIZONTAL = "horizontal"; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
const APPEND = true; | ||
const PREPEND = false; | ||
|
||
function fill(length, pos) { | ||
return new Array(length).fill(pos); | ||
} | ||
class GridLayout { | ||
constructor(options = {}) { | ||
this.options = Object.assign( | ||
{ | ||
direction: "vertical", | ||
margin: 0, | ||
}, | ||
options); | ||
this.isHorizontal = this.options.direction === "horizontal"; | ||
this.columnSize = 0; | ||
this.coulmnLength = 0; | ||
} | ||
getPoints(outlines) { | ||
const pos = this.isHorizontal ? "left" : "top"; | ||
|
||
return outlines.map(outline => outline[pos]); | ||
} | ||
checkColumn(item) { | ||
const margin = this.options.margin; | ||
// if direction is horizontal, fixed dimension is height | ||
// if direction is vertical, fixed dimension is width | ||
const sizeName = this.isHorizontal ? "height" : "width"; | ||
|
||
this.columnSize = item.size[sizeName]; | ||
this.columnLength = parseInt((this[sizeName] + margin) / (this.columnSize + margin), 10); | ||
} | ||
_insert(items, outline, isAppend) { | ||
const columnSize = this.columnSize; | ||
const length = items.length; | ||
const margin = this.options.margin; | ||
const isHorizontal = this.isHorizontal; | ||
const sizeName = isHorizontal ? "width" : "height"; | ||
const pointCaculateName = isAppend ? "min" : "max"; | ||
const startOutline = outline.slice(); | ||
const endOutline = outline.slice(); | ||
|
||
for (let i = 0; i < length; ++i) { | ||
const point = Math[pointCaculateName](...endOutline); | ||
const index = endOutline.indexOf(point); | ||
const item = items[i]; | ||
const size = item.size[sizeName]; | ||
const pos1 = isAppend ? point : point - margin - size; | ||
const endPos1 = pos1 + size + margin; | ||
const pos2 = (columnSize + margin) * index; | ||
const endPos2 = pos2 + columnSize + margin; | ||
|
||
// tetris | ||
items[i].rect = { | ||
left: isHorizontal ? pos1 : pos2, | ||
right: isHorizontal ? endPos1 : endPos2, | ||
top: isHorizontal ? pos2 : pos1, | ||
bottom: isHorizontal ? endPos2 : endPos1, | ||
}; | ||
items[i].column = index; | ||
|
||
endOutline[index] = isAppend ? endPos1 : pos1; | ||
} | ||
if (isAppend) { | ||
return { | ||
start: startOutline, | ||
end: endOutline, | ||
}; | ||
} | ||
return { | ||
start: endOutline, | ||
end: startOutline, | ||
}; | ||
} | ||
append(items, outline) { | ||
const clone = items.map(item => ({ | ||
size: Object.assign({}, item.size), | ||
})); | ||
let startOutline = outline; | ||
|
||
if (!this.columnLength) { | ||
this.checkColumn(items[0]); | ||
} | ||
if (outline.length !== this.columnLength) { | ||
startOutline = fill(this.columnLength, Math.min(...outline)); | ||
} | ||
const result = this._insert(clone, startOutline, APPEND); | ||
|
||
return { | ||
items: clone, | ||
outlines: result, | ||
}; | ||
} | ||
prepend(items, outline) { | ||
const clone = items.map(item => ({ | ||
size: Object.assign({}, item.size), | ||
})); | ||
let startOutline = outline; | ||
|
||
if (!this.columnLength) { | ||
this.checkColumn(items[0]); | ||
} | ||
if (outline.length !== this.columnLength) { | ||
startOutline = fill(this.columnLength, Math.max(...outline)); | ||
} | ||
const result = this._insert(clone, startOutline, PREPEND); | ||
|
||
return { | ||
items: clone, | ||
outlines: result, | ||
}; | ||
} | ||
layout(groups, outline) { | ||
this.checkColumn(groups[0].items[0]); | ||
// if outlines' length and columns' length are now same, re-caculate outlines. | ||
let startOutline; | ||
|
||
if (outline.length !== this.columnLength) { | ||
const pos = Math.min(...outline); | ||
|
||
// re-layout items. | ||
startOutline = fill(this.columnLength, pos); | ||
} else { | ||
startOutline = outline.slice(); | ||
} | ||
groups.forEach(group => { | ||
const items = group.items; | ||
const result = this._insert(items, startOutline, APPEND); | ||
|
||
group.outlines = result; | ||
startOutline = result.end; | ||
}); | ||
} | ||
setViewport(width, height) { | ||
this.width = width; | ||
this.height = height; | ||
} | ||
} | ||
|
||
export default GridLayout; |
Oops, something went wrong.