DIY Presentation Micro-Framework

Related tags

Sliders bespoke
Overview

Build Status Coverage Status Gitter

Bespoke.js

DIY Presentation Micro-Framework

Bespoke.js is a super minimal (1KB min'd and gzipped), modular presentation library for modern browsers, designed to foster a rich plugin ecosystem.

The core library sets up the presentation, provides a simple control API and manages events. Any other functionality is implemented as a plugin.

Joining the Bespoke.js ecosystem is simple with the suite of official Yeoman generators:

Creating a Presentation

Due to the highly modular nature of Bespoke.js, the quickest way to get started is with Bespoke.js Generator, a Yeoman generator that scaffolds a boilerplate presentation with a Gulp build system.

Assuming you have Node.js installed, in a blank directory:

$ npm install -g generator-bespoke
$ yo bespoke

In your newly scaffolded project, you can use the following Gulp tasks:

  • $ gulp serve to run a preview server with LiveReload.
  • $ gulp deploy to deploy to GitHub Pages.
  • $ gulp to compile static assets to 'public'.

For more detailed instructions, check out the Bespoke.js Generator repo.

If you'd prefer to craft a new presentation from scratch, you can install Bespoke.js from npm with npm install bespoke, Bower with bower install bespoke.js, or manually download either the production version or the development version. The Bespoke.js core is extremely lightweight, so you'll probably want to include some plugins.

Basic Usage

Loading Bespoke

Bespoke.js is shipped in a UMD format, meaning that bespoke and its plugins are available as CommonJS/AMD modules or browser globals.

Markup

It's completely up to you which tags you use, but the following is a good starting point:

<article id="presentation">
  <section>Slide 1</section>
  <section>Slide 2</section>
  <section>Slide 3</section>
</article>

JavaScript

To create a new presentation, Bespoke.js provides the from(selector[, plugins]) method, which takes a selector or element reference and an array of plugins, and returns a deck instance.

var deck = bespoke.from('#presentation', [plugins]);

// Next slide
deck.next();

// Previous slide
deck.prev();

// Go to a specific slide
deck.slide(0);

// Get the active slide index
deck.slide(); // 0

By default, all non-script child elements of the resolved parent element become slides. You can customize this behavior by passing a custom selector.

Plugins

Official Plugins

All official plugins can be installed from npm or Bower, e.g. $ npm install bespoke-keys or $ bower install bespoke-touch

All Plugins

You can view the full list of Bespoke.js plugins on npm by browsing the bespoke-plugin keyword.

Using Plugins

All official plugins are provided in a UMD format, meaning they are available as CommonJS/AMD modules or browser globals.

For example, if you're using CommonJS modules via browserify or webpack, it would look something like this:

var bespoke = require('bespoke'),
  classes = require('bespoke-classes'),
  keys = require('bespoke-keys'),
  touch = require('bespoke-touch');

var deck = bespoke.from('#presentation', [
  classes(),
  keys(),
  touch()
]);

If you're using browser globals, all official plugins are added to the bespoke.plugins object, for example:

var deck = bespoke.from('#presentation', [
  bespoke.plugins.classes(),
  bespoke.plugins.keys(),
  bespoke.plugins.touch()
]);

The first slide is activated automatically after all plugins are called unless one of those plugins has already activated a slide.

Themes

Official Themes

As with plugins, all official themes can be installed from npm or Bower, e.g. $ npm install bespoke-theme-cube or $ bower install bespoke-theme-voltaire

All Themes

You can view the full list of Bespoke.js themes on npm by browsing the bespoke-theme keyword.

Using Themes

Themes are included just like any other plugin:

var bespoke = require('bespoke'),
  cube = require('bespoke-theme-cube'),
  keys = require('bespoke-keys'),
  touch = require('bespoke-touch');

var deck = bespoke.from('#presentation', [
  cube(),
  keys(),
  touch()
]);

If you're using browser globals, all official themes are added to the bespoke.themes object, for example:

var deck = bespoke.from('#presentation', [
  bespoke.themes.cube(),
  bespoke.plugins.keys(),
  bespoke.plugins.touch()
]);

Advanced Usage

From HTMLElement

If you already have a reference to a DOM node, you can pass it directly to the from method.

bespoke.from(element);

Slide Selector

You can specify which elements become slides by passing an options Hash containing the key parent and, optionally, the key slides) to the from method. The value of either key can be a CSS selector or a DOM node.

