# HG changeset patch # User bastiena # Date 1337008835 -7200 # Node ID 4003f84cd349bcd2fe622754772cfdcb168279aa # Parent 2c7fc855eba827081ff1521dbd2b7e575fa83648 Front IDILL : Player implemented and was mostly tested, still memory leaks. diff -r 2c7fc855eba8 -r 4003f84cd349 .hgignore --- a/.hgignore Fri May 11 11:04:06 2012 +0200 +++ b/.hgignore Mon May 14 17:20:35 2012 +0200 @@ -53,6 +53,25 @@ front_idill/extern/fajran-npTuioClient/TestClient/TestClient.vcxproj.filters front_idill/src/snapshots-little/ front_idill/src/snapshots/ +front_idill/src/player/markers/wheel.png +front_idill/src/player/markers/wave.png +front_idill/src/player/markers/updown.png +front_idill/src/player/markers/swipe-down.png +front_idill/src/player/markers/slow.png +front_idill/src/player/markers/run.png +front_idill/src/player/markers/right-angle.png +front_idill/src/player/markers/pendulum.png +front_idill/src/player/markers/knee-up.png +front_idill/src/player/markers/jump.png +front_idill/src/player/markers/join-hands.png +front_idill/src/player/markers/hello.png +front_idill/src/player/markers/cross.png +front_idill/src/player/markers/circle.png +front_idill/src/player/markers/bend.png +front_idill/src/player/markers/beat.png +front_idill/src/player/markers/arc.png +front_idill/src/player/TODO player 11-05-12.txt +front_idill/src/player/TODO player 02-05-12.txt syntax: regexp middleware/extern/.*/(bin|obj) middleware/src/bin/Debug/* diff -r 2c7fc855eba8 -r 4003f84cd349 front_idill/src/index.html --- a/front_idill/src/index.html Fri May 11 11:04:06 2012 +0200 +++ b/front_idill/src/index.html Mon May 14 17:20:35 2012 +0200 @@ -66,22 +66,22 @@ var lMos = new localMosaic(length, imagesToShow, zoomedMargin); mos.localMos = lMos; //Tableau d'images de test pour peupler la mosaïque. - var imgs = []; + /*var imgs = []; for(var i = 0 ; i < 42 ; i++) { imgs[i] = i + '.jpg'; - } + }*/ //Si on a changé les dimensions de la fenêtre, on raffraichit la mosaïque. $(window).resize(function () { - mos.loadMosaic(imgs); + mos.loadMosaic(); }); //Si la page a chargé, on raffraichit la mosaïque. $(document).ready(function () { - mos.loadMosaic(imgs); + mos.loadMosaic(); $('.snapshotDivs').mouseenter(function () { diff -r 2c7fc855eba8 -r 4003f84cd349 front_idill/src/mosaic/js/mosaic.js --- a/front_idill/src/mosaic/js/mosaic.js Fri May 11 11:04:06 2012 +0200 +++ b/front_idill/src/mosaic/js/mosaic.js Mon May 14 17:20:35 2012 +0200 @@ -32,6 +32,7 @@ //Nombre d'images dans la mosaïque. this.imagesToShow = imgToShow; //Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque. + this.videos = []; this.urls = []; this.imgs = []; this.ids = []; @@ -78,6 +79,10 @@ this.neighboursIds = []; //ID du snapshot du milieu lors d'un zoom. this.centerId; + + this.player; + + this.loadFromJson('./player/json/videos.json'); } else { @@ -106,20 +111,30 @@ } } + console.log(this.imagesToShow); + return str; } /* * Permet de raffraichir la mosaïque. */ -mosaic.prototype.loadMosaic = function(imgsTab) +mosaic.prototype.loadMosaic = function() { + var createMosaic = this.createMosaic(); + + if(createMosaic == '') + { + return; + } + + var _this = this; + //On affecte les chemins vers les images à la mosaïque. - this.imgs = imgsTab; this.previousZoomedSN; //this.width = //On met à jour la mosaïque. - $('#mainPanel').html(this.createMosaic()); + $('#mainPanel').html(createMosaic); //On récupère la taille des bordures. this.marginWidth = $('.snapshotDivs').css('margin-bottom'); this.marginWidth = parseFloat(mos.marginWidth)*2; @@ -134,6 +149,20 @@ //On centre verticalement la mosaïque. this.MPTop_margin = ($(document).height() - $('#mainPanel').height())/2; $('#mainPanel').css('margin-top', this.MPTop_margin).css('margin-bottom', this.MPTop_margin); + + $('.snapshotDivs').mouseenter(function () + { + //On effectue un prézoom dès qu'on va sur une image. + _this.preZoom($(this)); + }); + $('body').keypress(function (event) + { + //Si on a appuié sur la touche 'q' ou 'Q'; + if(event.which == 113 || event.which == 81) + { + _this.unzoom(); + } + }); } /* @@ -377,10 +406,15 @@ IriSP.libFiles.defaultDir = "../lib/"; IriSP.widgetsDir = "./player/metadataplayer/" + var videoToPlay = this.videos[this.centerId]; + var currentMetadata = this.urls[this.centerId]; + console.log('VIDEO[' + this.centerId + '] : ' + videoToPlay); + console.log('MD[' + this.centerId + '] : ' + currentMetadata); + console.log(newZoomTop + " " + newZoomLeft); var _metadata = { - url: 'http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/cljson/id/7c912bce-66b8-11e1-80f6-00145ea4a2be?callback=?', + url: currentMetadata, format: 'ldt' }; var _config = { @@ -400,7 +434,7 @@ }, player:{ type: 'html5', // player type - video: 'http://media.iri.centrepompidou.fr/video/ldtplatform/body_trail_cctv.mp4', + video: videoToPlay, live: true, height: newSnHeight, width: newSnWidth, @@ -419,8 +453,8 @@ }); //On démarre le player. - var _myPlayer = new IriSP.Metadataplayer(_config, _metadata); - console.log(_myPlayer); + this.player = null; + this.player = new IriSP.Metadataplayer(_config, _metadata); } /* @@ -556,7 +590,7 @@ 'left': 0, 'width': $(this).width() - marginValue*2, 'height': $(this).height() - marginValue*2, - 'background-image': 'url(' + $('img', $(this)).attr('src') + ')', + 'background-image': 'url("' + $('img', $(this)).attr('src') + '")', 'background-size': $(this).width() + 'px ' + $(this).height() + 'px', 'background-position': -marginValue + 'px ' + -marginValue + 'px', 'opacity': '0.4' @@ -734,4 +768,48 @@ } } return true; +} + +/* + * Charge les vidéos, les snapshots et les annotations depuis un fichier json. +*/ +mosaic.prototype.loadFromJson = function(path) +{ + var _this = this; + + $.getJSON(path, function(data) + { + $.each(data, function(key, val) + { + // console.log(val); + $.each(val, function(key_video, val_video) + { + $.getJSON(val_video.metadata, function(meta) + { + _this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/')); + //console.log(meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/')); + }); + + _this.imgs.push(val_video.snapshot); + _this.urls.push(val_video.metadata); + }); + }); + console.log('rdy'); + _this.loadMosaic(); + }); +} + +/* + * Affecte une vidéo au tableau des vidéos selon son id +*/ +mosaic.prototype.affectVideoById = function(metadata_id, video) +{ + for (i = 0 ; i < this.urls.length ; i++) + { + if(this.urls[i] == metadata_id) + { + this.videos[i] = video; + break; + } + } } \ No newline at end of file diff -r 2c7fc855eba8 -r 4003f84cd349 front_idill/src/mosaic/mosaic/css/mosaic.anc.less --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/front_idill/src/mosaic/mosaic/css/mosaic.anc.less Mon May 14 17:20:35 2012 +0200 @@ -0,0 +1,107 @@ +/* +* This file is part of the TraKERS\Front IDILL package. +* +* (c) IRI +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +/* + * Projet : TraKERS + * Module : Front IDILL + * Fichier : mosaic.less + * + * Auteur : alexandre.bastien@iri.centrepompidou.fr + * + * Fonctionnalités : Définit les propriétés d'apparence des éléments de base de la mosaïque (les snapshots, la mosaïque en elle-même). + * + * Avertissement : Afin que ce fichier puisse compiler, il est nécessaire de lancer index.html depuis un chemin ne commencant pas par file:///. + * C'est pourquoi j'utilise WAMP pour le lancer. + */ + +@mosaic-border-tickness: 1px; +@mosaic-background-color: #202020; +@mosaic-background-image-path: url("../../img/background.png"); +@selected-snapshot-background-image-path: url("../../img/selected_background.png"); +@snapshots-background-color: #8D8D8D; +@snapshots-margin-value: 5px; +@snapshots-margin: @snapshots-margin-value @snapshots-margin-value @snapshots-margin-value @snapshots-margin-value; +@black: #000000; + +body +{ + overflow: hidden; + background-color: @black; +} + +/* + * Il s'agit des propriétés de la mosaïque en elle même. + * On désactive les barres de défilement, on peut la placer à n'importe qu'elle position, elle doit être aussi large que la fenêtre du navigateur. + * Son fond se répète. + */ +#mainPanel +{ + overflow: hidden; + position: absolute; + width: 100%; + top: 0px; + left: 0px; + background-image: @mosaic-background-image-path; + background-repeat: repeat; +} + +/* + * Les divs contenant les snapshots (ou les "voisins" aussi en cas de zoom total). Ils se positionnent par défaut de gauche à droite, à l'horizontale et wrap dès + * qu'ils ont atteint la bordure de fenêtre de droite. + */ +.snapshotDivs, .neighbourDivs +{ + background-color: @black; + margin: @snapshots-margin; + float: left; +} + +/* + * Les snapshots sont des images, elles doivent remplir l'intégralité de leurs divs (snapshotDivs). + */ +.snapshots +{ + width: 100%; + height: 100%; +} + +/* + * Ce sont des divs créés spécialement lors d'un prézoom. Leur fonction est d'afficher un clone du snapshot, superposé au précédent et de grandir un peu de manière + * à faire ressortir visuellement le snapshot pointé. Leur bordure est d'une couleur différente au fond, ce qui permet de les discerner plus facilement dans la mosaïque. + * au départ, lors de sa création, il est caché, mais apparaît dès que l'image est chargée. + */ +.prezoomContainers +{ + position: absolute; + display: none; + background-image: @selected-snapshot-background-image-path; + background-repeat: repeat; +} + +/* + * Cette classe est attachée à des divs destinés à remplir les bordures d'une mosaïque locale. + */ +.blacks +{ + background-color: @black; + float: left; +} + +/* + * C'est une classe appliquée aux divs "voisins", afin de les colorer lorsque l'utilisateur intéragit avec eux. + * Ils se positionnent exactement sur le voisin qu'ils représentent, à la manière du clone de prézoom (prezoomContainer), bien que celui-là n'est qu'un div simple + * ne contenant pas d'image. + * Au départ, l'opacité est à 0, ce qui signifie que ce div est invisible. L'opacité change lors d'intéractions avec cet objet. Le div apparaît alors. + */ +.cyan +{ + position: absolute; + background-color: #94C6C5; + opacity: 0; +} \ No newline at end of file diff -r 2c7fc855eba8 -r 4003f84cd349 front_idill/src/mosaic/mosaic/css/mosaic.less --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/front_idill/src/mosaic/mosaic/css/mosaic.less Mon May 14 17:20:35 2012 +0200 @@ -0,0 +1,132 @@ +/* +* This file is part of the TraKERS\Front IDILL package. +* +* (c) IRI +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +/* + * Projet : TraKERS + * Module : Front IDILL + * Fichier : mosaic.less + * + * Auteur : alexandre.bastien@iri.centrepompidou.fr + * + * Fonctionnalités : Définit les propriétés d'apparence des éléments de base de la mosaïque (les snapshots, la mosaïque en elle-même). + * + * Avertissement : Afin que ce fichier puisse compiler, il est nécessaire de lancer index.html depuis un chemin ne commencant pas par file:///. + * C'est pourquoi j'utilise WAMP pour le lancer. + */ + +@mosaic-border-tickness: 1px; +@mosaic-background-color: #202020; +@mosaic-background-image-path: url("../../img/background.png"); +@selected-snapshot-background-image-path: url("../../img/selected_background.png"); +@snapshots-background-color: #8D8D8D; +@snapshots-margin-value: 8px; +@snapshots-margin: @snapshots-margin-value @snapshots-margin-value @snapshots-margin-value @snapshots-margin-value; +@black: #000000; + +body +{ + //overflow: hidden; + background-color: @black; +} + +/* + * Il s'agit des propriétés de la mosaïque en elle même. + * On désactive les barres de défilement, on peut la placer à n'importe qu'elle position, elle doit être aussi large que la fenêtre du navigateur. + * Son fond se répète. + */ +#mainPanel +{ + overflow: hidden; + position: absolute; + width: 100%; + top: 0px; + left: 0px; + background-image: @mosaic-background-image-path; + background-repeat: repeat; +} + +/* + * Les divs contenant les snapshots (ou les "voisins" aussi en cas de zoom total). Ils se positionnent par défaut de gauche à droite, à l'horizontale et wrap dès + * qu'ils ont atteint la bordure de fenêtre de droite. + */ +.snapshotDivs, .neighbourDivs +{ + background-color: @black; + margin: @snapshots-margin; + float: left; +} + +/* + * Les snapshots sont des images, elles doivent remplir l'intégralité de leurs divs (snapshotDivs). + */ +.snapshots +{ + width: 100%; + height: 100%; +} + +/* + * Ce sont des divs créés spécialement lors d'un prézoom. Leur fonction est d'afficher un clone du snapshot, superposé au précédent et de grandir un peu de manière + * à faire ressortir visuellement le snapshot pointé. Leur bordure est d'une couleur différente au fond, ce qui permet de les discerner plus facilement dans la mosaïque. + * au départ, lors de sa création, il est caché, mais apparaît dès que l'image est chargée. + */ +.prezoomContainers +{ + position: absolute; + display: none; + background-image: @selected-snapshot-background-image-path; + background-repeat: repeat; +} + +/* + * Cette classe est attachée à des divs destinés à remplir les bordures d'une mosaïque locale. + */ +.blacks +{ + background-color: @black; + float: left; +} + +/* + * C'est une classe appliquée aux divs "voisins", afin de les colorer lorsque l'utilisateur intéragit avec eux. + * Ils se positionnent exactement sur le voisin qu'ils représentent, à la manière du clone de prézoom (prezoomContainer), bien que celui-là n'est qu'un div simple + * ne contenant pas d'image. + * Au départ, l'opacité est à 0, ce qui signifie que ce div est invisible. L'opacité change lors d'intéractions avec cet objet. Le div apparaît alors. + */ +.neighbourFrame +{ + position: absolute; + //background-color: #94C6C5; + //background-color: rgba(148, 198, 197, 1); + background-image: @selected-snapshot-background-image-path; + background-repeat: repeat; + opacity: 0; +} + +/* + * + */ +.neighbourImgBg +{ + position: absolute; + background-image: @mosaic-background-image-path; +} + +/* + * + */ +.neighbourImg +{ + position: absolute; +} + +video +{ + //position: absolute; +} \ No newline at end of file diff -r 2c7fc855eba8 -r 4003f84cd349 front_idill/src/mosaic/mosaic/css/reset.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/front_idill/src/mosaic/mosaic/css/reset.css Mon May 14 17:20:35 2012 +0200 @@ -0,0 +1,48 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff -r 2c7fc855eba8 -r 4003f84cd349 front_idill/src/mosaic/mosaic/js/localMosaic.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/front_idill/src/mosaic/mosaic/js/localMosaic.js Mon May 14 17:20:35 2012 +0200 @@ -0,0 +1,106 @@ +/* +* This file is part of the TraKERS\Front IDILL package. +* +* (c) IRI +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +/* + * Projet : TraKERS + * Module : Front IDILL + * Fichier : localMosaic.js + * + * Auteur : alexandre.bastien@iri.centrepompidou.fr + * + * Fonctionnalités : Définit la "classe" mosaïque locale (lors d'un zoom sur une mosaïque) et définit des fonctions d'intéractions. + */ + +/* + * Classe définissant la mosaïque locale. + * Elle sera toujours de la forme 3x3, même si toutes les cases ne seront pas remplies par des snapshots (cas des bords et coins). +*/ +function localMosaic(len, imgToShow, marginWidth) +{ + if(imgToShow % len == 0) + { + this.length = len; + this.imagesToShow = imgToShow; + this.centerId; + this.urls = []; + this.imgs = []; + this.ids = []; + this.width; + this.height; + this.marginWidth = marginWidth; + this.zoomed; + this.snapshotTop; + this.snapshotLeft; + this.snapshotWidth; + this.snapshotHeight; + } + else + { + //Affiche un message d'erreur. + } +} + +/* + * Crée la mosaïque locale, qui est une partie de la mosaïque de mosaic.js. + * Il y a le snapshot sur lequel on a zoomé, et les 8 snapshots voisins. +*/ +localMosaic.prototype.createLocalMosaic = function() +{ + var str = ''; + + var t = this.coord1Dto2D(this.centerId); + var localId; + + for(var a = t[1] - 1 ; a < t[1] + 2 ; a++) + for(var b = t[0] - 1 ; b < t[0] + 2 ; b++) + if(a > -1 && a < this.imagesToShow / this.length && b > -1 && b < this.length) + { + localId = this.coord2Dto1D(a, b); + str += '
'; + } + else + str += '
'; + + return str; +} + +/* + * Permet de charger la mosaïque locale. +*/ +localMosaic.prototype.loadLocalMosaic = function(snTop, snLeft, snWidth, snHeight, imgsTab, id) +{ + //On affecte les chemins vers les images à la mosaïque. + this.imgs = imgsTab; + this.centerId = id; + this.snapshotTop = snTop;//*(newPreMPHeight/initMPHeight) - this.zoomedMargin/2 + (initMPHeight - initMPHeight * this.zoomPercentage)/2 + 'px'; + this.previousMPLeft = snLeft; + this.snapshotWidth = snWidth; + this.snapshotHeight = snHeight; + //On met à jour la mosaïque. + $('#mainPanel').html(this.createLocalMosaic(id)); + $('.snapshotDivs').css('width', snWidth).css('height', snHeight).css('margin', this.marginWidth/2); + // var lMosTop = , newZoomLeft = -this.previousZoomedSN.position().left*(newPreMPWidth/initMPWidth) - this.zoomedMargin/2 + (initMPWidth - initMPWidth * this.zoomPercentage)/2 + 'px'; + $('#mainPanel').css('top', 0).css('left', 0); +} + +/* + * Change de 1 à 2 dimensions pour les coordonnées des snapshots dans la mosaïque. +*/ +localMosaic.prototype.coord1Dto2D = function(i) +{ + return [i%length, Math.floor(i/this.length)]; +} + +/* + * Change de 2 à 1 dimension pour les coordonnées des snapshots dans la mosaïque. +*/ +localMosaic.prototype.coord2Dto1D = function(i, j) +{ + return j * this.length + i; +} \ No newline at end of file diff -r 2c7fc855eba8 -r 4003f84cd349 front_idill/src/mosaic/mosaic/js/mosaic.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/front_idill/src/mosaic/mosaic/js/mosaic.js Mon May 14 17:20:35 2012 +0200 @@ -0,0 +1,815 @@ +/* +* This file is part of the TraKERS\Front IDILL package. +* +* (c) IRI +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +/* + * Projet : TraKERS + * Module : Front IDILL + * Fichier : mosaic.js + * + * Auteur : alexandre.bastien@iri.centrepompidou.fr + * + * Fonctionnalités : Définit la "classe" mosaïque et définit des fonctions d'intéractions. + */ + +/* + * Classe définissant la mosaïque. + * Elle contient sa longueur, le nombre d'images total, une liste d'urls pour les vidéos, leurs snapshots principaux et leur position. + * Contient également les dimensions en px de la mosaïque. + */ +function mosaic(len, imgToShow, zoomPercentage, prezoomPercentage, zoomedMargin) +{ + //S'il s'agit d'un rectangle. + if(imgToShow % len == 0) + { + //Longueur horizontale. + this.length = len; + //Nombre d'images dans la mosaïque. + this.imagesToShow = imgToShow; + //Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque. + this.videos = []; + this.urls = []; + this.imgs = []; + this.ids = []; + //Dimensions de la mosaïque en pixels. + this.width; + this.height; + //Dimensions d'un snapshot en pixels. + this.snapshotWidth; + this.snapshotHeight; + //Espacement entre les snapshots en pixels. + this.marginWidth; + + //Temps d'intéractions/d'animations. + this.preZoomTime; + this.preUnzoomTime; + this.zoomTime; + this.unzoomTime; + this.timeNeighbourGlowing; + this.timeNeighbourUnglowing; + this.timeMovingToNeighbour; + + //Booléens permettant ou non certaines intéractions selon le contexte. + this.zoomed; + this.fullscreen; + this.canMoveToNeighbour; + + //Mode actuel. + this.currentMode; + //Snapshot sur lequel on a zoomé. + this.previousZoomedSN; + //Son ID. + this.previousId; + //Largeur de la marge pour le centrage vertical de la mosaïque. + this.MPTop_margin; + this.top_margin; + //Pourcentage d'agrandissement lors d'un prézoom et d'un zoom. + this.prezoomPercentage = prezoomPercentage; + this.zoomPercentage = zoomPercentage; + //Espacement des snapshots après un zoom. + this.zoomedMargin = zoomedMargin; + //Mosaïque locale. + this.localMos; + //Position des voisins lors d'un zoom. + this.neighboursIds = []; + //ID du snapshot du milieu lors d'un zoom. + this.centerId; + + this.player; + + this.loadFromJson('./player/json/videos.json'); + } + else + { + //Affiche un message d'erreur. + } +} + +/* + * Méthode d'affichage de la mosaïque. + * Génère une matrice de imgs. + */ +mosaic.prototype.createMosaic = function() +{ + this.previousZoomedSN = ''; + this.previousPrezoomDiv = ''; + this.fullscreen = false; + this.canMoveToNeighbour = false; + var str = ''; + + if(this.imgs.length >= this.imagesToShow) + { + for(var i = 0 ; i < this.imagesToShow ; i++) + { + //On charge les images de petite taille pour ne pas surcharger la mosaïque lors de l'affichage global. + str += '
'; + } + } + + console.log(this.imagesToShow); + + return str; +} + +/* + * Permet de raffraichir la mosaïque. + */ +mosaic.prototype.loadMosaic = function() +{ + var createMosaic = this.createMosaic(); + + if(createMosaic == '') + { + return; + } + + var _this = this; + + //On affecte les chemins vers les images à la mosaïque. + this.previousZoomedSN; + //this.width = + //On met à jour la mosaïque. + $('#mainPanel').html(createMosaic); + //On récupère la taille des bordures. + this.marginWidth = $('.snapshotDivs').css('margin-bottom'); + this.marginWidth = parseFloat(mos.marginWidth)*2; + //On calcule la taille des divs contenant les snapshots. + this.width = $('#mainPanel').innerWidth(); + //On ne calculera pas tout de suite la hauteur de la mosaique étant donnée qu'elle est calculée par la suite dynamiquement. + this.snapshotWidth = this.width / this.length - this.marginWidth; + this.snapshotHeight = this.snapshotWidth*9/16; + $('.snapshotDivs').css('width', this.snapshotWidth).css('height', this.snapshotHeight).css('margin', this.marginWidth/2); + + this.height = $('#mainPanel').innerHeight(); + //On centre verticalement la mosaïque. + this.MPTop_margin = ($(document).height() - $('#mainPanel').height())/2; + $('#mainPanel').css('margin-top', this.MPTop_margin).css('margin-bottom', this.MPTop_margin); + + $('.snapshotDivs').mouseenter(function () + { + //On effectue un prézoom dès qu'on va sur une image. + _this.preZoom($(this)); + }); + $('body').keypress(function (event) + { + //Si on a appuié sur la touche 'q' ou 'Q'; + if(event.which == 113 || event.which == 81) + { + _this.unzoom(); + } + }); +} + +/* + * Zoom sur la position d'une image, 1ère partie. Durant le laps de temps de time ms, l'utilisateur a le choix de zoomer sur une autre image. + * Après ce laps de temps, l'image zoom complétement et il n'est plus possible de sélectionner une autre image par pointage. + */ +mosaic.prototype.preZoom = function(snapshot) +{ + if(this.fullscreen) + { + return; + } + //Mosaïque. + var mosaic = this; + //Dimensions de la mosaïque. + var h = this.height, w = this.width; + //Longueur en images, nombre d'images et taille de bordure de la mosaïque. + var len = this.length, imgs = this.imagesToShow, margin = this.marginWidth; + //Dimensions et position d'un snapshot dans la mosaïque. + var snHeight = this.snapshotHeight, snWidth = this.snapshotWidth; + var sTop = snapshot.position().top, sLeft = snapshot.position().left; + var prezoomPercentage = this.prezoomPercentage; + + //ID de l'image actuelle. + var currentId = $('img', snapshot).attr('id'); + + //Si un zoom est déjà en cours, on ne zoom sur rien d'autre en attendant que ce snapshot ai dézoomé en cas de mouseleave. + if(this.zoomed) + { + if($('#preZoomContainer-' + currentId) != $(this) && this.previousZoomedSN != '' && this.previousId != '') + { + this.preUnzoom(); + } + else + { + return; + } + } + + //On indique qu'on a zoomé et on spécifie le snapshot sur lequel on a zoomé. + this.zoomed = true; + this.previousZoomedSN = snapshot; + this.previousId = currentId; + + //On récupère les attributs de l'image. + var fakeImg = $('img', snapshot); + //On forme la balise de la fausse image et on passe son url pour les grands snapshots. + fakeImg = ''; + //On génère un faux snapshot identique au précédent et qu'on va coller dessus. + var fakeSnapshot = '
' + fakeImg + '
'; + + //On l'ajoute à la mosaïque. + $('#mainPanel').append(fakeSnapshot); + //On modifie ses attributs. + $('#fake-' + currentId).load(function() + { + $('#prezoomContainer-' + currentId).css('display', 'block'); + $('#prezoomContainer-' + currentId).css('top', sTop).css('left', sLeft).css('width', (snWidth + margin)).css('height', (snHeight + margin)); + $('#prezoomSnapshot-' + currentId).css('width', (snWidth)).css('height', (snHeight)); + + //Dimensions et coordonnées initiales du div sur lequel on zoom. + var initialDivWidth = $('#prezoomContainer-' + currentId).width(), initialDivHeight = $('#prezoomContainer-' + currentId).height(); + var initialDivTop = $('#prezoomContainer-' + currentId).position().top, initialDivLeft = $('#prezoomContainer-' + currentId).position().left; + //Dimensions et coordonnées finales du div. + var finalDivWidth = initialDivWidth * (prezoomPercentage+1), diffWidth = finalDivWidth - initialDivWidth, finalDivHeight = initialDivHeight + diffWidth; + var finalDivTop = (initialDivTop - (finalDivHeight - snHeight)/2), finalDivLeft = (initialDivLeft - (finalDivWidth - snWidth)/2); + + //CAS PARTICULIER pour la position du snapshot zoomé : les bordures. + if(finalDivTop < 0) + { + finalDivTop = -margin; + } + if(finalDivTop + finalDivHeight > h) + { + finalDivTop = h - finalDivHeight; + } + if(finalDivLeft < 0) + { + finalDivLeft = 0; + } + if(finalDivLeft + finalDivWidth + margin*2 > w) + { + finalDivLeft = w - finalDivWidth - margin*2; + } + + ////Code de debug. + ////CAUTION//// + /*var red = '
'; + if($('#red') != null || $('#red') != undefined) + $('body').append(red); + $('#red').css('background-color', '#FF0000').css('position', 'absolute').css('top', '0px').css('left', '0px').css('width', '100px').css('height', '100px'); + $('#red').css('top', finalDivTop).css('left', finalDivLeft).css('width', finalDivWidth).css('height', finalDivHeight);*/ + //alert("initial : " + initialDivWidth + " " + initialDivHeight + " ; final : " + finalDivWidth + " " + finalDivHeight); + ////CAUTION//// + + //On prézoom le div en le centrant sur le milieu du snapshot pointé. + $('#prezoomSnapshot-' + currentId).animate( + { + width: finalDivWidth + margin, + height: finalDivHeight - margin*2, + top: finalDivTop + margin, + left: finalDivLeft + margin + }, this.preZoomTime); + $('#prezoomContainer-' + currentId).animate( + { + width: finalDivWidth + margin*2, + height: finalDivHeight - margin, + top: finalDivTop + margin, + left: finalDivLeft + }, this.preZoomTime); + }); + + //Si on clique sur le snapshot prézoomé, on enclenche un zoom total sur ce snapshot. + $('#prezoomContainer-' + currentId).click(function () + { + if(this.previousZoomedSN != '') + { + mosaic.zoom(); + } + }); +} + +/* + * Dézoome sur la position de l'image. Il est à noter que ce dézoome diffère du dézoom global dans la mesure où celui-ci ne concerne que l'image sur laquelle on a zoomé. + */ +mosaic.prototype.preUnzoom = function() +{ + //Si on n'a pas zoomé, on quitte la fonction. + if(!this.zoomed) + { + return; + } + + //On spécifie la marge afin de centrer le prédézoom. + var margin = this.marginWidth; + //ID du snapshot précédemment pointé. + var id = this.previousId; + //On ne zoom plus. + this.zoomed = false; + //On rétrécit le snapshot de prézoom, puis on le supprime en donnant l'illusion qu'il s'agissait du véritable snapshot, alors qu'en fait c'était un clone. + $('#prezoomSnapshot-' + id).animate( + { + width: this.snapshotWidth, + height: this.snapshotHeight, + top: this.previousZoomedSN.position().top, + left: this.previousZoomedSN.position().left + }, this.preUnzoomTime); + $('#prezoomContainer-' + id).animate( + { + width: this.snapshotWidth + margin, + height: this.snapshotHeight + margin, + top: this.previousZoomedSN.position().top, + left: this.previousZoomedSN.position().left + }, this.preUnzoomTime, function(){ $(this).remove(); this.zoomed = false; }); +} + + +/* + * Zoom d'un snapshot en plein écran. + */ +mosaic.prototype.zoom = function() +{ + var mos = this; + + //Si la mosaïque est en pleine écran, pas la peine de zoomer. + if(this.fullscreen) + { + return; + } + + //On prend les attributs nécessaires au calculs. + var margin = this.marginWidth, len = this.length, imgs = this.imagesToShow; + var initMPWidth = this.previousZoomedSN.width() * len + margin*len, initMPHeight = this.previousZoomedSN.height() * (imgs / len) + margin*(imgs / len); + var newMPWidth = initMPWidth * len + this.zoomedMargin * (len), newMPHeight = initMPHeight * (imgs / len) + this.zoomedMargin * ((imgs / len)); + var newPreMPWidth = initMPWidth * len * this.zoomPercentage + this.zoomedMargin * (len), newPreMPHeight = initMPHeight * (imgs / len) * this.zoomPercentage + this.zoomedMargin * ((imgs / len)); + + //Dimensions et coordonnées initiales du div sur lequel on zoom. + var initialDivWidth = this.previousZoomedSN.width(), initialDivHeight = this.previousZoomedSN.height(); + var initialDivTop = this.previousZoomedSN.position().top, initialDivLeft = this.previousZoomedSN.position().left; + //Dimensions et coordonnées finales du div. + var finalDivWidth = initialDivWidth * (this.zoomPercentage+1), finalDivHeight = initialDivHeight * (this.zoomPercentage+1); + var newZoomTop = -this.previousZoomedSN.position().top*(newPreMPHeight/initMPHeight) - this.zoomedMargin/2 + (initMPHeight - initMPHeight * this.zoomPercentage)/2, newZoomLeft = -this.previousZoomedSN.position().left*(newPreMPWidth/initMPWidth) - this.zoomedMargin/2 + (initMPWidth - initMPWidth * this.zoomPercentage)/2; + var newSnWidth = initMPWidth * this.zoomPercentage, newSnHeight = initMPHeight * this.zoomPercentage; + + this.preUnzoom(this); + /*SINGULARITE*/ + this.fullscreen = true; + + //On passe l'image du snapshot pointé en HD. + var zoomedImg = $('img', this.previousZoomedSN); + var src = zoomedImg.attr('src'); + zoomedImg.attr('src', src.replace('-little/', '/')); + + //On récupère son ID. + var tab, zoomedImgId; + tab = mos.previousId.split('-'); + zoomedImgId = tab[1]; + + //Les snapshots baissent alors en opacité, donnant l'impression qu'ils sont grisés. + $('.snapshotDivs').animate( + { + width: newSnWidth, + height: newSnHeight, + margin: this.zoomedMargin/2 + 'px', + opacity: '0.4' + }, this.zoomTime); + //Le snapshot du milieu revient à une opacité optimale, ce qui attire l'attention de l'utilisateur. + $(this.previousZoomedSN).animate( + { + opacity: '1' + }, this.zoomTime); + //On zoome sur la mosaïque. + $('#mainPanel').animate( + { + width: newPreMPWidth, + height: newPreMPHeight, + top: newZoomTop, + left: newZoomLeft + }, this.zoomTime, function() + { + //On charge les interactions avec les voisins. + mos.centerId = zoomedImgId; + mos.listenToNeighbours(); + mos.currentMode = 'VIDEO'; + + console.log('h : ' + -newZoomLeft + " " + zoomedImg.position().left); + + mos.loadPlayer((zoomedImg.position().top + newZoomTop + mos.MPTop_margin), (zoomedImg.position().left + newZoomLeft), newSnWidth + 1, newSnHeight + 1); + + /*mos.unload(); + mos.localMos.loadLocalMosaic(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, mos.imgs, tab[1]);*/ + }); +} + +/* + * Chargement du player basé sur le metadataplayer. +*/ +mosaic.prototype.loadPlayer = function(newZoomTop, newZoomLeft, newSnWidth, newSnHeight) +{ + //On configure les options de lancement. + IriSP.libFiles.defaultDir = "../lib/"; + IriSP.widgetsDir = "./player/metadataplayer/" + + var videoToPlay = this.videos[this.centerId]; + var currentMetadata = this.urls[this.centerId]; + console.log('VIDEO[' + this.centerId + '] : ' + videoToPlay); + console.log('MD[' + this.centerId + '] : ' + currentMetadata); + + console.log(newZoomTop + " " + newZoomLeft); + + var _metadata = { + url: currentMetadata, + format: 'ldt' + }; + var _config = { + gui: { + width: newSnWidth, + height: newSnHeight, + container: 'LdtPlayer', + default_options: { + metadata: _metadata + }, + css:'./player/metadataplayer/LdtPlayer-core.css', + widgets: [ + { + type: "Timeline" + } + ] + }, + player:{ + type: 'html5', // player type + video: videoToPlay, + live: true, + height: newSnHeight, + width: newSnWidth, + autostart: true + } + }; + + //On positionne le player. + $('.LdtPlayer').css( + { + //display: 'none', + position: 'absolute', + 'background-color': '#000000', + top: newZoomTop, + left: newZoomLeft + }); + + //On démarre le player. + this.player = null; + this.player = new IriSP.Metadataplayer(_config, _metadata); +} + +/* + * Retour à la taille normale de la mosaïque. + */ +mosaic.prototype.unzoom = function() +{ + //Si on n'est pas en plein écran, on quitte. + if(!this.fullscreen) + { + return; + } + + //On charge les attributs nécessaires aux calculs. + var sWidth = this.snapshotWidth, sHeight = this.snapshotHeight; + var mpWidth = this.width, mpHeight = this.height; + var mos = this; + + //On passe le snapshot sur lequel on a zoomé en SD. + var zoomedImg = $('img', this.previousZoomedSN); + var src = zoomedImg.attr('src'); + zoomedImg.attr('src', src.replace('snapshots/', 'snapshots-little/')); + + $('div').remove('.LdtPlayer'); + $('body').append('
'); + + //On rend leur opacité aux snapshots. Qui ne sont alors plus grisés. + $('.snapshotDivs').animate( + { + width: sWidth, + height: sHeight, + margin: this.marginWidth/2 + 'px', + opacity: '1' + }, this.unzoomTime); + //On dézoom sur la mosaïque. + $('#mainPanel').animate( + { + width: mpWidth, + height: mpHeight, + top: '0px', + left: '0px' + }, this.unzoomTime, function() + { + //On n'est plus en plein écran, et on ne peut plus se déplacer vers le prochain voisin. + mos.fullscreen = false; + mos.canMoveToNeighbour = false; + //On revient en mode MOSAIC. + mos.currentMode = 'MOSAIC'; + //On ne permet plus le déplacement vers les voisins. + $('.snapshotDivs').unbind('mouseenter', mos.selectNeighbour); + }); +} + +/* + * Affecte les listeners mouseenter aux voisins lors d'une vue en plein écran. + */ +mosaic.prototype.listenToNeighbours = function() +{ + ////TEST + //$('.test').empty(); + this.canMoveToNeighbour = false; + var currentLine = Math.floor(this.centerId / this.length), currentColumn = this.centerId % this.length; + var zoomedImg = $('img', this.previousZoomedSN); + var mos = this; + + //On cherche l'ID des voisins. + //Si le voisin de gauche est sur la même ligne, on n'est pas sur la bordure de gauche. + this.neighboursIds[0] = (currentColumn > 0) ? (this.centerId - 1) : -1; + //Si le voisin de droite est sur la même ligne, on n'est pas sur la bordure de droite. + this.neighboursIds[1] = (currentColumn < this.length) ? (+this.centerId + 1) : -1; + //Si le voisin du haut est sur la même colonne, on n'est pas sur la bordure du haut. + this.neighboursIds[2] = (currentLine > 0) ? (this.centerId - this.length) : -1; + //Si le voisin du bas est sur la même colonne, on n'est pas sur la bordure du bas. + this.neighboursIds[3] = (currentLine < (this.imagesToShow / this.length)) ? (+this.centerId + this.length) : -1; + + //ID du cadre voisin. + var preId; + + for(var i = 0 ; i < this.neighboursIds.length ; i++) + { + if(this.neighboursIds[i] != -1) + { + preId = '#neighbourFrameBorder-' + this.neighboursIds[i]; + //On permet le déplacement vers les voisins. + // $('#snapshotDiv-' + this.neighboursIds[i] + ', ' + preId + '-left,' + preId + '-right,' + preId + '-up,' + preId + '-down').mouseenter(mos.selectNeighbour); + $('#snapshotDiv-' + this.neighboursIds[i]).mouseenter(mos.selectNeighbour); + } + } +} + +/* + * Change la coloration d'une bordure où on se positionne lors d'une vue en plein écran. + */ +mosaic.prototype.selectNeighbour = function() +{ + ////TEST + //$('.test').append(mos.currentMode + " " + $(this).attr('id') + " " + 'snapshotDiv-' + mos.centerId + ','); + + //Si on est en mode VIDEO (plein écran) ET si le snapshot pointé est un voisin. + if((mos.currentMode == 'VIDEO') && ($(this).attr('id') != 'snapshotDiv-' + mos.centerId)) + { + //On crée le cadre qui va être superposé au voisin. + //On le colle au voisin. + var tab = $(this).attr('id').split('-'); + var snapshotId = tab[1]; + var neighbourFrame = ''; + var marginValue = parseFloat($(this).css('margin')); + + neighbourFrame += '
'; + + $('#mainPanel').append(neighbourFrame); + + //On positionne le div de background juste au niveau du voisin. + $('#neighbourFrame-' + snapshotId).css( + { + 'top': (+$(this).position().top + marginValue), + 'left': (+$(this).position().left + marginValue), + 'width': $(this).width(), + 'height': $(this).height() + }); + //On positionne le div de background noir juste au niveau de l'image du voisin. + $('#neighbourImgBg-' + snapshotId).css( + { + 'top': marginValue, + 'left': marginValue, + 'width': $(this).width() - marginValue*2, + 'height': $(this).height() - marginValue*2, + }); + //On met par dessus le div de l'image clonée du voisin. + $('#neighbourImg-' + snapshotId).css( + { + 'top': 0, + 'left': 0, + 'width': $(this).width() - marginValue*2, + 'height': $(this).height() - marginValue*2, + 'background-image': 'url("' + $('img', $(this)).attr('src') + '")', + 'background-size': $(this).width() + 'px ' + $(this).height() + 'px', + 'background-position': -marginValue + 'px ' + -marginValue + 'px', + 'opacity': '0.4' + }); + + var fId = '#neighbourFrame-' + snapshotId; + + $(fId).animate( + { + //On le fait apparaître. + opacity: '1' + }, timeNeighbourGlowing, function() + { + //On peut désormais se déplacer vers ce voisin. + mos.canMoveToNeighbour = true; + }); + //Lorsqu'on quitte un des snapshots (bien entendu le voisin en question), on retire le cadre. + $(fId).mouseleave(mos.deselectNeighbour) + //Si on clique sur le voisin ou son cadre, on passe au voisin suivant. + $(fId).click(mos.moveToNeighbour); + } +} + +/* + * Change la coloration d'une bordure quittée lors d'une vue en plein écran. + */ +mosaic.prototype.deselectNeighbour = function() +{ + ////TEST + //$('.test').append('un,'); + + //On ne peut plus se déplacer vers les voisins. + mos.canMoveToNeighbour = false; + + //On récupère le voisin. + var neighbourFrame = $(this); + + //Si on est en mode VIDEO. + if(mos.currentMode == 'VIDEO') + { + //On le fait disparaître progressivement. + neighbourFrame.animate( + { + opacity: '0' + }, timeNeighbourUnglowing, function() + { + //Une fois invisible, on le supprime. + neighbourFrame.remove(); + }); + } +} + +/* + * Lors d'une vue en plein écran, on se déplace vers le voisin dont l'id a été spécifié dans la fonction appelante. + */ +mosaic.prototype.moveToNeighbour = function() +{ + //Si on ne peut pas se déplacer vers les voisins, on quitte. + if(!mos.canMoveToNeighbour) + { + return; + } + + //On obtient l'ID de destination. + var tab = $(this).attr('id').split('-'); + var destinationId = tab[1]; + + //On charge les attributs nécessaires aux calculs. + var MPCurrentTop = $('#mainPanel').position().top, MPCurrentLeft = $('#mainPanel').position().left; + var divideCoeffTop = Math.floor(destinationId / mos.length) == 0 ? 1 : Math.floor(destinationId / mos.length); + var divideCoeffLeft = destinationId % mos.length == 0 ? 1 : destinationId % mos.length; + var neighbourFrameTop = $('#snapshotDiv-' + destinationId).position().top, neighbourFrameLeft = $('#snapshotDiv-' + destinationId).position().left; + + //On définit pour le déplacement vertical s'il est nécessaire de se déplacer en haut ou en bas. + if(mos.previousZoomedSN.position().top > neighbourFrameTop) + MPCurrentTop += Math.abs(neighbourFrameTop - mos.previousZoomedSN.position().top); + else if(mos.previousZoomedSN.position().top < neighbourFrameTop) + MPCurrentTop -= Math.abs(neighbourFrameTop - mos.previousZoomedSN.position().top); + //On définit pour le déplacement horizontal s'il est nécessaire de se déplacer à gauche ou à droite. + if(mos.previousZoomedSN.position().left > neighbourFrameLeft) + MPCurrentLeft += Math.abs(neighbourFrameLeft - mos.previousZoomedSN.position().left); + else if(mos.previousZoomedSN.position().left < neighbourFrameLeft) + MPCurrentLeft -= Math.abs(neighbourFrameLeft - mos.previousZoomedSN.position().left); + + //On passe le snapshot de destination en HD. + var destinationImg = $('#snapshot-' + destinationId); + var destinationImgSrc = destinationImg.attr('src'); + destinationImg.attr('src', destinationImgSrc.replace('snapshots-little/', 'snapshots/')); + + //On passe l'ancien snapshot en SD. + var currentImgSrc = $('img', mos.previousZoomedSN).attr('src'); + $('img', mos.previousZoomedSN).attr('src', currentImgSrc.replace('snapshots/', 'snapshots-little/')); + + //On obtient l'ID du div de coloration du snapshot vers lequel on se déplace afin de le supprimer. + var neighbourFrame = $(this); + var tab = neighbourFrame.attr('id').split('-'); + mos.centerId = tab[1]; + $(this).css('opacity', '0'); + neighbourFrame.remove(); + + $('div').remove('.LdtPlayer'); + $('body').append('
'); + + //On grise le snapshot qu'on vient de quitter. + mos.previousZoomedSN.animate( + { + opacity: '0.4' + }); + + //On se déplace. + $('#mainPanel').animate( + { + top: MPCurrentTop, + left: MPCurrentLeft + }, timeMovingToNeighbour, function() + { + //On fait apparaître le snapshot vers lequel on s'est déplacé. + $('#snapshotDiv-' + destinationId).animate( + { + opacity: '1' + }, mos.zoomTime, function() + { + //On recharge les voisins. + $('.snapshotDivs').unbind('mouseenter', mos.selectNeighbour); + mos.previousZoomedSN = $('#snapshotDiv-' + mos.centerId); + mos.listenToNeighbours(); + + mos.loadPlayer((destinationImg.position().top + MPCurrentTop + mos.MPTop_margin), (destinationImg.position().left + MPCurrentLeft), destinationImg.width(), destinationImg.height()); + }); + }); +} + +/* + * Déchargement du contenu de la mosaïque pour le chargement de la mosaïque locale. + */ +mosaic.prototype.unload = function() +{ + //On supprime les event listeners des objets de la mosaïque. + $('.snapshotDivs').unbind(); + $('.snapshots').unbind(); + $('.prezoomContainers').unbind(); + //On supprime physiquement les objets. + $('#mainPanel').empty(); +} + +/* + * Centre verticalement un snapshot. + */ +/*function verticalCenterImg(mosaic, img) +{ + //On récupère sa hauteur. + var image_height = img.height(); + //Calcule la marge du haut de chaque div pour le centrage. + if(mosaic.top_margin == undefined) + mosaic.top_margin = (mosaic.snapshotHeight > image_height) ? (mosaic.snapshotHeight - image_height)/2 : (image_height - mosaic.snapshotHeight)/2; + //On centre le snapshot. + img.css('margin-top', mosaic.top_margin).css('margin-bottom', mosaic.top_margin); +}*/ + +/* + * Permet de tester l'égalité des éléments de deux objets. + * Pour ce faire on compare les éléments définissant ces objets. + */ +$.fn.equals = function(compareTo) +{ + if (!compareTo || !compareTo.length || this.length!=compareTo.length) + { + return false; + } + for (var i=0; i + + + + Metadataplayer - Polemic tweet integration test + + + + + + + + + + + + + + + +
+
+ + + + + +
+ diff -r 2c7fc855eba8 -r 4003f84cd349 front_idill/src/player/json/videos.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/front_idill/src/player/json/videos.json Mon May 14 17:20:35 2012 +0200 @@ -0,0 +1,560 @@ +{ + "videos" : [ + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/23256da6-66b9-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "mue.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/076230fe-66b9-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "deep end dance.png", + "gestures": [ + { + "gesture_name": "circle", + "snapshot": "" + }, + { + "gesture_name": "jump", + "snapshot": "" + }, + { + "gesture_name": "contact", + "snapshot": "" + }, + { + "gesture_name": "updown", + "snapshot": "" + }, + { + "gesture_name": "wave", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/b411a6dc-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "-s-pression.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/98517ca6-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "i am my mother.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/9e92ebdc-66b7-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "hannah.png", + "gestures": [ + { + "gesture_name": "wave", + "snapshot": "" + }, + { + "gesture_name": "run", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/82cd7e30-66b7-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "vrtti.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/0d8f65f6-66b8-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "palms.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/f1cee904-66b7-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "fenella.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/2f8b92b6-66b7-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "patria.png", + "gestures": [ + { + "gesture_name": "circle", + "snapshot": "" + }, + { + "gesture_name": "updown", + "snapshot": "" + }, + { + "gesture_name": "slow", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/3f1f08e6-66b9-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "stronger.png", + "gestures": [ + { + "gesture_name": "jump", + "snapshot": "" + }, + { + "gesture_name": "circle", + "snapshot": "" + }, + { + "gesture_name": "contact", + "snapshot": "" + }, + { + "gesture_name": "beat", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/ba4d888c-66b7-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "50 shots.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/7c912bce-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "body trail cctv.png", + "gestures": [ + { + "gesture_name": "screw", + "snapshot": "" + }, + { + "gesture_name": "contact", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/f80bd9fe-66b6-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "encontro cotidianos.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/d610e47e-66b7-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "instrument.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/dc8c4d62-66b6-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "jeu de societe.png", + "gestures": [ + { + "gesture_name": "wave", + "snapshot": "" + }, + { + "gesture_name": "run", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/e2b5b9e8-562c-11e1-b3c3-00145ea49a02?callback=?", + "snapshot": "joudance 2 in asakusa_stage1.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/cfd63004-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "nid de lune.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/4b4aa85c-66b7-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "molecule no.1.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/eba1967a-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "mine.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/60d03074-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "you are you.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/c66bfa64-66b6-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "new under the sun.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/294f727c-66b8-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "sliced.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/670c5054-66b7-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "field n.8.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/23256da6-66b9-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "mue.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/076230fe-66b9-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "deep end dance.png", + "gestures": [ + { + "gesture_name": "circle", + "snapshot": "" + }, + { + "gesture_name": "jump", + "snapshot": "" + }, + { + "gesture_name": "contact", + "snapshot": "" + }, + { + "gesture_name": "updown", + "snapshot": "" + }, + { + "gesture_name": "wave", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/b411a6dc-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "-s-pression.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/98517ca6-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "i am my mother.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/9e92ebdc-66b7-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "hannah.png", + "gestures": [ + { + "gesture_name": "wave", + "snapshot": "" + }, + { + "gesture_name": "run", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/82cd7e30-66b7-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "vrtti.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/0d8f65f6-66b8-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "palms.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/f1cee904-66b7-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "fenella.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/2f8b92b6-66b7-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "patria.png", + "gestures": [ + { + "gesture_name": "circle", + "snapshot": "" + }, + { + "gesture_name": "updown", + "snapshot": "" + }, + { + "gesture_name": "slow", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/3f1f08e6-66b9-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "stronger.png", + "gestures": [ + { + "gesture_name": "jump", + "snapshot": "" + }, + { + "gesture_name": "circle", + "snapshot": "" + }, + { + "gesture_name": "contact", + "snapshot": "" + }, + { + "gesture_name": "beat", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/ba4d888c-66b7-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "50 shots.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/7c912bce-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "body trail cctv.png", + "gestures": [ + { + "gesture_name": "screw", + "snapshot": "" + }, + { + "gesture_name": "contact", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/f80bd9fe-66b6-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "encontro cotidianos.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/d610e47e-66b7-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "instrument.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/dc8c4d62-66b6-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "jeu de societe.png", + "gestures": [ + { + "gesture_name": "wave", + "snapshot": "" + }, + { + "gesture_name": "run", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/e2b5b9e8-562c-11e1-b3c3-00145ea49a02?callback=?", + "snapshot": "joudance 2 in asakusa_stage1.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/cfd63004-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "nid de lune.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/4b4aa85c-66b7-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "molecule no.1.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/eba1967a-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "mine.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/60d03074-66b8-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "you are you.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/c66bfa64-66b6-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "new under the sun.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/294f727c-66b8-11e1-91ba-00145ea4a2be?callback=?", + "snapshot": "sliced.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + }, + { + "metadata": "http://ldt.iri.centrepompidou.fr//ldtplatform/ldt/cljson/id/670c5054-66b7-11e1-80f6-00145ea4a2be?callback=?", + "snapshot": "field n.8.png", + "gestures": [ + { + "gesture_name": "", + "snapshot": "" + } + ] + } + ] +} \ No newline at end of file diff -r 2c7fc855eba8 -r 4003f84cd349 front_idill/src/player/metadataplayer/Timeline.js --- a/front_idill/src/player/metadataplayer/Timeline.js Fri May 11 11:04:06 2012 +0200 +++ b/front_idill/src/player/metadataplayer/Timeline.js Mon May 14 17:20:35 2012 +0200 @@ -20,10 +20,45 @@ this.top_epsilon = 0; this.imgDir = "player/img/"; this.markersDir = "player/markers/"; + + this.gestures = ["swipe-down", "jump", "circle", "screw", "bend", "join-hands", "arc", "pendulum", "knee-up", "right-angle", "wave", "slow", "hello", "beat", "cross", "wheel", "contact", "run"]; + + this.annotations = this.annotationsFilter(this.source.getAnnotations(), this.gestures, this.isGesture); + + // for(var a = 0 ; a < this.annotations.length ; a++) + // console.log("A : " + this.annotations[a].annotationType.contents.title); }; IriSP.Widgets.Timeline.prototype = new IriSP.Widgets.Widget(); +IriSP.Widgets.Timeline.prototype.isGesture = function(element, index, array) +{ + return ($.inArray(element.annotationType.contents.title, array) > -1); +} + +//Fonction de filtrage de tableaux +IriSP.Widgets.Timeline.prototype.annotationsFilter = function(annotations, gestures, fun /*, thisp*/) +{ + var len = annotations.length; + if (typeof fun != "function") + throw new TypeError(); + + var res = new Array(); + var thisp = arguments[1]; + for (var i = 0; i < len; i++) + { + if (i in annotations) + { + var val = annotations[i]; // in case fun mutates this + if (fun.call(thisp, val, i, gestures)) + { + res.push(val); + } + } + } + return res; +}; + IriSP.Widgets.Timeline.prototype.defaults = { minimized_height : 44, maximized_height : 44, @@ -133,13 +168,12 @@ */ IriSP.Widgets.Timeline.prototype.processMarkers = function() { var _this = this; - var annotations = this.source.getAnnotations(); var markers = ""; var timelineMiddleTop = this.$timelineMiddle.position().top; - for(var i = 0 ; i < annotations.length ; i++) + for(var i = 0 ; i < this.annotations.length ; i++) { - markers += "
"; + markers += "
"; // console.log(annotations[i].begin.milliseconds); } @@ -147,12 +181,12 @@ var markerHeight = IriSP.jQuery(".Ldt-Marker").height(); IriSP.jQuery(".Ldt-Marker").css("z-align", "150"); - for(var i = 0 ; i < annotations.length ; i++) + for(var i = 0 ; i < this.annotations.length ; i++) { - IriSP.jQuery("#" + annotations[i].id.replace(":", "_")).css( + IriSP.jQuery("#" + this.annotations[i].id.replace(":", "_")).css( { top: timelineMiddleTop + "px", - left: Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), annotations[i].begin/1000) + this.$timeline.position().left) + "px", + left: Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), this.annotations[i].begin/1000) + this.$timeline.position().left) + "px", "margin-top": (-_this.$timeline.height()/2 - markerHeight/2) - this.top_epsilon + "px" }); } @@ -174,9 +208,8 @@ //On supprime le marqueur précédemment affiché si c'est le cas. if(this.previousMarkerIdx > -1) { - var annotations = this.source.getAnnotations(); // console.log("EXT hide idx " + this.previousMarkerIdx); - var previousMarker = IriSP.jQuery("#" + annotations[this.previousMarkerIdx].id.replace(":", "_")); + var previousMarker = IriSP.jQuery("#" + this.annotations[this.previousMarkerIdx].id.replace(":", "_")); this.hideMarkerBig(previousMarker); // console.log("EXT hide " + this.previousMarkerIdx); } @@ -382,7 +415,6 @@ IriSP.Widgets.Timeline.prototype.onTimeupdate = function() { var _time = this.player.popcorn.currentTime(); var arrowLeft = Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), _time) + this.$timeline.position().left) - IriSP.jQuery("#TL_ArrowUp").width()/2 + "px"; - var annotations = this.source.getAnnotations(); this.$timeline.slider("value",_time*1000); IriSP.jQuery(".TL_Arrows").css("display", "block"); @@ -391,19 +423,19 @@ // this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: 1000 * _time}); //Si on a une distance de 500 ms à un marqueur, on l'affiche. var nearestMarkerIdx = 0; - for(var i = 0 ; i < annotations.length ; i++) + for(var i = 0 ; i < this.annotations.length ; i++) { //S'il existe des marqueurs dans l'intervalle de temps actuel (ici 500ms). - if(Math.abs(_time*1000 - annotations[i].begin.milliseconds) <= 250) + if(Math.abs(_time*1000 - this.annotations[i].begin.milliseconds) <= 250) { // console.log("1) i = " + i + " " + Math.abs(_time*1000 - annotations[i].begin.milliseconds)); //On sélectionne le plus proche marqueur (dans les cas où il en existe plusieurs dans l'intervalle des 1s) ou bien le premier marqueur. - if(Math.abs(_time*1000 - annotations[i].begin.milliseconds) < Math.abs(_time*1000 - annotations[nearestMarkerIdx].begin.milliseconds) || i == nearestMarkerIdx) + if(Math.abs(_time*1000 - this.annotations[i].begin.milliseconds) < Math.abs(_time*1000 - this.annotations[nearestMarkerIdx].begin.milliseconds) || i == nearestMarkerIdx) { // console.log("2) " + Math.abs(_time*1000 - annotations[i].begin.milliseconds) + " < " + Math.abs(_time*1000 - annotations[nearestMarkerIdx].begin.milliseconds)); //Si le prochain marqueur se situe après le curseur de lecture, on passe donc au marqueur le plus proche. - if(_time*1000 < annotations[i].begin.milliseconds) + if(_time*1000 < this.annotations[i].begin.milliseconds) { // console.log("3) " + _time*1000 + " < " + annotations[i].begin.milliseconds); // console.log("4) " + "nearest = " + i); @@ -412,18 +444,18 @@ //S'il y a un changement de marqueur (marqueur actuel différent du précédent). if(nearestMarkerIdx != this.previousMarkerIdx) { - var currentMarker = IriSP.jQuery("#" + annotations[nearestMarkerIdx].id.replace(":", "_")); + var currentMarker = IriSP.jQuery("#" + this.annotations[nearestMarkerIdx].id.replace(":", "_")); //S'il existe un marqueur précédent, on le cache. if(this.previousMarkerIdx > -1) { // console.log("hide idx " + this.previousMarkerIdx); - var previousMarker = IriSP.jQuery("#" + annotations[this.previousMarkerIdx].id.replace(":", "_")); + var previousMarker = IriSP.jQuery("#" + this.annotations[this.previousMarkerIdx].id.replace(":", "_")); this.hideMarkerBig(previousMarker); // console.log("5a) hide " + this.previousMarkerIdx); } // console.log("5b) show " + nearestMarkerIdx); - this.showMarkerBig(currentMarker, annotations[nearestMarkerIdx].annotationType.contents.title); + this.showMarkerBig(currentMarker, this.annotations[nearestMarkerIdx].annotationType.contents.title); //Mise à jour du marqueur précédent s'il y a un changement. this.previousMarkerIdx = nearestMarkerIdx; // console.log("MAJ : " + this.previousMarkerIdx); @@ -540,7 +572,20 @@ var _this = this; - var markerTop = marker.position().top, markerLeft = marker.position().left, markerWidth = marker.width(), markerHeight = marker.height(); + var markerTop, markerLeft; + + if(marker.position() == null) + { + markerTop = 0; + markerLeft = 0; + } + else + { + markerTop = marker.position().top; + markerLeft = marker.position().left; + } + + var markerWidth = marker.width(), markerHeight = marker.height(); this.markerBigShown = true; var markerBig = "
" + type + "
"; @@ -611,16 +656,15 @@ var _this = this; //On récupère les annotations. - var annotations = this.source.getAnnotations(); var markersSearch = "", markersPicSearch = ""; //Pour chaque annotation, on ajoute un double. - for(var i = 0 ; i < annotations.length ; i++) + for(var i = 0 ; i < this.annotations.length ; i++) { //Si elle correspond à la recherche. - if(annotations[i].annotationType.contents.title == type) + if(this.annotations[i].annotationType.contents.title == type) { //On récupère le marqueur associé à l'annotation. - var markerId = annotations[i].id.replace(":", "_"); + var markerId = this.annotations[i].id.replace(":", "_"); markersSearch += "
"; markersPicSearch += "
"; @@ -630,12 +674,12 @@ this.$.append(markersSearch + markersPicSearch); //On place chaque double. - for(var i = 0 ; i < annotations.length ; i++) + for(var i = 0 ; i < this.annotations.length ; i++) { //Si elle correspond à la recherche. - if(annotations[i].annotationType.contents.title == type) + if(this.annotations[i].annotationType.contents.title == type) { - var markerId = annotations[i].id.replace(":", "_"), marker = IriSP.jQuery("#" + markerId); + var markerId = this.annotations[i].id.replace(":", "_"), marker = IriSP.jQuery("#" + markerId); var markerTop = marker.position().top, markerLeft = marker.position().left, markerWidth = marker.width(), markerHeight = marker.height(); var markerBigPicWidth = parseFloat(IriSP.jQuery(".search_MBPic").css("width")), markerBigPicHeight = parseFloat(IriSP.jQuery(".search_MBPic").css("height")), markerBigPicTop = +parseFloat(marker.css("margin-top")) + markerHeight, markerBigPicLeft = (markerLeft - markerBigPicWidth/2 + markerWidth/2);