Skip to content

Instantly share code, notes, and snippets.

@joedaniels29
Forked from KraigWalker/FlexGrid.js
Last active August 29, 2015 14:08
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 joedaniels29/e41d550ec8fd7d1a6d16 to your computer and use it in GitHub Desktop.
Save joedaniels29/e41d550ec8fd7d1a6d16 to your computer and use it in GitHub Desktop.
define(function, exports, module) {
var View = require('famous/core/View');
var Entity = require('famous/core/Entity');
var Modifier = require('famous/core/Modifier');
var Transform = require('famous/core/Transform');
var Transitionable = require('famous/transitions/Transitionable');
var TransitionableTransform = require('famous/transitions/TransitionableTransform');
function FlexGrid() {
View.apply(this, arguments);
// private variables
this._cachedWidth null;
this._height = null;
this._modifiers = [];
this._states = [];
// Add entity to the global index of surfaces
this.id = Entity.register
}
FlexGrid.prototype = Object.create(View.prototype);
FlexGrid.prototype.constructor = FlexGrid;
FlexGrid.DEFAULT_OPTIONS = {
flexGutter: false,
minCol: 2,
topMargin: 0,
colGutter: 0,
rowGutter: 0,
itemSize: [0, 0],
transition: false
};
/**
* Re-organise the layout of the gird
**/
function _reflow(width) {
// if we don't have grid items, we should return nothing
if (!this._items) return;
var states = this.options.flexGutter ?
_calcFlexSpacing.call(this, width) :
_calcSpacing.call(this, width);
_animate.call(this, states);
}
/**
* Calculate normal spacing
**/
function _calcSpacing(width) {
var colGutter = this.options.colGutter;
var itemSize = this.options.itemSize;
var ySpacing = colGutter + itemSize[0];
var numCols = Math.min(Math.floor((width - 2 * this.options.sideMargin + colGutter)/(ySpacing)), this._items.length);
var sideMargin = Math.max(this.options.sideMargin, (width - numCols * ySpacing + colGutter)/2);
// calculate states, based on our results
return _calcStates.call(this, numCols, ySpacing, sideMargin, width);
}
function _calcStates(numCols, ySpacing, sideMargin, width) {
var positions = [];
var size = this.options.itemSize;
var col = 0;
var row = 0;
var xPos;
var yPos;
// minCols is the smallest number of columns to have
// before degrade down to a signle column view.
if (numCols < this.options.minCol) {
numCols = 1;
sideMargin = 0;
size = [width, this.options.itemSize[1]];
}
for (var i = 0; i < this._items.length; i++) {
xPos = sideMargin + col * ySpacing;
yPos = this.options.topMargin + row * (this.options.rowGutter + this.options.itemSize[1]);
positions.push([xPos, yPos]);
col ++;
if(col === numCols) {
row++;
col = 0;
}
this._height = yPos
}
this._height += this.options.itemSize[1] + this.options.topMargin;
return {
positions: positions,
size: size
};
}
/**
* Create a modifier for each state change for our Grid
* Or call the one assigned to the state if it already exists
**/
function _animate(states) {
var size = states.size;
for(var i = 0; i < states.positions.length; i++) {
var position = states.positions[i];
if(this._modifiers[i] === undefined) _createModifier.call(this, i, position, size);
else _animateModifier.call(this, i, position, size);
}
}
function _createModifier(index, position, size) {
var transformItem = {
transform: new TransitionableTransform(transform.translate.apply(null, position)),
size: new Transitionable((size || this.options.itemSize))
}
var modifier = new Modifier({
transform: transitionItem.transform,
size: transitionItem.size
});
this._states[index] = transitionItem;
this._modifiers[index] = modifier;
}
function _animateModifier(index, position, size) {
var transformTransitionable = this._states[index].transform;
var sizeTransitionable = this._states[index].size;
// Cancel any previous transitions
transformTransitionable.halt();
sizetransitionable.halt();
// Apply a new transform & transition to move to
transformTransitionable.setTranslate(position, this.options.transition);
sizeTransitionable.set(size, this.options.transition);
}
FlexGrid.prototype.render = function render() {
return this.id;
};
FlexGrid.prototype.sequenceFrom = function sequenceFrom(items) {
this._items = items;
};
// Apply changes to the created element.
FlexGrid.prototype.commit = function commit(context) {
var size = context.size;
var width = size[0];
var specs = [];
if (this._cachedWidth !== width) {
_reflow.call(this, width);
this._cachedWidth = width;
}
for(var i = 0; i < this._modifiers.length; i++) {
var item = this._items[i];
var spec = this._modifiers[i].modify({
target: item.render()
});
specs.push(spec);
}
return specs;
};
FlexGrid.prototype.getSize = function getSize() {
if (!this._height) return;
return [this._cachedWidth, this._height];
};
module.exports = FlexGrid;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment