le monde de crabs

Premiers pas avec impress.js

12/10/2014

Attention Fonctionne avec la version 0.5.3 de impress.js Attention

Ma première présentation avec impress.js : My First Step With Impress.Js.

Pourquoi impress.js

Il est temps de redonner une nouvelle jeunesse à Crabs's world... Donc j'investigue sur les nouvelles technologies web telles que HTML 5, CCS 3 et JavaScript.

Avec le WEB 2.0 et la prédominance d'AJAX, une des nouveautés c'est l'adaptabilité au divers moyen accès : PC, tablette ou téléphone... L'impression qu'une vie propre anime les sites sans que nous intervenions en est une autre. Ces nouvelles lignes de design sont maintenant accessibles via des technologies libres et ouvertes. Il est enfin temps que je m'y intéresse.

J'ai donc cherché à faire des animations simples qui ne nuisent pas au contenu (animation non intrusive comme le javascript) et j'ai croissé la route de impress.js.

Première impression sur impress.js

Après avoir lu et digéré « JavaScript : The Good Parts » de Douglas Crockford, mon regard sur le JavaScript a changé. Je trouve ainsi dommage que impress.js soit du code actif lors de son inclusion qui doit être faite en fin de document.

Après mes premiers tests, quelques fonctionnalités m'ont vite manqué :

  • pas de mode diaporama (slideshow) ;
  • pas de gestionnaire simple d'évenements pour l'entrée ou la sortie d'un slide ;
  • une seule présentation par page HTML.

Pour les deux premiers points, j'ai écrit un peu de JavaScript pour continuer mes investigations. Pour le troisième point, je vais devoir faire des progrès en JavaScript afin de comprende et de modifier impress.js.

API CrabsImpressJs.slideshow()

Attention Un step de impress.js est appelé diapositive Attention

Cette fonction fourni un objet dont les méthodes permettent la navigation dans la présentation ainsi de manière automatique ou scriptable.

Dans un premier temps il faut créer l'objet après avoir initialisé la presentation impress.js, comme le préconise son auteur.

Prototype :CrabsImpressJs.slideshow(duree, id)

Avec les valeurs par défauts : duree: 2000ms, id="impress"

var slide = CrabsImpressJs.slideshow();

Activation sur la présentation "impress", 5s entre chaque diapositive

var slide = CrabsImpressJs.slideshow(5000);

Activation sur la présentation "animation", 3s entre chaque diapositive

var slide = CrabsImpressJs.slideshow(3000, "animation");

L'objet retourné dispose de 7 méthodes appelables en cascade :

  • start() : lance le diaporama, en passant au suivant après le délais par défaut ou celui de la diapositive ;
  • resume() : lance le diaporama en passant immédiatement à la diapositive suivante ;
  • pause() : arrête le diaporama ;
  • first() : va à la première diapositive ;
  • last() : va à la dernière diapositive ;
  • prev() : revient sur la diapositive précédente ;
  • next() : passe à la diapositive suivante.

Exemples d'utilisation en javascript:

slide.start() ;         // lance le diaporama
slide.pause() ;         // arrête le diaporama
slide.pause().first() ; // arrête le diaporama et revient à la première diapositive

Changer le temps de persistance d'une diapositive en HTML

<div class="step" id="..." data-slideshow=15000>
  ...
</div>
    

API CrabsImpressJs.stepEvents()

Ici nous allons fournir des fonctions pour traiter les événements que fournit impress.js pour l'entree ou la sortie d'une diapositive. Ces événement interviennent à la fin de la transition pour l'entrée et avant le début de la transition pour sortir.

Prototype :CrabsImpressJs.stepEvents( step_id, enter, leave, presentation_id )

enter et leave sont les fonctions qui vont effectuer les traitements suite à la génération des événements. Leur prototype est le suivant :

Prototype :function (e, steps)

e est l'événement généré par impress.js. steps est un tableau qui contient les id des autres diapositives dans un tableau. Ce tableau est construit lors de l'appel, si vous ajoutez ou supprimer des diapositives dynamiquement à vous de le reconstruire ou d'adapter l'API.

Le source de impress_extend.js

Ma première présentation avec impress.js, My First Step With Impress.Js, utilise le fichier impress_extend.js présenté par la suite. Cette présentation utilise aussi jQuery qui n'est pas requis pour le fonctionnement de impress_extend.js.

// 
// =============================================================================
//  impress_extend.js : some extensions for impress.js
//
//  version 1.0.1 du 15/10/2014
//  (C) 2014 : Christophe Cazajus (crabs-mettre_le_signe_at-crabs-world.com)
//  
//  Ce source fait partie d'un projet logiciel libre. Vous pouvez le distribuer
//  et/ou le modifier en respectant les termes de la GNU General Public License
//  version 2 ou (suite a votre propre choix) une version ulterieure.
// 
//  Ce programme est distribue dans l'espoir qu'il puisse etre utile, mais
//  sans aucune garantie, meme si il est associe a un produit qui vous en
//  propose une. Conformez-vous a la GNU General Public License pour avoir
//  plus de precisions.
//  
//  L'auteur ne peut etre tenu responsable de l'utilisation faite de ce
//  fichier (en partie ou dans sa totalite).
// 
// =============================================================================
// You found a bug or a mistake ? Tell me through my contact form (I keep
// your email secret) :
// http://www.crabs-world.com/contact.php?f=2WEB/a8_impress_js.php
// =============================================================================
// 1.0.2: 02/11/2014: pass jslint...
//                  : optimize the use of querySelectorAll()
//                  : delete delay for start(), data-slideshow on element do
//                    the same
// 1.0.1: 15/10/2014: improve timer management
// 1.0  : 12/10/2014: initial release
// 
/*global impress, console*/
/*jslint browser: true, continue:true, plusplus: true, indent: 2 */