bespoke.from({ parent: selectorOrElement, slides: selectorOrElementList });

For example:

bespoke.from({ parent: '#presentation', slides: '#presentation > section' });

This advanced usage allows you to include auxiliary HTML inside the parent element, skip slides that don't match the selector or explicitly filter out slides before passing on the collection.

Deck Instances

Deck instances are provided to plugins and returned when instantiating a presentation. 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]]) Get or set the active slide index.
on(event, callback) Attach event handlers
off(event, callback) Unbind 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
destroy Fire the destroy event. This method can be used to remove the deck from the DOM.

Events

Binding Events

Events are bound via the deck instance. Each event is passed an event object containing a reference to the relevant slide and its index.

deck.on(eventName, function(event) {
  event.slide; // Relevant slide
  event.index; // Index of relevant slide

  // Prevent default functionality (for deck interaction events only)
  return false;
});
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.
destroy Presentation is about to be destroyed, it's time for clean-up.
Deck Interaction Events

These events are fired when the deck has been interacted with, but before the 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

When binding events, the on method returns a function that can be used to remove the event handler.

var off = deck.on('activate', function() {
  // ...
});

// Unbind event
off();

You can also use the off method. However, you must use the same function reference that was used when registering the event.

// Bind event
deck.on('activate', onActivate);

// Unbind event
deck.off('activate', onActivate);

Creating Plugins

Want a boilerplate plugin? Use the official Bespoke.js Plugin Generator.

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.

To be consistent with the suite of official Bespoke.js plugins, it is highly recommended that you implement your plugin as a function that takes configuration and returns a plugin function.

// Creating the plugin
var myPlugin = function() {
  return function() {
    deck.on('activate', function(e) {
      console.log('Activated slide ' + (e.index + 1) + ' of ' + deck.slides.length);
    });
  }
};

The plugin can now be provided in the plugins array when using the from(selector[, plugins]) method.

// Using the plugin
bespoke.from('#presentation', [
  myPlugin()
]);

Plugins with Options

If your plugin needs some configurability, your plugin factory function can take options and return a configured plugin function.

// Creating the plugin with options
var myPlugin = function(options) {
  return function(deck) {
    var showTotal = options && options.showTotal;

    deck.on('activate', function(e) {
      console.log('Activated slide ' + (e.index + 1) +
        (showTotal ? ' of ' + deck.slides.length : ''));
    });
  }
};

// Using the plugin with options
bespoke.from('#presentation', [
  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.

var myPlugin = function() {
  return 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'
    });

  };
}

Creating Themes

Themes are essentially just plugins that also happen to insert styles into the page.

You can quickly scaffold a boilerplate theme project with the official Bespoke.js Theme Generator.

Presentations

Made a presentation with Bespoke.js? Let me know.

Questions?

Contact me on GitHub or Twitter: @markdalgleish

License

MIT License

