BESPOKE – DIY Presentation Micro-Framework.
Bespoke is a wonderful plugin which will give the opportunity to present your content in a very appealing way. It is less than 1KB minified and gzipped, with no dependencies.
Bespoke.js provides the foundation, then gets out of your way so you can focus on uniquely crafting your own personal deck style.
Using keyboard and touch events, Bespoke.js adds classes to your slides, while you provide the CSS transitions. With its robust plugin system, new functionality can be added to Bespoke.js easily.
DEMO | DOWNLOAD
Getting Started
To create a Bespoke.js presentation, follow these 3 simple steps:
- Create a page with required slide markup and resources
- Activate your deck via the JavaScript API
- Create a custom style sheet using the Bespoke.js classes
Need more functionality? Use an existing plugin, or create a new one.
Basic Usage
Markup
The tags you use are completely optional. Once a parent element is selected, the child elements become slides.
<link rel="stylesheet" href="path/to/my/theme.css"> <article> <section>Slide 1</section> <section>Slide 2</section> <section>Slide 3</section> </article> <script src="bespoke.min.js"></script> <script src="path/to/my/script.js"></script>
JavaScript
Decks are created by selecting the parent element with the from(selector)
method, with optional ‘horizontal’ or ‘vertical’ event handlers.
Horizontal Deck
Uses space bar, horizontal arrows and swipes for navigation.
bespoke.horizontal.from('article');
Vertical Deck
Uses space bar, vertical arrows and swipes for navigation.
bespoke.vertical.from('article');
Minimal Deck
For the absolute purist only. Minimal decks provide a simple control API with zero default event handlers. Key presses and swipes have no effect, it’s up to you to implement your own interactions from scratch.
bespoke.from('article');
Plugins
The following plugins are available for Bespoke.js.
Official Plugins
All official plugins can be installed from Bower, e.g. $ bower install bespoke-bullets
- bespoke-bullets for animated bullet lists.
- bespoke-hash for hash routing.
- bespoke-state for slide-specific deck styles.
- bespoke-loop for looped presentations.
- bespoke-vcr for recording and playback.
Third-Party Plugins
- bespoke-spotlight by @mobz, for quick-searching slide content.
- bespoke-blackout by @originell, for temporarily blacking out the screen.
Advanced Usage
Control API
Programmatically control your presentation, or implement a custom interface when using a minimal deck.
// Next slide bespoke.next(); // Previous slide bespoke.prev(); // Go to a specific slide bespoke.slide(0);
Events
Binding Events
Each event is passed an event object containing a reference to the relevant slide and its index.
bespoke.on(eventName, function(event) { event.slide; // Relevant slide event.index; // Index of relevant slide // Prevent default functionality (for user interaction events only) return false; });
If you need more detail about the deck in your event handlers, you may need to retain a reference to the individual deck instance.
Standard Events
In most cases, you will only need to use these standard events.
activate | A slide has been activated. event.slide is the activated slide. |
deactivate | A slide has been deactivated. event.slide is the deactivated slide. |
User Interaction Events
These events are fired when the user has interacted with the presentation, but before their interaction has had any effect.
This allows you to intercept the default behaviour by returning false
from the event handler.
next | The next slide has been requested, even if last slide is active. event.slide is the current slide. |
prev | The previous slide has been requested, even if first slide is active. event.slide is the current slide. |
slide | A specific slide has been requested. event.slide is the requested slide. |
Unbinding events
Events handlers can be removed with the off(event, callback)
method.
Note: To remove an event handler, you must retain a reference to the original function.
var myEventHandler = function() { // Do something... }; // Bind event bespoke.on('activate', myEventHandler); // Unbind event bespoke.off('activate', myEventHandler);
Deck Instances
Creating Deck Instances
Individual deck instances can be created and controlled separately.
// First deck instance var one = bespoke.horizontal.from('#deck-one'); one.next(); one.prev(); one.slide(0); // Second deck instance var two = bespoke.horizontal.from('#deck-two'); two.next(); two.prev(); two.slide(0);
The global bespoke
API interacts with all deck instances. For example, calling bespoke.next()
is actually calling next()
on all decks.
Deck Instance Properties
The following properties are available on each instance.
Note: The optional eventData
parameter is an object that will be merged with the event
object in subsequent event handlers.
next([eventData]) | Next slide. |
prev([eventData]) | Previous slide. |
slide(index[, eventData]) | Activate a specific slide by index. |
on(event, callback) | Attach event handlers |
off(event, callback) | Remove event handlers |
fire(event[, eventData]) | Fire custom events. This method is primarily designed for plugin authors. |
parent | The deck’s parent element |
slides | An array of slide elements |
Creating Plugins
If you need to expand upon the core Bespoke.js feature set, additional functionality can be packaged up as plugins.
If you’d like to learn by example, check out the list of existing plugins.
Basic Plugins
Plugins are simply functions that are called when presentations are created.
They are passed a deck instance which allows you to interact with the deck’s state, bind events and modify its elements.
// Creating the plugin bespoke.plugins.myPlugin = function(deck) { deck.on('activate', function(e) { console.log('Activated slide ' + (e.index + 1) + ' of ' + deck.slides.length); }); };
The plugin can now be provided to the second parameter of the from(selector[, plugins])
method.
// Using the plugin bespoke.horizontal.from('article', { myPlugin: true });
Note: If the value provided is false
instead of true
, your plugin won’t run.
Plugins with Options
If your plugin needs some configurability, options can be passed through as the second parameter.
Note: The ‘options’ parameter is an empty object if no options are provided.
// Creating the plugin with options bespoke.plugins.myPlugin = function(deck, options) { options.showTotal = options.showTotal !== undefined ? options.showTotal || true; deck.on('activate', function(e) { console.log('Activated slide ' + (e.index + 1) + (options.showTotal ? ' of ' + deck.slides.length : '')); }); }; // Using the plugin with options bespoke.from('article', { myPlugin: { showTotal: true } });
Custom Event Data
Additional event data can be supplied to next
, prev
and slide
, which is merged with the final event
object in subsequent event handlers.
This functionality is particularly useful if you need to differentiate between events caused by your plugin, and those caused by your end users or other plugins.
bespoke.plugins.myPlugin = function(deck) { // Differentiating our plugin's events deck.on('activate', function(event) { if (event.foo === 'bar') { // Triggered by my plugin... } else { // Triggered by end user, or another plugin... } }); // Providing custom event data deck.next({ foo: 'bar' }); };