// Like a namespace
var CrabsImpressJs = {};

//=====
// Crabs.slideshow(duration, rootId)
//   Add slidewshow capacities to an "impress.js". The duration between one
//   'step' to the following will be duration or the value "slideshow" in
//   'dataset' of the current step. example : wait 10s on this 'step'
//     <div class=step" id="..." data-slideshow="10000" ...>
//
//===== parameters
//   duration : default duration in milliseconds (2000 by default)
//   rootId   : id of the impress div (impress by default)
//
//===== return
// object with slideshow controls : start(), resume(), pause(), first(),
// prev(), next() and last().
// start() control can be delayed with optionnal delay argument in ms
//
//===== usage
//== After document loaded
//   <script type="text/javascript" src=".../impress.js"></script>
//
//== Initialization (in any javascript function)
//     impress().init() ;
//     var sl = CrabsImpressJs.slideshow(5000);
//
//   or with an id different than impress
//     impress().init("hello") ;
//     var sl = CrabsImpressJs.slideshow(5000, "hello");
//
//== Start the slideshow
//   sl.start(); // go the next after waiting delay of the current step
//   sl.resume(); // start and  go to the next step with no delay
//== Stop the slideshow
//   sl.pause();
//== Manual navigation
//   sl.first(); // go to the first slide immediatly
//   sl.last();  // go to the last slide immediatly
//   sl.next();  // go to the next slide immediatly
//   sl.prev();  // go to the previous slide immediatly
//== cascade (with all methods)
//   sl.pause().first(); // stop the slideshow before manual navigation to
//                       // first slide.
//
CrabsImpressJs.slideshow = function (d, ri) {
  "use strict";
  var duration = d || 2000,
    rootId = ri || "impress",
    root = document.getElementById(rootId),

    // private attributes - closure design
    timer = null,
    started = false,
    imp_api = impress(rootId),
    cur_duration,

    // privates method
    slide;

  if (duration < 200) { duration = 200; }
  // invocation of anonymous function for retrieve first and last step
  slide = (function () {
    var i,
      f = false,
      l = false,
      qr = root && root.querySelectorAll('.step');
    if (qr) {
      for (i = 0; i < qr.length; i++) {
        if (!f) { f = qr[i]; }
        l = qr[i];
      }
    }
    return { first: f, last: l };
  }()); // slide = (function () { ...

  // add anonymous function for automatic next() if requiered
  document.addEventListener('impress:stepenter', function (e) {
    if (!started) { return; }
    if (e.target.parentNode.parentNode.id === rootId) {
      cur_duration = parseInt(e.target.dataset.slideshow || duration, 10);
      if (cur_duration < 200) { cur_duration = 200; }
      if (timer) { clearTimeout(timer); }
      timer = setTimeout(function () { imp_api.next(); }, cur_duration);
    }
  }, false);

  // return an object with the slideshow method
  return {
    start: function () {
      started = true;
      timer = setTimeout(function () { imp_api.next(); }, cur_duration);
      return this;
    },
    resume: function () {
      if (timer) { clearTimeout(timer); timer = null; }
      started = true;
      imp_api.next();
      return this;
    },
    pause: function () {
      started = false;
      if (timer) { clearTimeout(timer); timer = null; }
      return this;
    },
    first: function () { imp_api.goto(slide.first); return this; },
    last: function () {  imp_api.goto(slide.last); return this; },
    prev: function () {  imp_api.prev(); return this; },
    next: function () {  imp_api.next(); return this; }
  };
};

//-----
// CrabsImpressJs.stepEvents() : add events listenners on a specific step.
// The prototype of the listenners :
//  function (e, steps) { }
//  e : the event provided par impress.js
//  steps : id of the other steps (Array)
// Warning: the array of steps is computed on the call, not when the event
// is fired. You should adapt if you add or remove step dynamically.
//----- parameters
// stepId: the id of the step concerned by the event-handlers
// enter : event-handler on impress:stepenter
// leave : event-handler on impress:stepleave
// rootId: the id of the "impress" div
//----- return
// none
//-----
CrabsImpressJs.stepEvents = function (stepId, enter, leave, ri) {
  "use strict";
  var rootId = ri || "impress",
    step = [],
    i,
    s = 0,
    root = document.getElementById(rootId),
    qr = root && root.querySelectorAll('.step');

  if (qr) {
    for (i = 0; i < qr.length; i++) {
      if (qr[i].id !== stepId) { step[s++] = qr[i]; }
    }
  }

  // Add Event Listener only if necessary
  if (enter) {
    document.addEventListener('impress:stepenter', function (e) {
      if (e.target.id === stepId) { return enter(e, step); }
    }, false);
  }

  if (leave) {
    document.addEventListener('impress:stepleave', function (e) {
      if (e.target.id === stepId) { return leave(e, step); }
    }, false);
  }
};

Télécharger impress_extend.js Télécharger impress_extend.js