Comments
  • Add page up and down key support

    Add page up and down key support

    Hi!

    Bespoke.js is completly awesome. I make HTML presentations for a long time, but I always needed to overwrite a lot of CSS style. That was before :)

    So I made a presentation for a web conference in France. The page down and up key support was missing, and that's what use the remote controllers. I also added the Shift+Space key combination support, just because I like to use it. I made some refactoring to improve code readability of this section.

    I hope you will like it.

    See you, Thomas.

    opened by tzi 9
  • Event type

    Event type

    When wiring up events, the action triggering the event would be awesome to have in the event object:

    {
        slide: [some slide]
        , index: [number]
        , type: [keypress(left|right|spacebar)|slide|prev|next|whatever]
    }
    

    As it is, it's very hard to wire up things like history state when you can't discern between a popstate and a keypress. Maybe the option to pass in an additional param to the slide() method?

     deck.slide(index, myEventParams);
    

    I know you're trying to keep byte size down, but I feel like the utility introduced by this would make this library exponentially more powerful. If nothing else, the ability to add custom values to the event object would be a huge improvement.

    opened by ultimatedelman 9
  • Destroying the presentation from 3rd party code.

    Destroying the presentation from 3rd party code.

    First of all, thank you very much for this great library.

    I've been using it for my project, which involves showing multiple presentations on one page. It looks like an index of presentations, user can play them in sequential order and I'd like to make it in very seamless way, without page reload. So far, everything was good, but I noticed that some plugins like bespoke-hash bind some handlers to the window object events, and don't unbind them when bespoke instance gets destroyed (and later replaced with a new one). And there's no clear way for such plugins to unbind their handlers, since there's no destroy event in the core library.

    I propose to add the destroy() method, which will fire the 'destroy' event prior to the presentation element removal. This way all plugin developers would know that there's a standard event, which they could handle and implement the clean-up.

    If you find this reasonable and decide to accept this (or similar) code, I promise to create pull requests for all popular bespoke plugins with destroy handlers implementations.

    Thanks!

    opened by neochief 7
  • Minimal quickstart.

    Minimal quickstart.

    Hi,

    Such a cool premise of creating a diy presentations with a 1k core bespoke.js and a simple theme.css.

    I followed the installation wizard, but probably used it wrong as it produced a 99mb presentation directory containing a 70k build.js and an empty build.css.

    Can you point me to a starting presentation.html, bespoke.js and theme.css that I can use without all this extra plumbing?

    Thanks, Keenan

    opened by kbrock 6
  • step.bind() framework does not work on iOs5

    step.bind() framework does not work on iOs5

    Hello, I've read the this topic https://github.com/markdalgleish/bespoke.js/issues/2 where you say the issue is in the site not in the framework.

    I’m using your original bespoke.js file and trying to add buttons to make the desk’s cards slide but on iOs5 bespoke.next(); breaks the js at step.bind() (into bespoke.js).

    If you could fix it fast it would be great :) there are still many devices using iOs5… Thanks

    opened by synthview 6
  • Question: Why use bespoke instead of reveal, strut, impress, etc ?

    Question: Why use bespoke instead of reveal, strut, impress, etc ?

    Hi,

    I just discover bespoke through a presentation from @sokra (here). And I like it.

    But before go deep into I would ask you why you created bespoke instead of using other equivalents.

    Note: no evil question here I'm just curious


    ping @hsablonniere

    opened by zckrs 4
  • resolves #60 introduce off method to unbind an event

    resolves #60 introduce off method to unbind an event

    As it turns out, we can add this method without any additional lines of code (and only a slight increase in the gzipped version). The on method can reuse the off method when building the return value by leveraging bind.

    opened by mojavelinux 4
  • Links aren't clickable in Firefox

    Links aren't clickable in Firefox

    When a Bespoke.js presentation is viewed in Firefox, and presumably all Gecko-based UAs, links aren't clickable. I have no idea why. Chrome does not have this problem.

    I see nothing obvious in the console. Perhaps this is caused by a preventDefault() somewhere? I don't know.

    opened by strugee 4
  • plugin run when before hook events.

    plugin run when before hook events.

    Hello. I tried to create plugin that modify sections before bespoke start hook event. But currently cannot that.

    Out of necessity, I implement this function as outside plugin. But that so dirty. :sob: like this

    beforeBespke('article', function(from){
      bespoke.from(from, {
        keys: true,
        touch: true,
      });
    })
    var beforeBespke = function(from, callback){
      // emulate bespoke from
      var parent = selectorOrElement.nodeType === 1 ? selectorOrElement : document.querySelector(selectorOrElement)
      var slides = [].filter.call(parent.children, function(el) { return el.nodeName !== 'SCRIPT'; })
      var deck = {
        slides : slides
      }
    
      //  :
      // do something modification to slide.
      // (This is a point want to plugin)
      //  :
    
      callback(from)
    }
    

    Please tell me if you have more good idea

    opened by suisho 4
  • Should have a way to select children (by class)

    Should have a way to select children (by class)

    The reason I mention this, is because at the moment it's assumed that all the children of the node are slides, but that might not be the case. For example, ember inserts script tags around bound values, and this interferes with bespoke.

    Adding the class name as an option would be nice.

    opened by knownasilya 4
  • IE9 issue. Unable to get property 'add' of undefined or null reference

    IE9 issue. Unable to get property 'add' of undefined or null reference

    Hello, I've put your bespoke.js + the js you've used on your demo page on my page but I have this error with IE9-

    Unable to get property 'add' of undefined or null reference on the line: el.classList.add(moduleName + '-' + cls);

    any idea?

    opened by synthview 4
  • Add infrastructure for help text

    Add infrastructure for help text

    While it's not the responsibility of bespoke.js core to provide a help view, it would be nice if core could maintain and expose help metadata so that this information can be collected and displayed.

    One possible way is simply define a contract (in the README) that any plugin that contributes keybindings should fire and event with metadata for a help plugin.

    deck.fire('help', [{type: 'key', value: 'f', action: 'Toggles fullscreen'}]);
    

    Another way would be to expose methods that can be used to register and retrieve help metadata.

    The focus is to figure out what foundation is necessary to make it possible to write a help plugin. The main decision is to work out the structure of the metadata. Next, we need to figure out how to get that metadata to the help plugin.

    opened by mojavelinux 2
  • deck.slide(-1) should go to last slide

    deck.slide(-1) should go to last slide

    To make life for plugin authors simpler, it would be nice if deck.slide(-1) went to the last slide to avoid having to constantly type:

    deck.slide(deck.slides.length - 1);
    

    If this isn't acceptable, a reasonable compromise might be to add a deck.end() method to advance to the last slide.

    opened by mojavelinux 5
  • Must order bespoke-classes before bespoke-scale

    Must order bespoke-classes before bespoke-scale

    When using the bower versions of bespoke plugins, the order of plugins becomes important. If you specify bespoke-scale before bespoke-classes scaling won't work. e.g.

    bespoke.from('article', [
        bespoke.plugins.bullets('li, .bullet'),
        bespoke.plugins.backdrop(),
        bespoke.plugins.scale(),
        bespoke.plugins.hash(),
        bespoke.plugins.progress(),
        bespoke.plugins.classes(),
        bespoke.plugins.state(),
        bespoke.plugins.keys(),
        bespoke.plugins.touch()
    ]);
    

    won't work but this will:

    bespoke.from('article', [
        bespoke.plugins.classes(),
        bespoke.plugins.bullets('li, .bullet'),
        bespoke.plugins.backdrop(),
        bespoke.plugins.scale(),
        bespoke.plugins.hash(),
        bespoke.plugins.progress(),
        bespoke.plugins.state(),
        bespoke.plugins.keys(),
        bespoke.plugins.touch()
    ]);
    
    opened by phdesign 2
