front_idill/src/mosaic/js/mosaic.js
changeset 33 2d9b15f99b4e
parent 32 4003f84cd349
child 35 4267d6d27a7d
equal deleted inserted replaced
32:4003f84cd349 33:2d9b15f99b4e
    20 /*
    20 /*
    21  * Classe définissant la mosaïque.
    21  * Classe définissant la mosaïque.
    22  * Elle contient sa longueur, le nombre d'images total, une liste d'urls pour les vidéos, leurs snapshots principaux et leur position.
    22  * Elle contient sa longueur, le nombre d'images total, une liste d'urls pour les vidéos, leurs snapshots principaux et leur position.
    23  * Contient également les dimensions en px de la mosaïque.
    23  * Contient également les dimensions en px de la mosaïque.
    24  */
    24  */
    25 function mosaic(len, imgToShow, zoomPercentage, prezoomPercentage, zoomedMargin)
    25 function mosaic(len, imgToShow, imgTotal, zoomPercentage, prezoomPercentage, zoomedMargin)
    26 {
    26 {
    27     //S'il s'agit d'un rectangle.
    27     //S'il s'agit d'un rectangle.
    28     if(imgToShow % len == 0)
    28     if(imgToShow % len == 0)
    29     {
    29     {
    30         //Longueur horizontale.
    30         //Longueur horizontale.
    31         this.length = len;
    31         this.length = len;
    32         //Nombre d'images dans la mosaïque.
    32         //Nombre d'images dans la mosaïque.
    33         this.imagesToShow = imgToShow;
    33         this.imagesToShow = imgToShow;
       
    34 		this.imagesTotal = imgTotal;
    34         //Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque.
    35         //Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque.
    35         this.videos = [];
    36         this.videos = [];
    36         this.urls = [];
    37         this.urls = [];
    37         this.imgs = [];
    38         this.imgs = [];
    38         this.ids = [];
    39         this.ids = [];
       
    40 		//On remplit le tableau d'ids.
       
    41 		for(var i = 0 ; i < this.imagesTotal ; i++)
       
    42 			this.ids.push(i);
       
    43 		//On les mélange.
       
    44 		this.ids.sort(function()
       
    45 		{
       
    46 			return 0.5 - Math.random()
       
    47 		});
       
    48 		
       
    49 		console.log(this.ids);
       
    50 		
    39         //Dimensions de la mosaïque en pixels.
    51         //Dimensions de la mosaïque en pixels.
    40         this.width;
    52         this.width;
    41         this.height;
    53         this.height;
    42         //Dimensions d'un snapshot en pixels.
    54         //Dimensions d'un snapshot en pixels.
    43         this.snapshotWidth;
    55         this.snapshotWidth;
    51         this.zoomTime;
    63         this.zoomTime;
    52         this.unzoomTime;
    64         this.unzoomTime;
    53         this.timeNeighbourGlowing;
    65         this.timeNeighbourGlowing;
    54         this.timeNeighbourUnglowing;
    66         this.timeNeighbourUnglowing;
    55         this.timeMovingToNeighbour;
    67         this.timeMovingToNeighbour;
       
    68 		this.timeSearchFade;
       
    69 		this.timeNotifyFade;
    56         
    70         
    57         //Booléens permettant ou non certaines intéractions selon le contexte.
    71         //Booléens permettant ou non certaines intéractions selon le contexte.
    58         this.zoomed;
    72         this.zoomed;
    59         this.fullscreen;
    73         this.fullscreen;
    60         this.canMoveToNeighbour;
    74         this.canMoveToNeighbour;
       
    75 		this.helpDisplayed;
    61         
    76         
    62         //Mode actuel.
    77         //Mode actuel.
    63         this.currentMode;
    78         this.currentMode;
    64         //Snapshot sur lequel on a zoomé.
    79         //Snapshot sur lequel on a zoomé.
    65         this.previousZoomedSN;
    80         this.previousZoomedSN;
    78         //Position des voisins lors d'un zoom.
    93         //Position des voisins lors d'un zoom.
    79         this.neighboursIds = [];
    94         this.neighboursIds = [];
    80         //ID du snapshot du milieu lors d'un zoom.
    95         //ID du snapshot du milieu lors d'un zoom.
    81         this.centerId;
    96         this.centerId;
    82 		
    97 		
       
    98 		//Lecteur.
    83 		this.player;
    99 		this.player;
       
   100 		
       
   101 		//Coordonnées et dimensions d'un snapshot zoomé.
       
   102 		this.snTop = 0;
       
   103 		this.snLeft = 0;
       
   104 		this.snWidth = 0;
       
   105 		this.snHeight = 0;
       
   106 		
       
   107 		this.searchCanvas;
    84 		
   108 		
    85 		this.loadFromJson('./player/json/videos.json');
   109 		this.loadFromJson('./player/json/videos.json');
    86     }
   110     }
    87     else
   111     else
    88     {
   112     {
    98 {
   122 {
    99     this.previousZoomedSN = '';
   123     this.previousZoomedSN = '';
   100     this.previousPrezoomDiv = '';
   124     this.previousPrezoomDiv = '';
   101     this.fullscreen = false;
   125     this.fullscreen = false;
   102     this.canMoveToNeighbour = false;
   126     this.canMoveToNeighbour = false;
       
   127 	this.helpDisplayed = false;
   103     var str = '';
   128     var str = '';
   104     
   129     
   105     if(this.imgs.length >= this.imagesToShow)
   130     if(this.imgs.length >= this.imagesToShow)
   106     {
   131     {
   107         for(var i = 0 ; i < this.imagesToShow ; i++)
   132         for(var i = 0 ; i < this.imagesToShow ; i++)
   148     this.height = $('#mainPanel').innerHeight();
   173     this.height = $('#mainPanel').innerHeight();
   149     //On centre verticalement la mosaïque.
   174     //On centre verticalement la mosaïque.
   150     this.MPTop_margin = ($(document).height() - $('#mainPanel').height())/2;
   175     this.MPTop_margin = ($(document).height() - $('#mainPanel').height())/2;
   151     $('#mainPanel').css('margin-top', this.MPTop_margin).css('margin-bottom', this.MPTop_margin);
   176     $('#mainPanel').css('margin-top', this.MPTop_margin).css('margin-bottom', this.MPTop_margin);
   152 	
   177 	
       
   178 	//On affiche les notifications.
       
   179 	this.notifySelectionSearchMosaicFull();
       
   180 	
   153 	$('.snapshotDivs').mouseenter(function ()
   181 	$('.snapshotDivs').mouseenter(function ()
   154 	{
   182 	{
   155 		//On effectue un prézoom dès qu'on va sur une image.
   183 		//On effectue un prézoom dès qu'on va sur une image.
   156 		_this.preZoom($(this));
   184 		_this.preZoom($(this));
   157 	});
   185 	});
   173 {
   201 {
   174     if(this.fullscreen)
   202     if(this.fullscreen)
   175 	{
   203 	{
   176         return;
   204         return;
   177 	}
   205 	}
       
   206 	
       
   207 	//On enlève les notifications initiales si elles existent.
       
   208 	this.removeSelectionSearchMosaicFull();
       
   209 	
   178     //Mosaïque.
   210     //Mosaïque.
   179     var mosaic = this;
   211     var mosaic = this;
   180     //Dimensions de la mosaïque.
   212     //Dimensions de la mosaïque.
   181     var h = this.height, w = this.width;
   213     var h = this.height, w = this.width;
   182     //Longueur en images, nombre d'images et taille de bordure de la mosaïque.
   214     //Longueur en images, nombre d'images et taille de bordure de la mosaïque.
   270         {
   302         {
   271             width: finalDivWidth + margin*2,
   303             width: finalDivWidth + margin*2,
   272             height: finalDivHeight - margin,
   304             height: finalDivHeight - margin,
   273             top: finalDivTop + margin,
   305             top: finalDivTop + margin,
   274             left: finalDivLeft
   306             left: finalDivLeft
   275         }, this.preZoomTime);
   307         }, this.preZoomTime, function()
       
   308 		{
       
   309 			mosaic.notifyPointMosaicPrezoom();
       
   310 		});
   276     });
   311     });
   277     
   312     
   278     //Si on clique sur le snapshot prézoomé, on enclenche un zoom total sur ce snapshot.
   313     //Si on clique sur le snapshot prézoomé, on enclenche un zoom total sur ce snapshot.
   279     $('#prezoomContainer-' + currentId).click(function ()
   314     $('#prezoomContainer-' + currentId).click(function ()
   280     {
   315     {
   293     //Si on n'a pas zoomé, on quitte la fonction.
   328     //Si on n'a pas zoomé, on quitte la fonction.
   294     if(!this.zoomed)
   329     if(!this.zoomed)
   295 	{
   330 	{
   296         return;
   331         return;
   297 	}
   332 	}
       
   333 	
       
   334 	this.removePointMosaicPrezoom();
   298     
   335     
   299     //On spécifie la marge afin de centrer le prédézoom.
   336     //On spécifie la marge afin de centrer le prédézoom.
   300     var margin = this.marginWidth;
   337     var margin = this.marginWidth;
   301     //ID du snapshot précédemment pointé.
   338     //ID du snapshot précédemment pointé.
   302     var id = this.previousId;
   339     var id = this.previousId;
   330     //Si la mosaïque est en pleine écran, pas la peine de zoomer.
   367     //Si la mosaïque est en pleine écran, pas la peine de zoomer.
   331     if(this.fullscreen)
   368     if(this.fullscreen)
   332 	{
   369 	{
   333         return;
   370         return;
   334 	}
   371 	}
       
   372 	
       
   373 	this.removePointMosaicPrezoom();
   335     
   374     
   336     //On prend les attributs nécessaires au calculs.
   375     //On prend les attributs nécessaires au calculs.
   337     var margin = this.marginWidth, len = this.length, imgs = this.imagesToShow;
   376     var margin = this.marginWidth, len = this.length, imgs = this.imagesToShow;
   338     var initMPWidth = this.previousZoomedSN.width() * len + margin*len, initMPHeight = this.previousZoomedSN.height() * (imgs / len) + margin*(imgs / len);
   377     var initMPWidth = this.previousZoomedSN.width() * len + margin*len, initMPHeight = this.previousZoomedSN.height() * (imgs / len) + margin*(imgs / len);
   339     var newMPWidth = initMPWidth * len + this.zoomedMargin * (len), newMPHeight = initMPHeight * (imgs / len) + this.zoomedMargin * ((imgs / len));
   378     var newMPWidth = initMPWidth * len + this.zoomedMargin * (len), newMPHeight = initMPHeight * (imgs / len) + this.zoomedMargin * ((imgs / len));
   387         mos.centerId = zoomedImgId;
   426         mos.centerId = zoomedImgId;
   388         mos.listenToNeighbours();
   427         mos.listenToNeighbours();
   389         mos.currentMode = 'VIDEO';
   428         mos.currentMode = 'VIDEO';
   390 		
   429 		
   391 		console.log('h : ' + -newZoomLeft + " " + zoomedImg.position().left);
   430 		console.log('h : ' + -newZoomLeft + " " + zoomedImg.position().left);
   392 		
   431 
   393 		mos.loadPlayer((zoomedImg.position().top + newZoomTop + mos.MPTop_margin), (zoomedImg.position().left + newZoomLeft), newSnWidth + 1, newSnHeight + 1);
   432 		mos.snTop = (zoomedImg.position().top + newZoomTop + mos.MPTop_margin), mos.snLeft = (zoomedImg.position().left + newZoomLeft);
       
   433 		mos.snWidth = newSnWidth + 1, mos.snHeight = newSnHeight + 1;
       
   434 		
       
   435 		mos.loadPlayer(mos.snTop, mos.snLeft, mos.snWidth, mos.snHeight, newZoomTop, newZoomLeft);
   394 		
   436 		
   395         /*mos.unload();
   437         /*mos.unload();
   396         mos.localMos.loadLocalMosaic(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, mos.imgs, tab[1]);*/
   438         mos.localMos.loadLocalMosaic(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, mos.imgs, tab[1]);*/
   397     });
   439     });
   398 }
   440 }
   399 
   441 
   400 /*
   442 /*
   401  * Chargement du player basé sur le metadataplayer.
   443  * Chargement du player basé sur le metadataplayer.
   402 */
   444 */
   403 mosaic.prototype.loadPlayer = function(newZoomTop, newZoomLeft, newSnWidth, newSnHeight)
   445 mosaic.prototype.loadPlayer = function(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, zoomTop, zoomLeft)
   404 {
   446 {
   405 	//On configure les options de lancement.
   447 	//On configure les options de lancement.
   406 	IriSP.libFiles.defaultDir = "../lib/";
   448 	IriSP.libFiles.defaultDir = "../lib/";
   407 	IriSP.widgetsDir = "./player/metadataplayer/"
   449 	IriSP.widgetsDir = "./player/metadataplayer/"
   408 	
   450 	
   409 	var videoToPlay = this.videos[this.centerId];
   451 	var videoToPlay = this.videos[this.centerId];
   410 	var currentMetadata = this.urls[this.centerId];
   452 	var currentMetadata = this.urls[this.centerId];
   411 	console.log('VIDEO[' + this.centerId + '] : ' + videoToPlay);
   453 	console.log('VIDEO[' + this.centerId + '] : ' + videoToPlay);
   412 	console.log('MD[' + this.centerId + '] : ' + currentMetadata);
   454 	console.log('MD[' + this.centerId + '] : ' + currentMetadata);
   413 	
   455 	
   414 	console.log(newZoomTop + " " + newZoomLeft);
       
   415 	
       
   416 	var _metadata = {
   456 	var _metadata = {
   417 		url: currentMetadata,
   457 		url: currentMetadata,
   418 		format: 'ldt'
   458 		format: 'ldt'
   419 	};
   459 	};
       
   460 	console.log(zoomTop + " m" + this.marginWidth);
   420 	var _config = {
   461 	var _config = {
   421 		gui: {
   462 		gui: {
       
   463 			zoomTop: zoomTop - this.marginWidth*2,
       
   464 			zoomLeft: zoomLeft,
   422 			width: newSnWidth,
   465 			width: newSnWidth,
   423 			height: newSnHeight,
   466 			height: newSnHeight,
   424 			container: 'LdtPlayer',
   467 			container: 'LdtPlayer',
   425 			default_options: {
   468 			default_options: {
   426 				metadata: _metadata
   469 				metadata: _metadata
   465     //Si on n'est pas en plein écran, on quitte.
   508     //Si on n'est pas en plein écran, on quitte.
   466     if(!this.fullscreen)
   509     if(!this.fullscreen)
   467 	{
   510 	{
   468         return;
   511         return;
   469 	}
   512 	}
       
   513 	
       
   514 	this.snTop = 0;
       
   515 	this.snLeft = 0;
       
   516 	this.Width = 0;
       
   517 	this.snHeight = 0;
   470     
   518     
   471     //On charge les attributs nécessaires aux calculs.
   519     //On charge les attributs nécessaires aux calculs.
   472     var sWidth = this.snapshotWidth, sHeight = this.snapshotHeight;
   520     var sWidth = this.snapshotWidth, sHeight = this.snapshotHeight;
   473     var mpWidth = this.width, mpHeight = this.height;
   521     var mpWidth = this.width, mpHeight = this.height;
   474     var mos = this;
   522     var mos = this;
   476     //On passe le snapshot sur lequel on a zoomé en SD.
   524     //On passe le snapshot sur lequel on a zoomé en SD.
   477     var zoomedImg = $('img', this.previousZoomedSN);
   525     var zoomedImg = $('img', this.previousZoomedSN);
   478     var src = zoomedImg.attr('src');
   526     var src = zoomedImg.attr('src');
   479     zoomedImg.attr('src', src.replace('snapshots/', 'snapshots-little/'));
   527     zoomedImg.attr('src', src.replace('snapshots/', 'snapshots-little/'));
   480 	
   528 	
   481 	$('div').remove('.LdtPlayer');
   529 	mos.player.widgets[0].freePlayer();
       
   530 	$('.LdtPlayer').remove();
   482 	$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
   531 	$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
   483     
   532     
   484     //On rend leur opacité aux snapshots. Qui ne sont alors plus grisés.
   533     //On rend leur opacité aux snapshots. Qui ne sont alors plus grisés.
   485     $('.snapshotDivs').animate(
   534     $('.snapshotDivs').animate(
   486     {
   535     {
   503         mos.canMoveToNeighbour = false;
   552         mos.canMoveToNeighbour = false;
   504         //On revient en mode MOSAIC.
   553         //On revient en mode MOSAIC.
   505         mos.currentMode = 'MOSAIC';
   554         mos.currentMode = 'MOSAIC';
   506         //On ne permet plus le déplacement vers les voisins.
   555         //On ne permet plus le déplacement vers les voisins.
   507         $('.snapshotDivs').unbind('mouseenter', mos.selectNeighbour);
   556         $('.snapshotDivs').unbind('mouseenter', mos.selectNeighbour);
       
   557 		//On remet les notifications initiales.
       
   558 		mos.notifySelectionSearchMosaicFull();
   508     });
   559     });
   509 }
   560 }
   510 
   561 
   511 /*
   562 /*
   512  * Affecte les listeners mouseenter aux voisins lors d'une vue en plein écran.
   563  * Affecte les listeners mouseenter aux voisins lors d'une vue en plein écran.
   689     var tab = neighbourFrame.attr('id').split('-');
   740     var tab = neighbourFrame.attr('id').split('-');
   690     mos.centerId = tab[1];
   741     mos.centerId = tab[1];
   691     $(this).css('opacity', '0');
   742     $(this).css('opacity', '0');
   692     neighbourFrame.remove();
   743     neighbourFrame.remove();
   693     
   744     
   694 	$('div').remove('.LdtPlayer');
   745 	mos.player.widgets[0].freePlayer();
       
   746 	$('.LdtPlayer').remove();
   695 	$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
   747 	$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
   696 	
   748 	
   697     //On grise le snapshot qu'on vient de quitter.
   749     //On grise le snapshot qu'on vient de quitter.
   698     mos.previousZoomedSN.animate(
   750     mos.previousZoomedSN.animate(
   699     {
   751     {
   716             //On recharge les voisins.
   768             //On recharge les voisins.
   717             $('.snapshotDivs').unbind('mouseenter', mos.selectNeighbour);
   769             $('.snapshotDivs').unbind('mouseenter', mos.selectNeighbour);
   718             mos.previousZoomedSN = $('#snapshotDiv-' + mos.centerId);
   770             mos.previousZoomedSN = $('#snapshotDiv-' + mos.centerId);
   719             mos.listenToNeighbours();
   771             mos.listenToNeighbours();
   720 			
   772 			
   721 			mos.loadPlayer((destinationImg.position().top + MPCurrentTop + mos.MPTop_margin), (destinationImg.position().left + MPCurrentLeft), destinationImg.width(), destinationImg.height());
   773 			mos.loadPlayer((destinationImg.position().top + MPCurrentTop + mos.MPTop_margin), (destinationImg.position().left + MPCurrentLeft), destinationImg.width(), destinationImg.height(), MPCurrentTop, MPCurrentLeft);
   722         });
   774         });
   723     });
   775     });
   724 }
   776 }
   725 
   777 
   726 /*
   778 /*
   774  * Charge les vidéos, les snapshots et les annotations depuis un fichier json.
   826  * Charge les vidéos, les snapshots et les annotations depuis un fichier json.
   775 */
   827 */
   776 mosaic.prototype.loadFromJson = function(path)
   828 mosaic.prototype.loadFromJson = function(path)
   777 {
   829 {
   778 	var _this = this;
   830 	var _this = this;
       
   831 	var i = 0;
   779 
   832 
   780 	$.getJSON(path, function(data)
   833 	$.getJSON(path, function(data)
   781 	{
   834 	{
   782 		$.each(data, function(key, val)
   835 		$.each(data, function(key, val)
   783 		{
   836 		{
   784 			// console.log(val);
   837 			// console.log(val);
   785 			$.each(val, function(key_video, val_video)
   838 			$.each(val, function(key_video, val_video)
   786 			{
   839 			{
   787 				$.getJSON(val_video.metadata, function(meta)
   840 				$.getJSON(val_video.metadata, function(meta)
   788 				{
   841 				{
   789 					_this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/'));
   842 					_this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/').replace('mp4:', '').replace('.m4v', '.mp4'));
   790 					//console.log(meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/'));
   843 					//console.log(meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/'));
   791 				});
   844 				});
   792 				
   845 				
   793 				_this.imgs.push(val_video.snapshot);
   846 				// _this.imgs.push(val_video.snapshot);
   794 				_this.urls.push(val_video.metadata);
   847 				// _this.urls.push(val_video.metadata);
       
   848 				_this.imgs[_this.ids[i]] = val_video.snapshot;
       
   849 				_this.urls[_this.ids[i]] = val_video.metadata;
       
   850 				i++;
   795 			});
   851 			});
   796 		});
   852 		});
   797 		console.log('rdy');
   853 		console.log('rdy');
   798 		_this.loadMosaic();
   854 		_this.loadMosaic();
   799 	});
   855 	});
   811 			this.videos[i] = video;
   867 			this.videos[i] = video;
   812 			break;
   868 			break;
   813 		}
   869 		}
   814 	}
   870 	}
   815 }
   871 }
       
   872 
       
   873 /*
       
   874  * Lance une recherche par courbes.
       
   875  */
       
   876 mosaic.prototype.startSearch = function()
       
   877 {
       
   878 	var top, left, width, height, margin_top, inMosaic;
       
   879 	//Si on est dans le cas d'un filtrage de mosaïque.
       
   880 	if(this.currentMode == "FILTER")
       
   881 	{
       
   882 		var mainPanel = $('#mainPanel');
       
   883 		top = mainPanel.position().top;
       
   884 		left = mainPanel.position().left;
       
   885 		width = mainPanel.width();
       
   886 		height = mainPanel.height();
       
   887 		margin_top = this.MPTop_margin;
       
   888 		inMosaic = true;
       
   889 	}
       
   890 	//Sinon si c'est une recherche dans la vidéo.
       
   891 	else if(this.currentMode == "SEARCH")
       
   892 	{
       
   893 		top = this.snTop;
       
   894 		left = this.snLeft;
       
   895 		width = this.snWidth;
       
   896 		height = this.snHeight;
       
   897 		margin_top = '0px';
       
   898 		inMosaic = false;
       
   899 	}
       
   900 	
       
   901 	this.searchCanvas = new searchCanvas(top, left, width, height, margin_top, this.timeSearchFade, inMosaic);
       
   902 	this.searchCanvas.create();
       
   903 }
       
   904 
       
   905 /*
       
   906  * Quitte une recherche par courbes.
       
   907  */
       
   908 mosaic.prototype.leaveSearch = function()
       
   909 {
       
   910 	this.searchCanvas.leaveSearch();
       
   911 }
       
   912 
       
   913 /* ===============================================
       
   914  *												   *
       
   915  *		      ZONE DES NOTIFICATIONS			   *
       
   916  *												   *
       
   917    =============================================== */
       
   918 
       
   919 /*
       
   920  * Affiche la notification de sélection/recherche lorsque la mosaique est complète.
       
   921 */
       
   922 mosaic.prototype.notifySelectionSearchMosaicFull = function()
       
   923 {
       
   924 	//On spécifie les notifications en div.
       
   925 	var notification_selection = "<div id='notify_selection' class='notifications'></div>";
       
   926 	var notification_search = "<div id='notify_search' class='notifications'></div>";
       
   927 	
       
   928 	//On les ajoute à la mosaïque.
       
   929 	$('#mainPanel').append(notification_selection + notification_search);
       
   930 
       
   931 	//On calcule leurs coordonnées et dimensions.
       
   932 	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
       
   933 	var notify_margin = parseInt($('.notifications').css('margin'));
       
   934 	var selection_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
       
   935 	var search_left = selection_left + notify_width + notify_margin;
       
   936 	
       
   937 	//On les positionne.
       
   938 	$('#notify_selection').css(
       
   939 	{
       
   940 		left: selection_left
       
   941 	});
       
   942 	$('#notify_search').css(
       
   943 	{
       
   944 		left: search_left
       
   945 	});
       
   946 	
       
   947 	//On les fait apparaître.
       
   948 	$('.notifications').css(
       
   949 	{
       
   950 		opacity: "0.9"
       
   951 	});
       
   952 }
       
   953 
       
   954 /*
       
   955  * Supprime la notification de sélection/recherche lorsque la mosaique est complète.
       
   956 */
       
   957 mosaic.prototype.removeSelectionSearchMosaicFull = function()
       
   958 {
       
   959 	$('#notify_selection, #notify_search').remove();
       
   960 }
       
   961 
       
   962 /*
       
   963  * Affiche la notification de maintient du pointage lors d'une phase de prézoom.
       
   964 */
       
   965 mosaic.prototype.notifyPointMosaicPrezoom = function()
       
   966 {
       
   967 	if($('#notify_point').length > 0)
       
   968 	{
       
   969 		return;
       
   970 	}
       
   971 	
       
   972 	//On spécifie les notifications en div.
       
   973 	var notification_point = "<div id='notify_point' class='notifications'></div>";
       
   974 	
       
   975 	//On les ajoute à la mosaïque.
       
   976 	$('#mainPanel').append(notification_point);
       
   977 	console.log('Append');
       
   978 	//On calcule leurs coordonnées et dimensions.
       
   979 	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
       
   980 	var notify_margin = parseInt($('.notifications').css('margin'));
       
   981 	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
       
   982 	
       
   983 	//On les positionne.
       
   984 	$('#notify_point').css(
       
   985 	{
       
   986 		left: point_left
       
   987 	});
       
   988 	
       
   989 	//On les fait apparaître.
       
   990 	$('.notifications').css(
       
   991 	{
       
   992 		opacity: "0.9"
       
   993 	});
       
   994 }
       
   995 
       
   996 /*
       
   997  * Supprime la notification de maintient du pointage.
       
   998 */
       
   999 mosaic.prototype.removePointMosaicPrezoom = function()
       
  1000 {	
       
  1001 	$('#notify_point').remove();
       
  1002 }
       
  1003 
       
  1004 /*
       
  1005  * Affiche l'aide.
       
  1006 */
       
  1007 mosaic.prototype.notifyHelp = function()
       
  1008 {
       
  1009 	if(this.helpDisplayed)
       
  1010 	{
       
  1011 		return;
       
  1012 	}
       
  1013 	
       
  1014 	this.removeSelectionSearchMosaicFull();
       
  1015 	this.removePointMosaicPrezoom();
       
  1016 	
       
  1017 	this.helpDisplayed = true;
       
  1018 	
       
  1019 	var search_2hands_tab = ['no_motion', 'right_angle', 'contact', 'grand_jete', 'circle', 'screw', 'arc', 'rythme', 'slow', 'up_down', 'wave', 'wheel'];
       
  1020 	var search_body_tab = ['bend', 'fall', 'jump', 'hello', 'knee_up'];
       
  1021 	var controls_1hand_tab = ['selection'];
       
  1022 	
       
  1023 	//On spécifie les notifications en div.
       
  1024 	var search_title = "<div id='search_title'></div>";
       
  1025 	var search_img = "<div id='search_img' class='notify_imgs'></div>";
       
  1026 	var search_2hands_text = "<div id='search_2hands_text'></div>";
       
  1027 	var search_2hands_imgs = "<div id='search_2hands_imgs' class='notify_imgs_big'>";
       
  1028 	
       
  1029 	for(var i = 0 ; i < search_2hands_tab.length ; i++)
       
  1030 	{
       
  1031 		search_2hands_imgs += "<div id='2hands_" + search_2hands_tab[i] + "' class='notify_imgs_small'></div>";
       
  1032 	}
       
  1033 	search_2hands_imgs += "</div>";
       
  1034 	
       
  1035 	var search_body_text = "<div id='search_body_text'></div>";
       
  1036 	var search_body_imgs = "<div id='search_2hands_imgs' class='notify_imgs'>"
       
  1037 	
       
  1038 	for(var i = 0 ; i < search_body_tab.length ; i++)
       
  1039 	{
       
  1040 		search_body_imgs += "<div id='body_" + search_body_tab[i] + "' class='notify_imgs_small'></div>";
       
  1041 	}
       
  1042 	search_body_imgs += "</div>";
       
  1043 	
       
  1044 	var controls_title = "<div id='controls_title'></div>";
       
  1045 	var controls_img = "<div id='controls_img' class='notify_imgs'></div>";
       
  1046 	var controls_1hand_text = "<div id='controls_1hand_text'></div>";
       
  1047 	var controls_1hand_imgs = "<div id='controls_1hand_imgs' class='notify_imgs'>";
       
  1048 	
       
  1049 	for(var i = 0 ; i < controls_1hand_tab.length ; i++)
       
  1050 	{
       
  1051 		controls_1hand_imgs += "<div id='1hand_" + controls_1hand_tab[i] + "' class='notify_imgs_small'></div>";
       
  1052 	}
       
  1053 	controls_1hand_imgs += "</div>";
       
  1054 	
       
  1055 	var help_search = "<div id='help_search'>" + search_title + search_img + search_2hands_text + search_2hands_imgs + search_body_text + search_body_imgs + "</div>";
       
  1056 	var help_controls = "<div id='help_controls'>" + controls_title + controls_img + controls_1hand_text + controls_1hand_imgs + "</div>";
       
  1057 	
       
  1058 	var notification_help = "<div id='notify_help'>" + help_search + "<div id='help_sep'></div>" + help_controls + "</div>";
       
  1059 	
       
  1060 	//On les ajoute à la mosaïque.
       
  1061 	$('body').append(notification_help);
       
  1062 	
       
  1063 	//On calcule leurs coordonnées et dimensions.
       
  1064 	var notify_width = $(window).width(), notify_height = $(window).height();
       
  1065 	var notify_margin = parseInt($('#notify_help').css('margin'));
       
  1066 	var notify_ = 10;
       
  1067 	
       
  1068 	//On les positionne.
       
  1069 	$('#notify_help').css(
       
  1070 	{
       
  1071 		left: "0px",
       
  1072 		top: "0px",
       
  1073 		width: notify_width - notify_margin * 2,
       
  1074 		height: notify_height - notify_margin * 2,
       
  1075 		"margin-top": notify_margin_top
       
  1076 	});
       
  1077 	
       
  1078 	var search_width = $('#help_search').width();
       
  1079 	
       
  1080 	$('#search_title').html('Recherche');
       
  1081 	$('#search_2hands_text').html('Gestes à effectuer avec les deux mains');
       
  1082 	$('#search_body_text').html('Gestes à effectuer avec le corps entier');
       
  1083 	
       
  1084 	for(var i = 0 ; i < search_2hands_tab.length ; i++)
       
  1085 	{
       
  1086 		$("#2hands_" + search_2hands_tab[i]).css("background-image", "url('./pictos/help/" + search_2hands_tab[i] + ".png')");
       
  1087 		//console.log("url('../../pictos/help/" + search_2hands_tab[i] + ".png')");
       
  1088 	}
       
  1089 	
       
  1090 	for(var i = 0 ; i < search_body_tab.length ; i++)
       
  1091 	{
       
  1092 		$("#body_" + search_body_tab[i]).css("background-image", "url('./pictos/help/" + search_body_tab[i] + ".png')");
       
  1093 		//console.log("url('../../pictos/help/" + search_2hands_tab[i] + ".png')");
       
  1094 	}
       
  1095 	
       
  1096 	$('#controls_title').html('Contrôles');
       
  1097 	$('#controls_1hand_text').html('Gestes à effectuer avec une seule main');
       
  1098 	
       
  1099 	for(var i = 0 ; i < controls_1hand_tab.length ; i++)
       
  1100 	{
       
  1101 		$("#1hand_" + controls_1hand_tab[i]).css("background-image", "url('./pictos/help/" + controls_1hand_tab[i] + ".png')");
       
  1102 		//console.log("url('../../pictos/help/" + search_2hands_tab[i] + ".png')");
       
  1103 	}
       
  1104 	
       
  1105 	//On les fait apparaître.
       
  1106 	$('#notify_help').css(
       
  1107 	{
       
  1108 		opacity: "1"
       
  1109 	});
       
  1110 	
       
  1111 	$('.notify_imgs_big').css(
       
  1112 	{
       
  1113 		opacity: "1"
       
  1114 	});
       
  1115 }
       
  1116 
       
  1117 /*
       
  1118  * Supprime l'aide.
       
  1119 */
       
  1120 mosaic.prototype.removeHelp = function()
       
  1121 {
       
  1122 	if(!this.helpDisplayed)
       
  1123 	{
       
  1124 		return;
       
  1125 	}
       
  1126 	
       
  1127 	var _this = this;
       
  1128 	
       
  1129 	$('#notify_help').fadeOut(this.timeNotifyFade, function()
       
  1130 	{
       
  1131 		_this.helpDisplayed = false;
       
  1132 		$('#notify_help').remove();
       
  1133 	});
       
  1134 }