Skip to content

Instantly share code, notes, and snippets.

@kejun
Created March 7, 2015 12:14
Show Gist options
  • Select an option

  • Save kejun/72112e5848f5e3921b0d to your computer and use it in GitHub Desktop.

Select an option

Save kejun/72112e5848f5e3921b0d to your computer and use it in GitHub Desktop.

Revisions

  1. kejun created this gist Mar 7, 2015.
    99 changes: 99 additions & 0 deletions gistfile1.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,99 @@
    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;