Owner
Bespoke.js
DIY Presentation Micro-Framework
Bespoke.js
It's a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prezi.com.

impress.js It's a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prez

impress.js 37.1k Jan 3, 2023
It's a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prezi.com.

impress.js It's a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prez

impress.js 37.1k Jan 3, 2023
Strut - An Impress.js and Bespoke.js Presentation Editor

All new development is happening in Strut2 Strut2 is currently private until we further solidify our "open source dividened program." Open Source Divd

Matthew Wonlaw 1.7k Dec 30, 2022
The responsive CSS animation framework for creating unique sliders, presentations, banners, and other step-based applications.

Sequence.js The responsive CSS animation framework for creating unique sliders, presentations, banners, and other step-based applications. Sequence.js

Ian Lunn 3.4k Dec 20, 2022
JavaScript image gallery for mobile and desktop, modular, framework independent

PhotoSwipe Repository JavaScript image gallery for mobile and desktop. Documentation and getting started guide. Demo and script home page. NPM npm ins

Dmitry Semenov 22.5k Dec 30, 2022
DIY Presentation Micro-Framework

Bespoke.js DIY Presentation Micro-Framework Bespoke.js is a super minimal (1KB min'd and gzipped), modular presentation library for modern browsers, d

Bespoke.js 4.7k Dec 18, 2022
A minimal presentation package for Svelte, including a "Presenter" and "Presentation View"

svelte - presenter A minimal presentation package for Svelte, includes synchronized "Presenter" and "Presentation" views. Adding Slides All slides are

Stephane 17 Sep 16, 2022
DIY Raspberry PI Display for Nicehash stats

nicehashpi DIY Raspberry PI Display for Nicehash stats Prerequisites : RaspberryPi 3b+ or higher RaspberryPi 3.5 inch SPI TFT LCD Display SD Card 16GB

null 20 Jun 6, 2022
Micro.publish is an Obsidian plugin to publish notes directly to Micro.blog, written in TypeScript

Micro.publish Micro.publish is a community maintained plugin for Obsidian to publish notes to a Micro.blog blog. Installing This plugin will be availa

Otavio Cordeiro 14 Dec 9, 2022
It's a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prezi.com.

impress.js It's a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prez

impress.js 37k Jan 2, 2023
The HTML Presentation Framework

reveal.js is an open source HTML presentation framework. It enables anyone with a web browser to create fully featured and beautiful presentations for

Hakim El Hattab 62.8k Jan 2, 2023
It's a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prezi.com.

impress.js It's a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prez

impress.js 37.1k Jan 3, 2023
It's a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prezi.com.

impress.js It's a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prez

impress.js 37.1k Jan 3, 2023
Single Page Application micro framework. Views, routes and controllers in 60 lines of code

SPApp Single Page Application Micro Framework Supports views, controllers and routing in 60 lines of code! Introduction If you heard anything about MV

Andrew 262 Nov 23, 2022
A new flexbox based CSS micro-framework.

Strawberry CSS What Strawberry is a new flexbox based CSS micro-framework. A set of common flexbox's utilities focused on making your life easier and

Andrea Simone Costa 74 Sep 26, 2022
Garfish is a powerful micro front-end framework 🚚

Garfish is a micro front-end framework, mainly used to solve the problems of cross-team collaboration, diversification of technology system, and increasing complexity of applications brought by modern web applications in the context of front-end ecological boom and increasing complexity of web applications, and Garfish has been polished and tested by a large number of online applications, with strong functional stability and reliability

Modern JS 1.8k Dec 30, 2022
Fast & Robust Front-End Micro-framework based on modern standards

Chat on gitter Hello slim.js - your declarative web components library import { Slim } from 'slim-js'; import { tag, template } from 'slim-js/decorato

slim.js 942 Dec 30, 2022
`raaghu-mfe` is an opensource micro front end framework built on top of `raaghu-elements`, Bootstrap 5 and Storybook offering highly customizable UI components and built-in pages

`raaghu-mfe` is an opensource micro front end framework built on top of `raaghu-elements`, Bootstrap 5 and Storybook offering highly customizable UI components and built-in pages. Raaghu mfe can be used as a base to build complex components and UI layouts whilst maintaining a high level of reusability,flexibility with ease of maintenance.

Wai Technologies 160 Dec 30, 2022
♠️ React MDX-based presentation decks

MDX Deck Award-winning React MDX-based presentation decks ?? Write presentations in markdown ⚛️ Import and use React components ?? Customizable themes

Brent Jackson 11k Jan 2, 2023
Strut - An Impress.js and Bespoke.js Presentation Editor

All new development is happening in Strut2 Strut2 is currently private until we further solidify our "open source dividened program." Open Source Divd

Matthew Wonlaw 1.7k Dec 30, 2022