Vous n'êtes pas connecté. Connexion
|
|
Programmable Web 2015-2016De $1IntroductionDans ce cours vous allez voir différents aspects de la programmation Web :
Le sujet tournera autours du développement d'un logiciel d'écoute de chansons multipistes à l'aide de HTML5 et d'APIs gravitant autours comme WebAudio API. D'autres APIs HTML5 seront mises à contribution comme l'API du canvas pour le dessin et l'animation, la persistence avec XHR2 et IndexedDB ou Web Storage etc. Voici une image préliminaire d'un prototype (ne faites pas attention à l'interface graphique) fonctionnel:
Le but n'est pas que vous réalisiez exactement ce prototype, le but est que l'on vous aide à développer votre propre version, en ajoutant de nombreuses améliorations:
Nous allons découper le travail que vous allez faire en séances de TP et à chaque fois nous vous fourniront des éléments pour avancer. Les dernières séances seront consacrées à la finalisation de votre travail et à la présentation de vos résultats. Séance numéro 1Travail à faire:
Séance numéro 2Vous aurez certainement besoin, pour vos projets, d'utiliser des composants graphiques évolués: boutons qui tournent, sliders, interrupteurs, vu mètres, etc... Une approche nouvelle de la conception de GUIs pour le Web s'appelle les "Web Components", ce sera le sujet du cours d'aujourd'hui! Web Components qui pourront vous être utiles:
Si cela ne convient pas, voici quelques ressources pour des composants graphiques pour Web Audio:
Supports de cours:
Travail à faire:
Séance numéro 3: dessin, animation, dessiner la forme d'onde d'un son, XhR2, fetch, promesses...Moocs gratuits sur MongoDB/NodeJS/clients angular/ionicInfo importante: le MOOC "MongoDB for NodeJS developers" démarre aujourd'hui, gratuit, donné par les auteurs de MongoDB. https://university.mongodb.com/courses/M101JS/about Il y a aussi un Mooc sur EDx qui couvre Mongo/Node/Express/Angular/Ionic (app mobiles hybrides): https://www.edx.org/course/introduct...mongodbx-m101x qui a démarré le 6 janvier! Comment dessiner une forme d'onde, à la manière de ?
Ce n'est pas aussi simple que de dessiner la forme d'onde qui danse en musique. Si on balaye le canvas colonne par colonne et qu'on va chercher l'échantillon qui correspond, on fait du sous échantillonage (il y en a 44100 pour une seconde de musique) et cela ne sera pas représentatif. Inversement, si on ballaye tous les échantillons, on va dessiner des centaines de fois des valeurs souvent très proches dans la même colonne du canvas. La bonne solution consiste à balayer l'échantillon mais avec une certaine "définition", en gros, on va sauter dans l'échantillon et ne prendre qu'un échantillon tous les n échantillons. Le logiciel MT5 (http://mainline.i3s.unice.fr, lien github dans le menu help) utilise le code du fichier waveformDrawer.js pour cela. Voici le code qui l'utilise: // Object that draws a sample waveform in a canvas var waveformDrawer new WaveformDrawer(); function drawTrack(decodedBuffer) waveformDrawer.init(decodedBuffer, canvas, 'green'); // First parameter = Y position (top left corner) // second = height of the sample drawing waveformDrawer.drawWave(0, canvas.height); } Mais vous pouvez aussi utiliser des librairies comme WaveSurfer.js ou autres... Avec cela vous n'aurez plus besoin d'images pour dessiner les formes d'ondes mais vous pourrez les dessiner à la volée. Ecrire un chargeur de sons multiples en AjaxVous avez certainement lu le MOOC HTML5 part 2 sur Web Audio, ou regardé le chargeur multiple fourni avec le lecteur multi-pistes. Pour les plus curieux d'entre vous, il y a moyen d'écrire du code bien plus concis avec les nouveautés de EcmaScript 6, notamment la methode fetch() et les "promesses". Pour voir les nouveautés du nouveau JavaScript, allez faire un tour sur http://www.es6fiddle.net/ Vous pouvez comparer un chargeur multiple de sons utilisant Xhr2 avec le même utilisant fetch et les promesses. Lire aussi: un tutorial sur fetch() et un autre sur les promesses Remarquez qu'il existe des polyfills pour que tout cela tourne dans tous les navigateurs (même assez anciens), il faut utiliser babel et un polyfill pour fetch. En général on utilise un outil de build pour "transcompiler" le code ES6 en ES5 avant de l'exécuter. Cela peut se faire également à la volée dans le browser avec babel-standalone (c'est ce qui est utilisé dans l'exemple tournant dans jsbin, que je vous ai montré 5 lignes au-dessus). Dans ce cas, une fois le code chargé dans le browser, il est trans-compilé dans le browser avant d'être exécuté. Notez que FireFox supporte 100% les promesses et fetch(), et que le support natif arrive à grand pas. Si le code est exécuté dans un navigateur qui supporte nativement ces features, le polyfill ne doit normalement rien faire. Ceux parmis vous qui sont habitués à développer en JS avec des outils comme gulp vont trouver des gulp files qui viennent déja avec le support pour babel et fetch. Les autres, si vous ne comprenez pas cette dernière phrase, ce n'est pas grave, vous n'utilisez pas gulp ! Uploader des fichiers avec NodeJSTestez cet exemple qui fait de l'upload de fichiers en Ajax. Il utilise les modules nodeJS express et le module multer, qui permet le support de formulaires multipart. Je vous fournis cet exemple car la plupart de ceux que j'ai trouvé sur le net sont obsolètes ou bien ne supportent pas l'envoi de multiples fichiers, ou bien ne sont pas avec des clients Ajax modernes... Noter que si on veut envoyer en plus des champs de formulaires, ou pouvoir envoyer des fichiers par drag'n'drop, très très peu de modifications sont nécessaires (cf le MOOC HTML5 partie 2, sur Xhr2 upload de fichiers avec FormData et sur drag'n'drop). index.html (code client): <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>HTML5 file upload with monitoring</title> </head> <body> <h1>Example of Xhr2 file upload, with progress bar</h1> Choose a file and wait a little until it is uploaded. <p> <input id="file" type="file" multiple/> <br/><br /> Progress: <progress value = 0 id="progress"></progress> <script> var fileInput = document.querySelector('#file'), progress = document.querySelector('#progress'); fileInput.onchange = function() { var xhr = new XMLHttpRequest(); xhr.open('POST', 'api/file'); xhr.upload.onprogress = function(e) { progress.value = e.loaded; progress.max = e.total; }; xhr.onload = function() { console.log('Upload complete!'); showUploadedImages(); }; var form = new FormData(); // ici on aurait pu ajouter un formulaire // comme param de FormData, cela // aurait envoyé les champs en plus for(var i=0; i < fileInput.files.length; i++) form.append('file', fileInput.files[i]); xhr.send(form); }; // for displaying uploaded images function showUploadedImages() { var xhr = new XMLHttpRequest(); xhr.open('GET', 'uploads'); xhr.onload = function(e) { var images = JSON.parse(this.response); for(var i=0; i < images.length; i++) { var img = document.createElement("img"); img.src = "uploads/" + images[i]; img.width=100; document.body.appendChild(img); } }; xhr.send(); } </script> </body> </html> server.js (code serveur): var express = require("express"); var fs = require("fs"); var multer = require("multer"); var app = express(); var storage = multer.diskStorage({ destination: "./public/uploads", filename: function (req, file, cb) { cb(null, file.originalname + '-' + Date.now()); } }); var upload = multer({ storage: storage }); app.use(express.static('./public')); app.post('/api/file', upload.array('file'), function (req, res) { console.log("received " + req.files.length + " files");// form files for(var i=0; i < req.files.length; i++) { console.log("### " + req.files[i].path); } //console.log("The URL for the file is:" + "localhost:3000\\"+req.file.path); res.status(204).end(); }); app.get('/', function (req, res) { res.sendFile("index.html"); }); app.get('/uploads', function (req, res) { fs.readdir("./public/uploads", function(err, list) { res.end(JSON.stringify(list)); }); }); app.listen(3000, function () { console.log("Server is listening on port 3000"); console.log("Open http://localhost:3000 and upload some files!") }); |
Powered by MindTouch Deki Open Source Edition v.8.08 |