Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Rayi/782c76d3f33bdd17f5a98028293ef076 to your computer and use it in GitHub Desktop.
Save Rayi/782c76d3f33bdd17f5a98028293ef076 to your computer and use it in GitHub Desktop.
react + linear partition算法实现的图墙布局
var React = require('react');
var EventListener = require('react/lib/EventListener');
var partition = require('linear-partitioning');
var TileLayout = React.createClass({
getDefaultProps: function() {
return {
gutter: 0,
photos: []
}
},
getInitialState: function() {
return {
photos: this.props.photos,
gutter: this.props.gutter,
viewBounding: this.props.viewBounding,
size: []
}
},
componentDidMount: function() {
this.initLayout();
this._resizeListener = EventListener.listen(window, 'resize', this.initLayout);
},
componentWillUnmout: function() {
this._resizeListener.remove();
},
render: function() {
var photos = this.state.photos;
var blank = <p className="blank">(空)</p>;
return (
<div className="tile-layout-container">
{ photos.length ? photos.map(this.getGridCell) : blank }
</div>
);
},
getGridCell: function(photo, i) {
var size = this.state.size[i] || [];
var gutter = this.state.gutter;
var style = {
padding: gutter,
width: size[0] - gutter * 2,
height: size[1] - gutter * 2
};
return (
<div key={ i } className="tile-layout-cell" style={ style }>
<a href={ photo.raw } target="_blank">
<img src={ photo.url } />
</a>
</div>
);
},
initLayout: function() {
var photos = this.state.photos;
var size = [];
if (photos.length == 0) {
return;
}
var bounding = this.state.viewBounding;
var idealHeight = bounding[1];
var photoWidth = photos.map(function(p) {
return idealHeight * p.aspect_ratio | 0;
});
var totalWidth = photoWidth.reduce(function(a, b) {
return a + b;
});
if (totalWidth <= bounding[0]) {
size = photos.map(function(p, i) {
return [photoWidth[i], idealHeight];
});
this.setState({
size: size
});
return;
}
var rows = totalWidth / bounding[0] | 0;
var ratioSeq = photos.map(function(p) {
return p.aspect_ratio * 100 | 0;
});
partitionTable = partition(ratioSeq, rows);
var index = 0;
partitionTable.forEach(function(row) {
var buff_size = [];
var rowRatio = row.reduce(function(sum, r) {
buff_size.push(index);
return sum + photos[index++].aspect_ratio;
}, 0);
var rowHeight = bounding[0] / rowRatio | 0;
buff_size = buff_size.map(function(index) {
return [rowHeight * photos[index].aspect_ratio | 0, rowHeight];
});
size = size.concat(buff_size);
});
this.setState({
size: size
});
}
});
module.exports = TileLayout;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment