Développer votre webapp mobile avec Wink

| Jérôme GIRAUD | winktoolkit |

Wink est un framework JavaScript permettant de développer des applications Web sur mobile. C'est un outil particulièrement adapté aux navigateurs WebKit que l'on retrouve aujourd'hui sur l'iPhone, sur Android ou encore les terminaux BlackBerry.
Commentez ♪

- Titre : Développer votre webapp mobile avec Wink

- Auteurs : Jérôme GIRAUD, winktoolkit

- Parution : 25 octobre 2010

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2010 Jérôme GIRAUD. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Description

- II. Présentation des packages

- III. Téléchargement et utilisation

- IV. Ma première WebApp

- IV-A. Première étape : positionnement des metas

- IV-B. Deuxième étape : création des header et footer

- IV-C. Troisième étape : ajout du menu

- IV-D. Quatrième étape : les sliding panels

- IV-E. Cinquième étape : le scroller (header et footer fixes)

- V. Pour aller un peu plus loin

- VI. Remerciements

I - Description

Wink est un framework JavaScript mobile Open Source et un projet de la fondation Dojo. Il cible avant tout les navigateurs WebKit (que l'on retrouve sur la majorité des smartphones et tablettes du moment) et annonce sa compatibilité avec iOS (iPod touch, iPhone, iPad), Android ou encore BlackBerry. Il a été pensé et construit pour s'adapter aux contraintes et aux spécificités des environnements Web mobile : c'est un framework qui reste ultraléger (6 ko une fois minimisé et gzippé) et qui fournit, par exemple, toute une couche de gestion des événements « touch » et « gesture ». Bien entendu, on y retrouve les fonctions HTML5 comme la géolocalisation ou le stockage local. Toutes les animations (2D et 3D) sont quant à elles réalisées en CSS3.

Wink présente un grand nombre d'éléments graphiques innovants (nuages de tags 3D en HTML, mises en pages originales, composants multitouch…) et se démarque ainsi de ses concurrents directs comme Sencha ou jQuery mobile.

Enfin, Wink se veut être un framework simple d'utilisation, c'est ce que nous allons voir au travers des différents exemples présentés dans cet article.

Ci-dessous, un exemple de composant innovant que l'on retrouvera dans le toolkit:

Animation en format "youtube" non supportée.
Contenu uniquement consultable en ligne à cette adresse :
https://www.youtube.com/v/l_GJMXdl55A&hl=en_EN&fs=1&rel=0

II - Présentation des packages

Wink a été divisé en huit packages

Wink Core, qui constitue la base du framework, offre toutes les fonctions de base, dont un développeur à besoin. Des requêtes XHR à la manipulation du DOM, en passant par la publication d'événements ou la gestion des transformations CSS. C'est aussi dans ce package que l'on retrouve tout ce qui concerne la gestion des événements de toucher.

Wink « ui » rassemble tous les composants graphiques. Certains sont familiers, comme le « date picker » ou le « carousel » alors que d'autres sont plus inattendus comme le nuage de tags HTML en 3D ou le composant « flippage » permettant de naviguer à la manière d'un e-book. C'est dans ce package que l'on retrouve aussi les layouts les plus populaires : sliding panels, scrollers… De quoi donner à sa webapp un Look and Feel d'application native.

Quelques vidéos des composants en action

- Carousel

- Nuage de tags 3D

- Scroller

C'est dans Wink « ux » que l'on retrouve tous les composants d'interaction. Bien sûr, les éléments « touch » et « multitouch » mais aussi des briques comme le gestionnaire de Drag and Drop ou encore l'adaptation du moteur de reconnaissance de forme « $1 ». Des utilitaires permettant de facilement gérer les changements d'orientation du terminal, ou encore l'historique de navigation du browser sont également présents.

Quelques vidéos des composants en action

- Drag and Drop

- Reconnaissance de forme

Wink « net » inclut un certain nombre de « loaders ». Le « JsLoader » peut être utilisé pour charger des ressources JavaScript externes à la volée, ce qui devient vite utile dans un environnement mobile dans lequel on voudra éviter de charger toutes les ressources au démarrage. Ce composant est parfaitement adapté pour le JSONP. Le préchargement d'images et de CSS fait aussi partie de ce package. Comme on le verra plus amplement par la suite, l'instanciation des composants reste simple et suit toujours le même pattern.

Voilà un premier exemple d'instanciation du JsLoader utilisé pour effectuer une requête JSONP

jsLoader = new wink.net.JsLoader();
jsLoader.load('http://server2.example.com/getjson?jsonp=parseResponse');

Wink « fx » regroupe toutes les librairies CSS permettant de gérer les transformations 2D, 3D ainsi que les animations. Wink « api » fournit des couches d'abstraction aux API HTML5 comme la géolocalisation ou le stockage local et le tout nouveau Wink « mm » (multimédia) contient désormais des players audio et vidéo.

Un tout nouveau composant « Easy Caching » vient compléter le tout. Le but : répliquer le fonctionnement du cache grâce au stockage local et ainsi améliorer jusqu'à dix fois les temps de chargement des WebApps tout en s'affranchissant des problèmes de compatibilité entre les différents OS mobiles.

III - Téléchargement et utilisation

L'intégralité du framework est disponible sur winktoolkit.org. Deux choix s'offrent alors à vous. Soit télécharger la version « code source », soit la version optimisée. Le plus simple est de télécharger cette dernière car elle comprend le core déjà minimisé. Dans cet article, nous utiliserons la version 1.2 optimisée que vous pourrez retrouver ici.

IV - Ma première WebApp

Nous allons maintenant développer notre première WebApp en se basant en partie sur les composants Wink. Le but est d'obtenir une WebApp « classique » contenant un header et un footer fixes, une zone de contenu intermédiaire dans laquelle l'utilisateur pourra scroller. Enfin, un bouton dans le header permettra l'ouverture d'un menu en overlay dans la page.

Finalement, nous devrions obtenir un résultat équivalent aux deux captures ci-après :

Dans un premier temps, nous allons créer un répertoire test qui contiendra notre WebApp. Le fichier principal de notre application sera index.html (situé dans le répertoire test). Pour simplifier, le répertoire wink est recopié directement dans le répertoire test, afin que notre page HTML accède facilement aux ressources.

IV-A - Première étape : positionnement des metas

Nous allons définir deux directives meta dans cette page. La première spécifie que sur iOS, la WebApp va pouvoir s'afficher en mode « WebApp » (plus d'informations sur le mode « WebApp »). La seconde va permettre d'adapter la page HTML à la taille de l'écran.

