Skip to content

Commit

Permalink
Merge pull request #32 from jeremyruppel/fixups
Browse files Browse the repository at this point in the history
Miscellaneous fixes
  • Loading branch information
pdokas authored Nov 6, 2017
2 parents a4ace4c + 5f3124a commit ebd2bf1
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 95 deletions.
74 changes: 42 additions & 32 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@
'use strict';

var merge = require('merge'),
Row = require('./row'),
layoutConfig = {},
layoutData = {};
Row = require('./row');

/**
* Create a new, empty row.
*
* @method createNewRow
* @return A new, empty row of the type specified by this layout.
*/
function createNewRow() {
* Create a new, empty row.
*
* @method createNewRow
* @param layoutConfig {Object} The layout configuration
* @param layoutData {Object} The current state of the layout
* @return A new, empty row of the type specified by this layout.
*/

function createNewRow(layoutConfig, layoutData) {

var isBreakoutRow;

Expand Down Expand Up @@ -48,10 +49,13 @@ function createNewRow() {
* Note: the row must have already been completed.
*
* @method addRow
* @param layoutConfig {Object} The layout configuration
* @param layoutData {Object} The current state of the layout
* @param row {Row} The row to add.
* @return {Array} Each item added to the row.
*/
function addRow(row) {

function addRow(layoutConfig, layoutData, row) {

layoutData._rows.push(row);
layoutData._layoutItems = layoutData._layoutItems.concat(row.getItems());
Expand All @@ -63,14 +67,17 @@ function addRow(row) {
}

/**
* Calculate the current layout for all items in the list that require layout.
* "Layout" means geometry: position within container and size
*
* @method computeLayout
* @param itemLayoutData {Array} Array of items to lay out, with data required to lay out each item
* @return {Object} The newly-calculated layout, containing the new container height, and lists of layout items
*/
function computeLayout(itemLayoutData) {
* Calculate the current layout for all items in the list that require layout.
* "Layout" means geometry: position within container and size
*
* @method computeLayout
* @param layoutConfig {Object} The layout configuration
* @param layoutData {Object} The current state of the layout
* @param itemLayoutData {Array} Array of items to lay out, with data required to lay out each item
* @return {Object} The newly-calculated layout, containing the new container height, and lists of layout items
*/

function computeLayout(layoutConfig, layoutData, itemLayoutData) {

var laidOutItems = [],
itemAdded,
Expand All @@ -94,7 +101,7 @@ function computeLayout(itemLayoutData) {

// If not currently building up a row, make a new one.
if (!currentRow) {
currentRow = createNewRow();
currentRow = createNewRow(layoutConfig, layoutData);
}

// Attempt to add item to the current row.
Expand All @@ -103,14 +110,14 @@ function computeLayout(itemLayoutData) {
if (currentRow.isLayoutComplete()) {

// Row is filled; add it and start a new one
laidOutItems = laidOutItems.concat(addRow(currentRow));
laidOutItems = laidOutItems.concat(addRow(layoutConfig, layoutData, currentRow));

if (layoutData._rows.length >= layoutConfig.maxNumRows) {
currentRow = null;
return true;
}

currentRow = createNewRow();
currentRow = createNewRow(layoutConfig, layoutData);

// Item was rejected; add it to its own row
if (!itemAdded) {
Expand All @@ -120,12 +127,12 @@ function computeLayout(itemLayoutData) {
if (currentRow.isLayoutComplete()) {

// If the rejected item fills a row on its own, add the row and start another new one
laidOutItems = laidOutItems.concat(addRow(currentRow));
laidOutItems = laidOutItems.concat(addRow(layoutConfig, layoutData, currentRow));
if (layoutData._rows.length >= layoutConfig.maxNumRows) {
currentRow = null;
return true;
}
currentRow = createNewRow();
currentRow = createNewRow(layoutConfig, layoutData);
}
}
}
Expand Down Expand Up @@ -155,7 +162,7 @@ function computeLayout(itemLayoutData) {

}

laidOutItems = laidOutItems.concat(addRow(currentRow));
laidOutItems = laidOutItems.concat(addRow(layoutConfig, layoutData, currentRow));
layoutConfig._widowCount = currentRow.getItems().length;

}
Expand All @@ -175,14 +182,17 @@ function computeLayout(itemLayoutData) {
}

/**
* Takes in a bunch of box data and config. Returns
* geometry to lay them out in a justified view.
*
* @method covertSizesToAspectRatios
* @param sizes {Array} Array of objects with widths and heights
* @return {Array} A list of aspect ratios
**/
* Takes in a bunch of box data and config. Returns
* geometry to lay them out in a justified view.
*
* @method covertSizesToAspectRatios
* @param sizes {Array} Array of objects with widths and heights
* @return {Array} A list of aspect ratios
*/

module.exports = function (input, config) {
var layoutConfig = {};
var layoutData = {};

// Defaults
var defaults = {
Expand Down Expand Up @@ -229,7 +239,7 @@ module.exports = function (input, config) {
layoutConfig._widowCount = 0;

// Convert widths and heights to aspect ratios if we need to
return computeLayout(input.map(function (item) {
return computeLayout(layoutConfig, layoutData, input.map(function (item) {
if (item.width && item.height) {
return { aspectRatio: item.width / item.height };
} else {
Expand Down
131 changes: 68 additions & 63 deletions lib/row.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,25 @@
var merge = require('merge');

/**
* Row
* Wrapper for each row in a justified layout.
* Stores relevant values and provides methods for calculating layout of individual rows.
*
* @param {Object} layoutConfig - The same as that passed
* @param {Object} Initialization parameters. The following are all required:
* @param params.top {Number} Top of row, relative to container
* @param params.left {Number} Left side of row relative to container (equal to container left padding)
* @param params.width {Number} Width of row, not including container padding
* @param params.spacing {Number} Horizontal spacing between items
* @param params.targetRowHeight {Number} Layout algorithm will aim for this row height
* @param params.targetRowHeightTolerance {Number} Row heights may vary +/- (`targetRowHeight` x `targetRowHeightTolerance`)
* @param params.edgeCaseMinRowHeight {Number} Absolute minimum row height for edge cases that cannot be resolved within tolerance.
* @param params.edgeCaseMaxRowHeight {Number} Absolute maximum row height for edge cases that cannot be resolved within tolerance.
* @param params.isBreakoutRow {Boolean} Is this row in particular one of those breakout rows? Always false if it's not that kind of photo list
* @param params.widowLayoutStyle {String} If widows are visible, how should they be laid out?
* @constructor
*/
* Row
* Wrapper for each row in a justified layout.
* Stores relevant values and provides methods for calculating layout of individual rows.
*
* @param {Object} layoutConfig - The same as that passed
* @param {Object} Initialization parameters. The following are all required:
* @param params.top {Number} Top of row, relative to container
* @param params.left {Number} Left side of row relative to container (equal to container left padding)
* @param params.width {Number} Width of row, not including container padding
* @param params.spacing {Number} Horizontal spacing between items
* @param params.targetRowHeight {Number} Layout algorithm will aim for this row height
* @param params.targetRowHeightTolerance {Number} Row heights may vary +/- (`targetRowHeight` x `targetRowHeightTolerance`)
* @param params.edgeCaseMinRowHeight {Number} Absolute minimum row height for edge cases that cannot be resolved within tolerance.
* @param params.edgeCaseMaxRowHeight {Number} Absolute maximum row height for edge cases that cannot be resolved within tolerance.
* @param params.isBreakoutRow {Boolean} Is this row in particular one of those breakout rows? Always false if it's not that kind of photo list
* @param params.widowLayoutStyle {String} If widows are visible, how should they be laid out?
* @constructor
*/

var Row = module.exports = function (params) {

// Top of row, relative to container
Expand Down Expand Up @@ -66,25 +67,26 @@ var Row = module.exports = function (params) {
Row.prototype = {

/**
* Attempt to add a single item to the row.
* This is the heart of the justified algorithm.
* This method is direction-agnostic; it deals only with sizes, not positions.
*
* If the item fits in the row, without pushing row height beyond min/max tolerance,
* the item is added and the method returns true.
*
* If the item leaves row height too high, there may be room to scale it down and add another item.
* In this case, the item is added and the method returns true, but the row is incomplete.
*
* If the item leaves row height too short, there are too many items to fit within tolerance.
* The method will either accept or reject the new item, favoring the resulting row height closest to within tolerance.
* If the item is rejected, left/right padding will be required to fit the row height within tolerance;
* if the item is accepted, top/bottom cropping will be required to fit the row height within tolerance.
*
* @method addItem
* @param itemData {Object} Item layout data, containing item aspect ratio.
* @return {Boolean} True if successfully added; false if rejected.
*/
* Attempt to add a single item to the row.
* This is the heart of the justified algorithm.
* This method is direction-agnostic; it deals only with sizes, not positions.
*
* If the item fits in the row, without pushing row height beyond min/max tolerance,
* the item is added and the method returns true.
*
* If the item leaves row height too high, there may be room to scale it down and add another item.
* In this case, the item is added and the method returns true, but the row is incomplete.
*
* If the item leaves row height too short, there are too many items to fit within tolerance.
* The method will either accept or reject the new item, favoring the resulting row height closest to within tolerance.
* If the item is rejected, left/right padding will be required to fit the row height within tolerance;
* if the item is accepted, top/bottom cropping will be required to fit the row height within tolerance.
*
* @method addItem
* @param itemData {Object} Item layout data, containing item aspect ratio.
* @return {Boolean} True if successfully added; false if rejected.
*/

addItem: function (itemData) {

var newItems = this.items.concat(itemData),
Expand Down Expand Up @@ -172,24 +174,25 @@ Row.prototype = {
},

/**
* Check if a row has completed its layout.
*
* @method isLayoutComplete
* @return {Boolean} True if complete; false if not.
*/
* Check if a row has completed its layout.
*
* @method isLayoutComplete
* @return {Boolean} True if complete; false if not.
*/

isLayoutComplete: function () {
return this.height > 0;
},


/**
* Set row height and compute item geometry from that height.
* Will justify items within the row unless instructed not to.
*
* @method completeLayout
* @param newHeight {Number} Set row height to this value.
* @param widowLayoutStyle {String} How should widows display? Supported: left | justify | center
*/
* Set row height and compute item geometry from that height.
* Will justify items within the row unless instructed not to.
*
* @method completeLayout
* @param newHeight {Number} Set row height to this value.
* @param widowLayoutStyle {String} How should widows display? Supported: left | justify | center
*/

completeLayout: function (newHeight, widowLayoutStyle) {

var itemWidthSum = this.left,
Expand Down Expand Up @@ -289,13 +292,14 @@ Row.prototype = {
},

/**
* Force completion of row layout with current items.
*
* @method forceComplete
* @param fitToWidth {Boolean} Stretch current items to fill the row width.
* This will likely result in padding.
* @param fitToWidth {Number}
*/
* Force completion of row layout with current items.
*
* @method forceComplete
* @param fitToWidth {Boolean} Stretch current items to fill the row width.
* This will likely result in padding.
* @param fitToWidth {Number}
*/

forceComplete: function (fitToWidth, rowHeight) {

// TODO Handle fitting to width
Expand All @@ -317,12 +321,13 @@ Row.prototype = {
},

/**
* Return layout data for items within row.
* Note: returns actual list, not a copy.
*
* @method getItems
* @return Layout data for items within row.
*/
* Return layout data for items within row.
* Note: returns actual list, not a copy.
*
* @method getItems
* @return Layout data for items within row.
*/

getItems: function () {
return this.items;
}
Expand Down

0 comments on commit ebd2bf1

Please sign in to comment.