Urban Dictionary definition - G-Bone: Found deep within the woman; if broken it will lead to instant death. This bone joins the base of the spine to the G-spot and can be dislodged as a result of deep penetration or rough sex.
Note: This definition was NOT the inspiration for Gbone.js
Gbone.js is a framework written on top of Backbone for building mobile JavaScript applications.
This project is heavily inspired by Spine.Mobile, especially the idea of Stages and Panels. I really liked the framework but since it was built on top of Spine, I wanted to write one for Backbone. Some design patterns such as the observer
and cleanup
mixins were also influenced by ThoughtBot's excellent ebook Backbone.js on Rails.
You can view the annotated source at http://gobhi.github.com/gbone.js/docs/gbone.html.
Gbone.js is dependant on Backbone, Underscore and either Zepto or jQuery. Zepto is recommended over jQuery because it's lightweight and ideal for mobile webkit development. The default transition effects used by the transitions
mixin are dependant on Zepto-GFX if Zepto is used, or GFX if jQuery is used.
It's important to note that jQuery doesn't provide touch events. So in order to implement touch events, you would need to use a third-party plugin. For Zepto, touch events are provided out-of-box (another reason why Zepto is recommended over jQuery for Gbone).
Include gbone.js
after including all the dependancies. If using Zepto:
<script src="zepto.js" type="text/javascript" charset="utf-8"></script>
<script src="zepto-gfx.js" type="text/javascript" charset="utf-8"></script>
<script src="underscore.js" type="text/javascript" charset="utf-8"></script>
<script src="backbone.js" type="text/javascript" charset="utf-8"></script>
<script src="gbone.js" type="text/javascript" charset="utf-8"></script>
...or if jQuery is used:
<script src="jquery.js" type="text/javascript" charset="utf-8"></script>
<script src="gfx.js" type="text/javascript" charset="utf-8"></script>
<script src="underscore.js" type="text/javascript" charset="utf-8"></script>
<script src="backbone.js" type="text/javascript" charset="utf-8"></script>
<script src="gbone.js" type="text/javascript" charset="utf-8"></script>
Stage and Panel are subclasses of Backbone.View
. They both use a template to render their skeleton html and have transition support. Stages contain one or more Panels that are managed by an internal Panel manager.
Stages cover the entire viewport and they contain an element with class viewport
. The Panels are appended to this element. Thus when setting a skeleton template for a Stage, remember to set an element within the skeleton to have class viewport
.
An application displays only one Stage and Panel at a time. The Stage's Panels are transitioned in and out to reveal the different parts of the application.
Typically the main Stage's DOM element el
would be the document body
and it's html (that's rendered using it's skeleton template) is appended to it.
All Stages come with a default skeleton template to render from. This can be easily overridden when extending Gbone.Stage (provide it as an instance property - skeleton
).
Default Stage skeleton:
<header></header>
<article class="viewport"></article>
<footer></footer>
A Stage with the document body
as it's el
and the default skeleton template rendered into it:
<body class="stage">
<header></header>
<article class="viewport"></article>
<footer></footer>
</body>
Note: Since Gbone.Stage
extends Backbone.View
, these are additional methods and properties provided on top of the ones provided by Backbone.View
. However, some properties and methods of Backbone.View
may be mentioned here as well if needed.
extend - Gbone.Stage.extend(properties, classProperties) - Create a custom Gbone.Stage
class of your own by extending Gbone.Stage
with instance properties
as well as optional classProperties
.
var GlobalStage = Gbone.Stage.extend({
initialize: function() {...},
skeleton: _.template('...'),
render: function() {...}
});
constructor / initialize - new Gbone.Stage(options) - When creating a new Gbone.Stage
, the options you pass in are attached to the Stage as this.options
. There are some Stage specific options that will be attached directly to the Stage instance: name
and router
.
new GlobalStage({
name: 'global-stage',
router: router,
el: 'body'
});
name - stage.name - Name of the Stage. If one is not provided as an options
property during initialization, it will be created automatically in the format stage-:num
, where num
is a unique number. Used primarily for setting up the routes for the Panels.
skeleton - stage.skeleton - The html skeleton template to be used by the Stage. It's important that the class viewport
be set in an element in the skeleton; this element will be used by the Stage to append its Panel views.
router - stage.router - This Router contains all the routes for the Panels managed by the Stage. When instantiating a Stage, pass in the Backbone.Router
as an options
property. Note that if you don't pass one in, one will be created for the Stage during initialization.
A Panel's route will be of the following format:
/stage_name/panel_name/trans-:trans
where stage_name
is the Stage's name, panel_name
is the Panel's name and :trans
is the name of the transition effect. If the last part; the trans-:trans
is left out, the transition used will be the default, which is just showing/hiding the Panel.
An example of calling a Panel with name panel-1
that is under the Stage with name stage-1
and uses the left
transition effect (sliding in from left) would be:
/stage-1/panel-1/trans-left
Note that any deactivating Panels will automatically use the reverse of this transition, i.e. sliding out to right.
add - stage.add(panel1, panel2, ...) - Add any number of Panels to this Stage. Automatically calls stage.append(panels...)
to append the Panels to the Stage's viewport
element.
stage.add(panel1);
stage.add(panel2, panel3, panel4);
getPanel - stage.getPanel(name) - Retrieve a Panel with a name of name
in this Stage (if any).
bindTo - stage.bindTo(source, event, callback) - On top of binding event
to source
, keeps track of all the event handlers that are bound. A single call to unbindFromAll()
will unbind them.
unbindFromAll - stage.unbindFromAll() - Unbind all events.
cleanup - stage.cleanup() - Cleanup the Stage. Unbind all events (DOM, Model/Collection and View) and remove the Stage from the DOM and it's parent if needed.
appendChild - stage.appendChild(view) - Append a child View to this Stage.
appendChildInto - stage.appendChildInto(view, container) - Append a child View to a container element within this Stage.
stage.appendChildInto(view, 'viewport');
removeChild - stage.removeChild(view) - Remove the given child View from the Stage.
removeFromParent - stage.removeFromParent() - Remove the Stage from its parent.
As mentioned before, Panels are contained within Stages. A single Stage can have multiple Panels that are managed by that Stage's internal Panel manager. Each Panel of the Stage can be transitioned in and out but only one can be shown at a time.
A Panel is appended into it's Stage's element with class viewport
. Like a Stage, it also has a default html skeleton template that can be overridden when extending Gbone.Panel
.
Default Panel skeleton:
<div class="container">
<header></header>
<article></article>
</div>
A Panel with it's skeleton rendered inside it's el
:
<div class="panel">
<div class="container">
<header></header>
<article></article>
</div>
</div>
The above will get appended into the Stage's .viewport
element.
Note: Since Gbone.Panel
extends Backbone.View
, these are additional methods and properties provided on top of the ones provided by Backbone.View
. However, some properties and methods of Backbone.View
may be mentioned here as well if needed.
extend - Gbone.Panel.extend(properties, classProperties) - Create a custom Gbone.Panel class of your own by extending Gbone.Panel
with instance properties as well as optional classProperties.
var GlobalPanel = Gbone.Panel.extend({
initialize: function() {...},
skeleton: _.template('...'),
render: function() {...}
});
constructor / initialize - new Gbone.Panel(options) - When creating a new Gbone.Panel, the options you pass in are attached to the Panel as this.options
. There are several Panel specific options that will be attached directly to the Panel instance: name
and stage
.
new GlobalPanel({
name: 'panel1',
stage: stage
});
name - panel.name - Name of the Panel. If one is not provided as an options
property during initialization, it will be created automatically in the format panel-:num
, where num
is a unique number. Used primarily for setting up the route for the Panel.
stage - panel.stage - The Panel's Stage. Providing this as part of the options
in the constructor automatically adds this Panel to the Stage.
skeleton - panel.skeleton - The html skeleton template to be used by the Panel. The default can be overridden when extending the Panel.
routePanel - panel.routePanel(callback) - Setup the routing for the Panel. The callback gets called after the routing happens. The route for a Panel is as follows: /stage_name/panel_name/trans-:trans
where trans-:trans
is optional and is used to set the transition effect. Within the callback you should activate the Panel by calling the active
method on it and/or render
etc...
effects / reverseEffects - panel.effects / panel.reverseEffects - The effects
object contains the activating transition effects and reverseEffects
contains the deactivating effects. See the Transitions section below for more details.
transitionBindings - panel.transitionBindings - The default element(s) in the Panel to animate for the transitions. An array of elements/selectors of the form ['.header', '.container', '.footer', ...]
. Each element/selector in the transitionBindings
array represents a child DOM element within the Panel that is to be animated. If transitionBindings
is not overridden, the default child element that will be animated in the Panel View is .container
.
addTransition - pane.addTransition(transition) - Add a new transition. The transition
argument is an object as follows: transition.effects
- Object that contains the activation transitions to be added. transition.reverseEffects
- Object that contains the deactivation transitions.
{
effects: {
up: function (callback) {
...
}
},
reverseEffects: {
up: function (callback) {
}
}
}
active - panel.active([*args]) - Trigger the active
event to activate this Panel. Arguments will be passed along to the active
event callbacks. The activated
event will be triggered once activation is complete and the deactivated
event will be triggered once deactivation is complete. To pass in the transition effect to use (left
transition for example): panel.active({trans:'left'})
.
isActive - panel.isActive() - Returns true if the Panel is the active one.
bindTo - panel.bindTo(source, event, callback) - On top of binding event
to source
, keeps track of all the event handlers that are bound. A single call to unbindFromAll()
will unbind them.
unbindFromAll - panel.unbindFromAll() - Unbind all events.
cleanup - panel.cleanup() - Cleanup the Panel. Unbind all events (DOM, Model/Collection and View) and remove the Panel from the DOM and it's parent if needed.
appendChild - panel.appendChild(view) - Append a child View to this Panel.
appendChildInto - panel.appendChildInto(view, container) - Append a child View to a container element within this Panel.
panel.appendChildInto(view, 'viewport');
removeChild - panel.removeChild(view) - Remove the given child View from the Panel.
removeFromParent - panel.removeFromParent() - Remove the Panel from its parent.
Transitions are used when a Panel is activated/deactivated (since only one Stage and Panel are visible at any one time). These transitions between Panels are handled using CSS transforms. The advantage of using CSS transforms is that the transitions are hardware accelerated, thus improving performance on mobile devices. Some default transitions are provided, you can add more using the addTransition
method of the Panel. If jQuery is used, the default transitions are done using GFX, or if Zepto is used, it's done by Zepto-GFX.
As mentioned above, you can add your own transitions by using the addTransition
method of a Panel. When defining a transition it must have a definition under effects
and reverseEffects
. The reverseEffects
object contains the deactivating transition effects for the effects in the effects
object. i.e. the left
effect in the effects
object is for sliding in from the left and the left
effect in the reverseEffects
object is for sliding out to the right.
The transitions must also take in an optional callback function as an argument that must be called when the transition is complete. You should view the Transitions module in the gbone.js
source and use it as a guide if writing your own. You can also look at the transitions in the demo app provided in up_down.js
under example/app/helpers/transitions/
When a transition effect is used, it animates the elements in the Panel provided by the transitionBindings
array. This is an array of elements/selectors of the form ['.header', '.container', '.footer', ...]
. Each element/selector in the transitionBindings
array represents a child DOM element within the Panel that is to be animated. If transitionBindings
is not overridden, the default child element that will be animated in the Panel View is .container
.
The index.css
file located at example/app/public/css in the provided demo application is a great example of how to layout the css for Stages and Panels. This layout works well with GFX and Zepto-GFX.
The css in the demo application is just one way of doing it. It is mainly up to you to style your application so that it works with Gbone.
The demo application (found under the example directory) is a re-write of the currency.io web application using Gbone.
Most of the application specific styling for the demo application was taken from the Spine.Mobile version of currency.io: https://github.com/maccman/spine.mobile.currency.
Gbone.js is licensed under the terms of the MIT License, see the included LICENSE file.