index.html : metas

<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;" />

IV-B - Deuxième étape : création des header et footer

Pour accéder aux fonctionnalités du toolkit, il va tout d'abord falloir rajouter un lien vers le core de Wink (fichier wink.min.js) dans la section « head » de notre WebApp.

index.html : layout

<script type="text/javascript" src="../js/wink.min.js"></script>

Nous allons maintenant créer le layout de la page. À savoir : un header, une zone de contenu et un footer.

index.html : layout

<body>
<div id="header">My WebApp</div>
<div id="content">
Lorem ipsum dolor sit amet...
</div>
<div id="footer">
</div>
</body>

Enfin, appliquons les styles sur les différents éléments HTML de la page.

index.html : styles

#header, #footer {
position: relative;
z-index: 0;
width: 100%;

text-align: center;
font-size: 1.4em;
line-height: 2em;
font-family: Verdana, Helvetica, sans-serif;
}

#header {
background-color: #444755;
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(0, #d4d4d4),
color-stop(0.05, #c1cbff), color-stop(0.95, #444755), color-stop(1, #23273b));
color: #fff;
text-shadow: 0 -0.05em 0 rgba(0, 0, 0, 0.5);
}

#footer {
background-color: #444755;
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(0, #d4d4d4),
color-stop(0.05, #c1cbff), color-stop(0.95, #444755), color-stop(1, #23273b));
color: #fff;
}

#content {
position: relative;
width: 100%;
min-height: 300px;
-webkit-box-sizing: border-box;
padding: 1em;
font-size: 1.1em;
text-align: justify;
background-color: #fff;
color: #000;
}

IV-C - Troisième étape : ajout du menu

Nous allons maintenant devoir nous servir du composant Popup de Wink (situé dans le répertoire ui/xy/popup). Pour cela, il va donc falloir rajouter dans la section « head » de la WebApp un lien vers le fichier JavaScript du composant Popup et un lien vers la feuille de style qui lui est associée.

index.html : intégration du composant Popup

<link rel="stylesheet" href="../../../wink/ui/xy/popup/css/styles.css" type="text/css">
<script type="text/javascript" src="../../../wink/ui/xy/popup/js/popup.js"></script>

Une fois cette étape effectuée, il va falloir rajouter un bouton dans le header. C'est sur ce bouton qu'il faudra cliquer pour voir le menu apparaitre. Nous allons donc modifier la structure HTML. Vous remarquerez que nous avons rajouté dans la balise body un handler sur l'événement load qui va permettre, une fois que la page sera chargée, de déclencher l'appel à la fonction « webapp.init » qui sera détaillée ci-après.

index.html

<body onload="setTimeout(webapp.init, 1);">
<div id="header">
<div class="title"><span>My WebApp</span></div>
<div id="menuBtn" class="button"><span>menu</span></div>
</div>
<div id="content">
Lorem ipsum dolor sit amet...
</div>
<div id="footer"> </div>
</body>

Intégrons le style du bouton dans la balise style précédemment créée.

index.html : styles

.title {
display: inline-block;
}

.button {
color: #fff;
display: inline-block;
padding: 0em 0.5em;
height: 2em;
line-height: 2em;
font-size: 0.8em;
background-image: -webkit-gradient(linear, left top, left bottom, from(#7d828c),
color-stop(0.5, #303749), color-stop(0.5, #121a2e), to(#121a2e));
border: solid 0.1em rgba(240, 240, 240, 0.75);
-webkit-user-select: none;
-webkit-border-radius: 0.5em;
}

#header .button {
position: absolute;
top: 0.2em;
right: 0.2em;
}

Reste à instancier et à initialiser le composant Popup, et à gérer les clics sur notre bouton.

Instanciation du composant Popup et gestion des clics sur le bouton contenu dans le header

var webapp =
{
popup: null,

init: function()
{
window.scrollTo(0,0);
webapp.initPopup();
},

initPopup: function()
{
webapp.popup = new wink.ui.xy.Popup()
document.body.appendChild(webapp.popup.getDomNode());

$('menuBtn').onclick = function() {
var menu = "";
menu += "<div class='menu'>";
menu += "Cras vulputate turpis id lorem scelerisque et scelerisque ipsum commodo.";
menu += "Cras sit amet nibh lacus, sed blandit nunc. Pellentesque aliquet mollis diam, non ultricies metus";
menu += "laoreet elementum.";
menu += "</div>";

webapp.popup.popup({
content: menu,
top: ($('header').offsetHeight + 20) + "px"
});
};
}
};

IV-D - Quatrième étape : les sliding panels

Si vous voulez donner à votre site Web des airs d'application native, vous allez sans doute vouloir que la navigation entre les différentes pages de votre WebApp se fasse en « slidant ». Pour cela, Wink offre un composant adapté qui permet de choisir parmi trois types de slides différents (« normal », « cover » et « reveal ») tout en spécifiant la durée de l'effet.

Nous allons maintenant devoir utiliser le composant SlidingPanels de Wink (situé dans le répertoire ui/layout/slidingpanels). Encore une fois, il va falloir rajouter dans la section « head » de la WebApp un lien vers le fichier JavaScript du composant ainsi qu'un lien vers la feuille de style qui lui est associée.

index.html : intégration du composant SlidingPanels

<link rel="stylesheet" href="../../../wink/ui/layout/slidingpanels/css/styles.css" type="text/css">
<script type="text/javascript" src="../../../wink/ui/layout/slidingpanels/js/slidingpanels.js"></script>

Le corps du document HTML doit aussi être modifié en fonction pour intégrer la notion de page. On pensera à bien séparer les pages identifiées par une 'div' (page1, page2) de leur contenu via une autre div (content1, content2) ; ceci afin de pouvoir associer le style souhaité au contenu sans modifier le style des pages qui est propre au fonctionnement du composant. Il nous faut aussi des boutons pour pouvoir naviguer à travers les pages. Nous allons intégrer cette fonctionnalité dans le footer de la WebApp.

index.html

<body onload="setTimeout(webapp.init, 1);">
<div id="header">
<div class="title"><span>My WebApp</span></div>
<div id="menuBtn" class="button"><span>menu</span></div>
</div>
<div id="content">
<div id="page1">
<div id="content1" class="pageContent">
Lorem ipsum dolor sit amet ...
</div>
</div>
<div id="page2">
<div id="content2" class="pageContent">
Aliquam vehicula scelerisque ...
</div>
</div>
</div>
<div id="footer">
<div id="previousBtn" class="button hidden"><span>previous</span></div>
<div id="nextBtn" class="button"><span>next</span></div>
</div>
</body>

Intégrons ensuite les styles de nos pages

index.html : styles

.pageContent {
min-height: 300px;

padding: 1em;
font-size: 1.1em;
text-align: justify;

-webkit-box-sizing: border-box;
}

#content1 {
background-color: #fff;
color: #000;
}

#content2 {
background-color: #000;
color: #fff;
}

Reste à déclencher la création du composant SlidingPanels, en JavaScript, au démarrage de l'application. Reste aussi à gérer les boutons « suivant » et « précédent » qui permettront de naviguer dans la webapp. Pour cela nous allons rajouter plusieurs méthodes et modifier la fonction « init ».

Instanciation du composant SlidingPanels et gestion des clics sur les boutons suivant/précédent

var webapp =
{
popup: null,

init: function()
{
window.scrollTo(0,0);
webapp.initSize();
webapp.initPopup();
webapp.initPanels();

$('nextBtn').onclick = webapp.next;
$('previousBtn').onclick = webapp.previous;
},

initPopup: function()
{
webapp.popup = new wink.ui.xy.Popup()
document.body.appendChild(webapp.popup.getDomNode());

$('menuBtn').onclick = function() {
var menu = "";
menu += "<div class='menu'>";
menu += "Cras vulputate turpis id lorem scelerisque et scelerisque ipsum commodo.";
menu += "Cras sit amet nibh lacus, sed blandit nunc. Pellentesque aliquet mollis diam, non ultricies metus";
menu += "laoreet elementum.";
menu += "</div>";

webapp.popup.popup({
content: menu,
top: ($('header').offsetHeight + 20) + "px"
});
};
},

initPanels: function()
{
webapp.slidingPanels = new wink.ui.layout.SlidingPanels(
{
'duration': 500,
'pages': [ 'page1', 'page2' ]
});

$('content').appendChild(webapp.slidingPanels.getDomNode());
},

next: function()
{
wink.addClass($('nextBtn'), "hidden");
wink.removeClass($('previousBtn'), "hidden");

webapp.slidingPanels.slideTo('page2');
},

previous: function()
{
wink.removeClass($('nextBtn'), "hidden");
wink.addClass($('previousBtn'), "hidden");

webapp.slidingPanels.slideBack();
},

initSize: function()
{
$('content').style.height = page1.offsetHeight + "px";
}
};

IV-E - Cinquième étape : le scroller (header et footer fixes)

Pour terminer la WebApp et lui permettre d'avoir un comportement proche de celui d'une application native, nous allons utiliser le composant Scroller. Il va nous permettre de garder les header et footer fixes tout en pouvant naviguer dans nos deux pages.

index.html : intégration du composant Slider

<script type="text/javascript" src="../../../wink/ux/window/js/window.js"></script>
<script type="text/javascript" src="../../../wink/ux/movementtracker/js/movementtracker.js"></script>
<script type="text/javascript" src="../../../wink/ux/inertia/js/inertia.js"></script>
<script type="text/javascript" src="../../../wink/ui/layout/scroller/js/scroller.js"></script>

Pour utiliser ce composant, il va simplement falloir rajouter son instanciation à l'initialisation de la WebApp.

Instanciation du composant Scroller

var webapp =
{
popup: null,

init: function()
{
window.scrollTo(0,0);
webapp.initSize();
webapp.initScroller();
webapp.initPopup();
webapp.initPanels();

$('nextBtn').onclick = webapp.next;
$('previousBtn').onclick = webapp.previous;
},

initPopup: function()
{
webapp.popup = new wink.ui.xy.Popup()
document.body.appendChild(webapp.popup.getDomNode());

$('menuBtn').onclick = function() {
var menu = "";
menu += "<div class='menu'>";
menu += "Cras vulputate turpis id lorem scelerisque et scelerisque ipsum commodo.";
menu += "Cras sit amet nibh lacus, sed blandit nunc. Pellentesque aliquet mollis diam, non ultricies metus";
menu += "laoreet elementum.";
menu += "</div>";

webapp.popup.popup({
content: menu,
top: ($('header').offsetHeight + 20) + "px"
});
};
},

initPanels: function()
{
webapp.slidingPanels = new wink.ui.layout.SlidingPanels(
{
'duration': 500,
'pages': [ 'page1', 'page2' ]
});

$('content').appendChild(webapp.slidingPanels.getDomNode());
},

initScroller: function()
{
webapp.scroller1 = new wink.ui.layout.Scroller(
{
target: "content1",
direction: "y"
});

webapp.scroller2 = new wink.ui.layout.Scroller(
{
target: "content2",
direction: "y",
scrollbars: {
backgroundColor: 'rgba(255, 255, 255, 0.8)',
borderColor: 'rgba(255, 255, 255, 0.9)'
}
});
},

next: function()
{
wink.addClass($('nextBtn'), "hidden");
wink.removeClass($('previousBtn'), "hidden");

webapp.slidingPanels.slideTo('page2');
},

previous: function()
{
wink.removeClass($('nextBtn'), "hidden");
wink.addClass($('previousBtn'), "hidden");

webapp.slidingPanels.slideBack();
},

initSize: function()
{
$('content').style.height = page1.offsetHeight + "px";
}
};

V - Pour aller un peu plus loin

D'autres exemples de code sont à retrouver dans la section « tutorials » du site de Wink, ainsi que des conseils sur le développement Web mobile.

Un forum de discussion est aussi là pour aider les développeurs à résoudre les problèmes rencontrés avec l'outil.

Enfin, si vous êtes intéressés pour contribuer au projet Wink, n'hésitez pas à contacter ses créateurs.

VI - Remerciements

Merci à Rodrigue Hunel ainsi que eusebe19, Mahefasoa et jacques_jean pour leur relecture.