-
-
Save suhaotian/e2b71ec979fae37617f9 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
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