Adds a function to perform transition between slides asynchronously
bespoke.horizontal.from('#slides');
bespoke.asyncTransition(function(data, done) {
setTimeout(done, 3000);
});
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.
Download the production version or the development version.
Bespoke.js requires a modern browser with ES5 support. If supporting old IE is your thing, there's always es5-shim and classList.js.
Bespoke.js can be installed from Bower using the following command:
$ bower install bespoke.js
View the demo at the official Bespoke.js project page.
- DIY Presentations With Bespoke.js by Mark Dalgleish
- Rapid Web App Dev With Yeoman by Michael Taranto
Made a presentation with Bespoke.js? Let me know.
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.
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>
Decks are created by selecting the parent element with the from(selector)
method, with optional 'horizontal' or 'vertical' event handlers.
Uses space bar, horizontal arrows and swipes for navigation.
bespoke.horizontal.from('article');
Uses space bar, vertical arrows and swipes for navigation.
bespoke.vertical.from('article');
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');
To create your own custom deck styles, Bespoke.js provides the necessary classes to your elements.
bespoke-parent | The deck's containing element |
bespoke-slide | Every slide element |
bespoke-active | The active slide |
bespoke-inactive | All inactive slides |
bespoke-before | All slides before the active slide |
bespoke-before-n | All slides before the active slive, with n value incrementing |
bespoke-after | All slides after the active slide |
bespoke-after-n | All slides after the active slive, with n value incrementing |
If you've created an awesome theme you'd like me to share, let me know.
The following plugins are available for Bespoke.js.
- bespoke-bullets for animated bullet lists.
- bespoke-hash for hash routing.
- bespoke-loop for looped presentations.
- bespoke-vcr for recording and playback.
- bespoke-spotlight by @mobz, for quick-searching slide content.
If you'd like your plugin added to this list, let me know.
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);
Bespoke.js provides the following events which can be handled with the on(event, callback)
method.
activate | A slide has been activated |
deactivate | A slide has been deactivated |
next | The next slide has been requested, even if last slide is active. Return false to cancel event. |
prev | The previous slide has been requested, even if first slide is active. Return false to cancel event. |
slide | A specific slide has been requested. Return false to cancel event. |
Each event is passed an event object containing a reference to the current slide and its index.
bespoke.on('next', function(event) {
event.slide; // Activated slide
event.index; // Index of activated slide
// Prevent default functionality and stop propagation
return false;
});
If you need more information about the presentation, you may need to retain a reference to the individual deck instance.
Note: Returning false from a 'next', 'prev' or 'slide' event handler will prevent default functionality and stop the event from propagating to subsequent event handlers. This allows you to intercept the standard navigation events and manage state within individual slides, allowing plugins for bullet lists, in-slide animations, etc.
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);
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.
The following properties are available on each instance:
next() | Next slide |
prev() | Previous slide |
slide(index) | Activate a specific slide by index |
on(event, callback) | Attach event handlers |
off(event, callback) | Remove event handlers |
fire(event[, payload]) | Fire custom events. This method is primarily designed for plugin authors. |
parent | The deck's parent element |
slides | An array of slide elements |
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.
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.
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 || 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
}
});
Contact me on GitHub or Twitter: @markdalgleish
Copyright 2013, Mark Dalgleish
This content is released under the MIT license
http://markdalgleish.mit-license.org