From f43904b9292e68d06d0410b6a05e1732d7f6b0e0 Mon Sep 17 00:00:00 2001 From: IjzerenHein Date: Thu, 15 Jan 2015 11:58:00 +0100 Subject: [PATCH] Updated docs + readme --- Gruntfile.js | 5 +- README.md | 14 ++- docs/LayoutController.md | 6 +- docs/ScrollController.md | 18 +++- docs/VirtualViewSequence.md | 105 +++++++++++++++++++++ docs/layouts/ProportionalLayout.md | 27 ++++++ docs/layouts/WheelLayout.md | 41 +++++++++ src/VirtualViewSequence.js | 143 +++++++++++++++++++---------- src/layouts/ProportionalLayout.js | 2 +- src/layouts/WheelLayout.js | 6 +- 10 files changed, 303 insertions(+), 64 deletions(-) create mode 100644 docs/VirtualViewSequence.md create mode 100644 docs/layouts/ProportionalLayout.md create mode 100644 docs/layouts/WheelLayout.md diff --git a/Gruntfile.js b/Gruntfile.js index 876e26d..354e6ca 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -27,6 +27,7 @@ module.exports = function(grunt) { { src: 'src/ScrollController.js', dest: 'docs/ScrollController.md' }, { src: 'src/FlexScrollView.js', dest: 'docs/FlexScrollView.md' }, { src: 'src/LayoutUtility.js', dest: 'docs/LayoutUtility.md' }, + { src: 'src/VirtualViewSequence.js', dest: 'docs/VirtualViewSequence.md' }, // helpers { src: 'src/helpers/LayoutDockHelper.js', dest: 'docs/helpers/LayoutDockHelper.md' }, // layouts @@ -34,7 +35,9 @@ module.exports = function(grunt) { { src: 'src/layouts/GridLayout.js', dest: 'docs/layouts/GridLayout.md' }, { src: 'src/layouts/ListLayout.js', dest: 'docs/layouts/ListLayout.md' }, { src: 'src/layouts/HeaderFooterLayout.js', dest: 'docs/layouts/HeaderFooterLayout.md' }, - { src: 'src/layouts/NavBarLayout.js', dest: 'docs/layouts/NavBarLayout.md' } + { src: 'src/layouts/NavBarLayout.js', dest: 'docs/layouts/NavBarLayout.md' }, + { src: 'src/layouts/WheelLayout.js', dest: 'docs/layouts/WheelLayout.md' }, + { src: 'src/layouts/ProportionalLayout.js', dest: 'docs/layouts/ProportionalLayout.md' } ] } } diff --git a/README.md b/README.md index 3443747..6b0b8c2 100644 --- a/README.md +++ b/README.md @@ -32,10 +32,12 @@ of renderables using a `GridLayout`, and change that into a `ListLayout`. When u ### [Layouts](#standard-layouts) - [GridLayout](docs/layouts/GridLayout.md) -- [ListLayout](docs/layouts/ListLayout.md) -- [CollectionLayout](docs/layouts/CollectionLayout.md) +- [ProportionalLayout](docs/layouts/ProportionalLayout.md) - [HeaderFooterLayout](docs/layouts/HeaderFooterLayout.md) - [NavBarLayout](docs/layouts/NavBarLayout.md) +- [ListLayout](docs/layouts/ListLayout.md) *(scrollable)* +- [CollectionLayout](docs/layouts/CollectionLayout.md) *(scrollable)* +- [WheelLayout](docs/layouts/WheelLayout.md) *(scrollable)* ### Resources - [API reference](#api-reference) @@ -249,10 +251,13 @@ custom layouts. Key features: |Layout|DataSource|Scrollable|Description| |---|---|---|---| |[GridLayout](docs/layouts/GridLayout.md)|ViewSequence / Array|No|Grid-layout with fixed number of rows & columns.| -|[ListLayout](docs/layouts/ListLayout.md)|ViewSequence / Array|Yes|List layout with margins, spacing and optionally sticky headers.| -|[CollectionLayout](docs/layouts/CollectionLayout.md)|ViewSequence / Array|Yes|Lays out renderables with a specific width & height.| +|[ProportionalLayout](docs/layouts/ProportionalLayout.md)|ViewSequence / Array|No|Lays out renderables sequentially and sizes them proportionally.| |[HeaderFooterLayout](docs/layouts/HeaderFooterLayout.md)|Id-based|No|Layout containing a top-header, bottom- footer and content.| |[NavBarLayout](docs/layouts/NavBarLayout.md)|Id-based|No|Layout containing one or more left and right items and a title.| +|*Scrollable layouts:*| +|[ListLayout](docs/layouts/ListLayout.md)|ViewSequence / Array|Yes|List layout with margins, spacing and optionally sticky headers.| +|[CollectionLayout](docs/layouts/CollectionLayout.md)|ViewSequence / Array|Yes|Lays out renderables with a specific width & height.| +|[WheelLayout](docs/layouts/WheelLayout.md)|ViewSequence / Array|Yes|Lays out renderables in a wheel (slot-machine) formation.| ## API reference @@ -264,6 +269,7 @@ custom layouts. Key features: |[FlexScrollView](docs/FlexScrollView.md)|Flexible scroll-view with pull-to-refresh, margins & spacing and more good stuff.| |[LayoutContext](docs/LayoutContext.md)|Context used for writing layout-functions.| |[LayoutUtility](docs/LayoutUtility.md)|Utility class containing helper functions.| +|[VirtualViewSequence](docs/VirtualViewSequence.md)|Infinite view-sequence which uses a factory delegate to create renderables.| ## Roadmap diff --git a/docs/LayoutController.md b/docs/LayoutController.md index 58a88b1..6a571b3 100644 --- a/docs/LayoutController.md +++ b/docs/LayoutController.md @@ -26,7 +26,7 @@ Events: * [layoutController.getLayoutOptions()](#module_LayoutController#getLayoutOptions) * [layoutController.setDirection(direction)](#module_LayoutController#setDirection) * [layoutController.getDirection([actual])](#module_LayoutController#getDirection) - * [layoutController.getSpec(node)](#module_LayoutController#getSpec) + * [layoutController.getSpec(node, normalize)](#module_LayoutController#getSpec) * [layoutController.reflowLayout()](#module_LayoutController#reflowLayout) * [layoutController.insert(indexOrId, renderable, [insertSpec])](#module_LayoutController#insert) * [layoutController.push(renderable, [insertSpec])](#module_LayoutController#push) @@ -45,6 +45,7 @@ Events: - \[dataSource\] `Array` | `ViewSequence` | `Object` - Array, ViewSequence or Object with key/value pairs. - \[direction\] `Utility.Direction` - Direction to layout into (e.g. Utility.Direction.Y) (when ommited the default direction of the layout is used) - \[flow\] `Bool` - Enables flow animations when the layout changes (default: `false`). + - \[reflowOnResize\] `Bool` - Smoothly reflows renderables on resize (only used when flow = true) (default: `true`). - \[insertSpec\] `Spec` - Size, transform, opacity... to use when inserting new renderables into the scene (default: `{}`). - \[removeSpec\] `Spec` - Size, transform, opacity... to use when removing renderables from the scene (default: `{}`). - \[alwaysLayout\] `Bool` - When set to true, always calls the layout function on every render-cycle (default: `false`). @@ -143,13 +144,14 @@ never returns undefined. **Returns**: `Utility.Direction` - Direction or undefined -###layoutController.getSpec(node) +###layoutController.getSpec(node, normalize) Get the spec (size, transform, etc..) for the given renderable or Id. **Params** - node `Renderable` | `String` - Renderabe or Id to look for +- normalize `Bool` - When set to `true` normalizes the origin/align into the transform translation (default: `false`). **Returns**: `Spec` - spec or undefined diff --git a/docs/ScrollController.md b/docs/ScrollController.md index 3e2d558..feda83f 100644 --- a/docs/ScrollController.md +++ b/docs/ScrollController.md @@ -16,8 +16,8 @@ Events: |event |description| |-----------|-----------| |scrollstart|Emitted when scrolling starts.| -|scroll |Emitted as the content scrolls (once for each frame the visible offset has changed)| -|pagechange |Emitted whenever visible page changes and options.paging is set to true.| +|scroll |Emitted as the content scrolls (once for each frame the visible offset has changed).| +|pagechange |Emitted whenever the visible page changes.| |scrollend |Emitted after scrolling stops (when the scroll particle settles).| Inherited from: [LayoutController](./LayoutController.md) @@ -49,6 +49,7 @@ Inherited from: [LayoutController](./LayoutController.md) * [scrollController.applyScrollForce(delta)](#module_ScrollController#applyScrollForce) * [scrollController.updateScrollForce(prevDelta, newDelta)](#module_ScrollController#updateScrollForce) * [scrollController.releaseScrollForce(delta, [velocity])](#module_ScrollController#releaseScrollForce) + * [scrollController.getSpec(node, normalize)](#module_ScrollController#getSpec) ###new ScrollController(options) @@ -56,7 +57,7 @@ Inherited from: [LayoutController](./LayoutController.md) - options `Object` - Configurable options (see LayoutController for all inherited options). - \[useContainer\] `Bool` - Embeds the view in a ContainerSurface to hide any overflow and capture input events (default: `false`). - - \[useContainerOverflow\] `String` - Overflow mode that is used when the `useContainer` option is true (default: `hidden`). + - \[container\] `String` - Options that are passed to the ContainerSurface in case `useContainer` is true. - \[paginated\] `Bool` - Enabled pagination when set to `true` (default: `false`). - \[alignment\] `Number` - Alignment of the renderables (0 = top/left, 1 = bottom/right) (default: `0`). - \[mouseMove\] `Bool` - Enables scrolling by holding the mouse-button down and moving the mouse (default: `false`). @@ -267,3 +268,14 @@ the scroll offset and corresponds to the `touchend` event. - \[velocity\] `Number` - Velocity to apply after which the view keeps scrolling **Returns**: `ScrollController` - this + +###scrollController.getSpec(node, normalize) +Get the spec (size, transform, etc..) for the given renderable or +Id. + +**Params** + +- node `Renderable` | `String` - Renderabe or Id to look for. +- normalize `Bool` - When set to `true` normalizes the origin/align into the transform translation (default: `false`). + +**Returns**: `Spec` - spec or undefined diff --git a/docs/VirtualViewSequence.md b/docs/VirtualViewSequence.md new file mode 100644 index 0000000..2d1606e --- /dev/null +++ b/docs/VirtualViewSequence.md @@ -0,0 +1,105 @@ + +#VirtualViewSequence +Virtual ViewSequence for famo.us which creates & destroys nodes using a +factory delegate. The factory class should support the following functions: +- create() +- createNext(prevRenderable) +- createPrevious(nextRenderable) +- destroy(renderable) (optional) + +Example: + +```javascript +var VirtualViewSequence = require('famous-flex/VirtualViewSequence'); + +// Factory for creating surfaces +function MyFactory() {} +MyFactory.prototype.create = function(index) { + var surface = new Surface({ + size: [undefined, 100], + classes: ['my-surface'] + }); + surface.index = index || 0; // add property to renderable + return surface; +}; +MyFactory.prototype.createNext = function(renderable) { + return this.create(renderable.index + 1); +}; +MyFactory.prototype.createPrevious = function(renderable) { + return this.create(renderable.index - 1); +}; + +// Create infinite scrollview +var viewSequence = new VirtualViewSequence({ + factory: new MyFactory() +}); +var scrollView = new FlexScrollView({ + dataSource: viewSequence +}); +``` + + +##class: VirtualViewSequence ⏏ +**Members** + +* [class: VirtualViewSequence ⏏](#exp_module_VirtualViewSequence) + * [new VirtualViewSequence(options)](#exp_new_module_VirtualViewSequence) + * [virtualViewSequence.getPrevious()](#module_VirtualViewSequence#getPrevious) + * [virtualViewSequence.getNext()](#module_VirtualViewSequence#getNext) + * [virtualViewSequence.get()](#module_VirtualViewSequence#get) + * [virtualViewSequence.getIndex()](#module_VirtualViewSequence#getIndex) + * [virtualViewSequence.toString()](#module_VirtualViewSequence#toString) + * [virtualViewSequence.cleanup()](#module_VirtualViewSequence#cleanup) + + +###new VirtualViewSequence(options) +**Params** + +- options `Object` - Configurable options. + - factory `Object` - Factory delegate for creating new renderables. + - \[value\] `Renderable` - Renderable for this node (when omitted, `factory.create()` is called) + - \[index\] `Number` - Index of this node (default: 0). + + +###virtualViewSequence.getPrevious() +Get previous node. + +When no previous node exists, the factory-delegate function `createPrevious` +is called to construct a renderable for the previous node. When `createPrevious` +returns `undefined`, no previous-node will be created. + +**Returns**: `VirtualViewSequence` - previous node. + +###virtualViewSequence.getNext() +Get next node. + +When no next node exists, the factory-delegate function `createNext` +is called to construct a renderable for the next node. When `createNext` +returns `undefined`, no next-node will be created. + +**Returns**: `VirtualViewSequence` - next node. + +###virtualViewSequence.get() +Get the value of this node. + +**Returns**: `Renderable` - surface/view + +###virtualViewSequence.getIndex() +Get the index of the node. + +**Returns**: `Number` - Index of node. + +###virtualViewSequence.toString() +Get human readable string verion of the node. + +**Returns**: `String` - node as a human readable string + +###virtualViewSequence.cleanup() +Cleans up any un-accessed nodes since the previous call to `cleanup`. + +This function cleans up any nodes that have not been accessed +since the last call to `cleanup`. When a node is accessed +through a call to `getNext`, `getPrevious`, `get` or `getIndex` +it is considered `touched` and should not be cleaned up. + +**Returns**: `VirtualViewSequence` - this. diff --git a/docs/layouts/ProportionalLayout.md b/docs/layouts/ProportionalLayout.md new file mode 100644 index 0000000..bd732ca --- /dev/null +++ b/docs/layouts/ProportionalLayout.md @@ -0,0 +1,27 @@ + +#ProportionalLayout +Lays-out renderables sequentially based on size-ratios (similar to the stock famo.us FlexibleLayout view). + +|options|type|description| +|---|---|---| +|`ratios`|Array|Size-ratios of the renderables.| + +Example: + +```javascript +var ProportionalLayout = require('famous-flex/layouts/ProportionalLayout'); + +var layoutController = new LayoutController({ + layout: ProportionalLayout, + layoutOptions: { + ratios: [1, 1, 2, 1], // total size: 5 + }, + dataSource: [ + new Surface({content: 'item 1'}), // 20% + new Surface({content: 'item 2'}), // 20% + new Surface({content: 'item 3'}), // 40% + new Surface({content: 'item 4'}) // 20% + ] +}); +``` + diff --git a/docs/layouts/WheelLayout.md b/docs/layouts/WheelLayout.md new file mode 100644 index 0000000..1c562e4 --- /dev/null +++ b/docs/layouts/WheelLayout.md @@ -0,0 +1,41 @@ + +#WheelLayout +Lays out renderables in a spinner wheel (slot-machine wheel) formation. + +|options|type|description| +|---|---|---| +|`itemSize`|Size|Size (width or height) of an item to layout.| +|`[diameter]`|Number|Diameter of the wheel in pixels (default: `3 x itemSize`).| +|`[radialOpacity]`|Number|Opacity (0..1) at the diameter edges of the wheel (default: 1).| + +Example: + +```javascript +var ContainerSurface = require('famous/surfaces/ContainerSurface'); +var ScrollController = require('famous-flex/ScrollController'); +var WheelLayout = require('famous-flex/layouts/WheelLayout'); + +// Create scroll-wheel +var scrollWheel = new ScrollController({ + layout: WheelLayout, + layoutOptions: { + itemSize: 100, // item has height of 100 pixels + radialOpacity: 0.5 // make items at the edges more transparent + }, + dataSource: [ + new Surface({content: 'item 1'}), + new Surface({content: 'item 2'}), + new Surface({content: 'item 3'}) + ] +}); + +// Create a container-surface for clipping and give it a nice perspective +var container = new ContainerSurface({ + properties: { + overflow: 'hidden' + } +}); +container.context.setPerspective(1500); +container.add(scrollWheel); +``` + diff --git a/src/VirtualViewSequence.js b/src/VirtualViewSequence.js index 4e56c99..0202ac1 100644 --- a/src/VirtualViewSequence.js +++ b/src/VirtualViewSequence.js @@ -13,20 +13,42 @@ /** * Virtual ViewSequence for famo.us which creates & destroys nodes using a - * factory for renderables. The factory class should support the following - * functions: + * factory delegate. The factory class should support the following functions: * - create() * - createNext(prevRenderable) * - createPrevious(nextRenderable) * - destroy(renderable) (optional) * - * VirtualViewSequence implements the following methods: - * - getPrevious - * - getNext - * - get - * - getIndex - * - toString (returns the index) + * Example: * + * ```javascript + * var VirtualViewSequence = require('famous-flex/VirtualViewSequence'); + * + * // Factory for creating surfaces + * function MyFactory() {} + * MyFactory.prototype.create = function(index) { + * var surface = new Surface({ + * size: [undefined, 100], + * classes: ['my-surface'] + * }); + * surface.index = index || 0; // add property to renderable + * return surface; + * }; + * MyFactory.prototype.createNext = function(renderable) { + * return this.create(renderable.index + 1); + * }; + * MyFactory.prototype.createPrevious = function(renderable) { + * return this.create(renderable.index - 1); + * }; + * + * // Create infinite scrollview + * var viewSequence = new VirtualViewSequence({ + * factory: new MyFactory() + * }); + * var scrollView = new FlexScrollView({ + * dataSource: viewSequence + * }); + * ``` * @module */ define(function(require, exports, module) { @@ -36,6 +58,10 @@ define(function(require, exports, module) { /** * @class + * @param {Object} options Configurable options. + * @param {Object} options.factory Factory delegate for creating new renderables. + * @param {Renderable} [options.value] Renderable for this node (when omitted, `factory.create()` is called) + * @param {Number} [options.index] Index of this node (default: 0). * @alias module:VirtualViewSequence */ function VirtualViewSequence(options) { @@ -55,50 +81,13 @@ define(function(require, exports, module) { this.eventOutput = new EventHandler(); }; - /** - * Cleans up any untouched nodes. - * - * @return {VirtualViewSequence} previous node. - */ - VirtualViewSequence.prototype.cleanup = function() { - var node = this.prev; - while (node) { - if (!node.touched) { - node.next.prev = undefined; - node.next = undefined; - if (this._.factory.destroy) { - while (node) { - this._.factory.destroy(node.value); - node = node.prev; - } - } - break; - } - node.touched = false; - node = node.prev; - } - node = this.next; - while (node) { - if (!node.touched) { - node.prev.next = undefined; - node.prev = undefined; - if (this._.factory.destroy) { - while (node) { - this._.factory.destroy(node.value); - node = node.next; - } - } - break; - } - node.touched = false; - node = node.next; - } - return this; - }; - /** * Get previous node. * + * When no previous node exists, the factory-delegate function `createPrevious` + * is called to construct a renderable for the previous node. When `createPrevious` + * returns `undefined`, no previous-node will be created. + * * @return {VirtualViewSequence} previous node. */ VirtualViewSequence.prototype.getPrevious = function() { @@ -123,7 +112,11 @@ define(function(require, exports, module) { /** * Get next node. * - * @return {VirtualViewSequence} node. + * When no next node exists, the factory-delegate function `createNext` + * is called to construct a renderable for the next node. When `createNext` + * returns `undefined`, no next-node will be created. + * + * @return {VirtualViewSequence} next node. */ VirtualViewSequence.prototype.getNext = function() { if (this.next) { @@ -173,8 +166,55 @@ define(function(require, exports, module) { return '' + this.index; }; + /** + * Cleans up any un-accessed nodes since the previous call to `cleanup`. + * + * This function cleans up any nodes that have not been accessed + * since the last call to `cleanup`. When a node is accessed + * through a call to `getNext`, `getPrevious`, `get` or `getIndex` + * it is considered `touched` and should not be cleaned up. + * + * @return {VirtualViewSequence} this. + */ + VirtualViewSequence.prototype.cleanup = function() { + var node = this.prev; + while (node) { + if (!node.touched) { + node.next.prev = undefined; + node.next = undefined; + if (this._.factory.destroy) { + while (node) { + this._.factory.destroy(node.value); + node = node.prev; + } + } + break; + } + node.touched = false; + node = node.prev; + } + node = this.next; + while (node) { + if (!node.touched) { + node.prev.next = undefined; + node.prev = undefined; + if (this._.factory.destroy) { + while (node) { + this._.factory.destroy(node.value); + node = node.next; + } + } + break; + } + node.touched = false; + node = node.next; + } + return this; + }; + /** * Not supported + * @private */ VirtualViewSequence.prototype.unshift = function() { if (console.error) { @@ -184,6 +224,7 @@ define(function(require, exports, module) { /** * Not supported + * @private */ VirtualViewSequence.prototype.push = function() { if (console.error) { @@ -193,6 +234,7 @@ define(function(require, exports, module) { /** * Not supported + * @private */ VirtualViewSequence.prototype.splice = function() { if (console.error) { @@ -202,6 +244,7 @@ define(function(require, exports, module) { /** * Not supported + * @private */ VirtualViewSequence.prototype.swap = function() { if (console.error) { diff --git a/src/layouts/ProportionalLayout.js b/src/layouts/ProportionalLayout.js index 3a0942c..deb4d80 100644 --- a/src/layouts/ProportionalLayout.js +++ b/src/layouts/ProportionalLayout.js @@ -12,7 +12,7 @@ /*eslint no-console: 0*/ /** - * Lays-out renderables sequentially based on size-ratios (similar to the stock famo.us FlexibleLayout). + * Lays-out renderables sequentially based on size-ratios (similar to the stock famo.us FlexibleLayout view). * * |options|type|description| * |---|---|---| diff --git a/src/layouts/WheelLayout.js b/src/layouts/WheelLayout.js index 93d2c93..47973fa 100644 --- a/src/layouts/WheelLayout.js +++ b/src/layouts/WheelLayout.js @@ -43,9 +43,9 @@ * * // Create a container-surface for clipping and give it a nice perspective * var container = new ContainerSurface({ - * properties: { - * overflow: 'hidden' - * } + * properties: { + * overflow: 'hidden' + * } * }); * container.context.setPerspective(1500); * container.add(scrollWheel);