front_idill/src/mosaic/js/mosaic.js
changeset 77 205409da0f32
parent 58 a28488078053
child 79 9eff85166868
--- a/front_idill/src/mosaic/js/mosaic.js	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/mosaic/js/mosaic.js	Wed Aug 08 18:40:40 2012 +0200
@@ -26,7 +26,7 @@
  */
 function Mosaic(config, default_conf)
 {
-    this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "knee-up", "right-angle", "wave", "slow", "hello", "no-motion", "contact", "up-down", "grand-jete"];
+    this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "knee-up", "right-angle", "wave", "no-motion", "contact", "up-down", "grand-jete"];
 
     //Chemin du fichier de configuration.
     this.config_path = config;
@@ -108,6 +108,8 @@
     this.mousePosLastY = null;
     //Valeur du déplacement entre un mouse up et un mouse down.
     this.mouseUpDownDelta = 0;
+    //Valeur du déplacement entre un touch start et un touch end.
+    this.touchUpDownDelta = 0;
 	//Coordonnées de la souris au dernier mouse down.
 	this.mouseDownPosX = null;
 	this.mouseDownPosY = null;
@@ -187,7 +189,12 @@
     this.actualCode = '';
     //Indique si l'utilisateur est entré dans la zone de recherche.
     this.isUserInSearchZone = false;
+	//Indique si on a fait un mouse down.
 	this.isMouseDown = false;
+	//Indique si on a fait un touch start.
+	this.isTouchStart = false;
+	//Indique si on a fait un touch move.
+	this.isTouchMove = false;
 	//Indique si on est en train de prézoomer.
 	this.isPrezooming = false;
 	//Indique si l'icone d'aide a été agrandie.
@@ -196,6 +203,9 @@
 	this.isHelpIconZooming = false;
 	//Indique à l'utilisateur s'il doit retirer ses mains pour refaire une recherche par courbes.
 	this.mustTakeOutHands = false;
+	
+	//Indique si on est sur une tablette.
+	this.isTablet = ('ontouchstart' in document.documentElement);
     
     //Timeout (attente) pour le zoom après un préZoom.
     this.zoomTimeout = null;
@@ -303,7 +313,7 @@
 	//On recharge la fenêtre si sa taille a changé.
 	$(window).resize(function()
 	{
-		_.debounce(window.location.reload(), _this.config.timeReloadAfterResize);
+		// _.debounce(window.location.reload(), _this.config.timeReloadAfterResize);
 	});
 	
     var initPanel = '<div id="initPanel"></div>';
@@ -339,7 +349,7 @@
             }
         }
         
-        return str + '<div id="ghostPanel"></div>';
+        return str;
     }
     else
     {
@@ -348,313 +358,6 @@
 }
 
 /*
- * Fonction appelée lors d'un mouse down en mode d'interaction souris.
- * Est appelé dans le fichier :
- * mosaic > fonction loadMosaic, attachée à l'événement jQuery mousedown.
-*/
-Mosaic.prototype.onMouseDown = function(e)
-{
-	this.isMouseDown = true;
-	
-	//Si on se trouve sur l'icone d'aide et qu'elle est zoomée.
-	if(this.isHelpIconZoomed)
-	{
-		//On affiche différentes aides en fonction de si on se trouve dans une vidéo ou non.
-		if(this.currentMode == 'SEARCH' || this.currentMode == 'VIDEO' || this.currentMode == 'TIMELINE')
-		{
-			this.notifyHelp(false);
-		}
-		else if(this.currentMode == 'FILTER' || this.currentMode == 'MOSAIC')
-		{
-			this.notifyHelp(true);
-		}
-	}
-	
-	//On met à jour les coordonnées de la souris au dernier mouse down.
-	this.mouseDownPosX = e.pageX;
-	this.mouseDownPosY = e.pageY;
-	
-	//Si on est sur une notification de gesture de recherche.
-	this.removeSearchNotificationIfOnIt(e.pageX, e.pageY);
-	this.isUserInSearchZone = true;
-	
-	//Si on est en mode de tracé de courbes, on indique qu'on a commencé à tracer au canvas.
-	if(this.isSearchByCurvesOn)
-	{
-		this.searchCanvas.onPointerIn(this.mousePosX, this.mousePosY, null, null);
-	}
-}
-
-/*
- * Fonction appelée lors d'un mouse move en mode d'interaction souris.
- * Est appelé dans le fichier :
- * mosaic > fonction loadMosaic, attachée à l'événement jQuery mousemove.
-*/
-Mosaic.prototype.onMouseMove = function(e)
-{
-	//On vérifie si la souris n'est pas sur l'icone d'aide.
-	if(this.isOnHelpIcon(this.mousePosX, this.mousePosY))
-	{
-		//On agrandit l'icone d'aide.
-		this.showBigHelp();
-	}
-	else
-	{
-		//On la rétrecit sinon.
-		this.showSmallHelp();
-	}
-	
-	//Si on n'a pas appuyé sur la souris avant, on part.
-	if(!this.isMouseDown)
-	{
-		return;
-	}
-	
-	var _this = this;
-	
-	//Si on est en mode de tracé de courbes, on met à jour la courbe.
-	if(this.isSearchByCurvesOn)
-	{
-		this.searchCanvas.onPointerMove(this.mousePosX, this.mousePosY - this.MPTop_margin, null, null);
-	}
-	
-	//On met à jour l'ancienne position de la souris si elle est nulle.
-	if(!this.mousePosLastX && this.mousePosLastX != 0)
-	{
-		this.mousePosLastX = this.mousePosX;
-	}
-	if(!this.mousePosLastY && this.mousePosLastY != 0)
-	{
-		this.mousePosLastY = this.mousePosY;
-	}
-	
-	//Le delta s'accroît si la souris bouge.
-	this.mouseUpDownDelta += Math.floor(Math.sqrt((this.mousePosLastX - e.pageX) * (this.mousePosLastX - e.pageX) + (this.mousePosLastY - e.pageY) * (this.mousePosLastY - e.pageY)));
-	
-	//On met à jour l'ancienne position de la souris.
-	if(this.mousePosLastX != this.mousePosX)
-	{
-		this.mousePosLastX = this.mousePosX;
-	}
-	if(this.mousePosLastY != this.mousePosY)
-	{
-		this.mousePosLastY = this.mousePosY;
-	}
-	
-	//Si la souris a parcouru une trop grande distance, on entre en recherche.
-	if(this.mouseUpDownDelta > this.config.mouseUpDownDeltaTreshold)
-	{
-		//Si on est en mosaique, on entre en filtrage.
-		if(this.currentMode == "MOSAIC")
-		{
-			this.preUnzoom();
-			this.currentMode = "FILTER";
-			this.isMosaicFiltered = true;
-		}
-		//Si on est en mode de filtrage, mais qu'on n'est pas en tracé de courbes.
-		else if(this.currentMode == "FILTER" && !this.isSearchByCurvesOn && this.isUserInSearchZone)
-		{
-			//On lance une nouvelle recherche pas courbes.
-			this.preUnzoom();
-		}
-		//Si on est dans une vidéo, on entre en recherche.
-		else if(this.currentMode == "VIDEO" || this.currentMode == "TIMELINE")
-		{
-			this.currentMode = "SEARCH";
-		}
-		//Si on est en mode recherche dans une vidéo, mais qu'on n'est pas en tracé de courbes.
-		/*else if(this.currentMode == "SEARCH" && !this.isSearchByCurvesOn)
-		{
-			//On lance une nouvelle recherche pas courbes.
-		}*/
-		
-		if(this.currentMode != "NO-USER" && this.currentMode.indexOf("INCOMING") == -1 && !this.isSearchByCurvesOn)
-		{
-			this.isSearchByCurvesOn = true;
-			this.startSearch();
-			this.searchCanvas.onPointerIn(this.mousePosX, this.mousePosY - this.MPTop_margin, null, null);
-		}
-		
-		//S'il n'est pas possible d'afficher l'aide.
-		if(!this.canNotifyHelp)
-		{
-			//On rend son affichage possible après un certain délai.
-			this.canNotifyHelpTimeout = setTimeout(function()
-			{
-				_this.canNotifyHelp = true;
-			}, this.config.timeoutCanNotifyHelp);
-		}
-	}
-}
-
-/*
- * Fonction appelée lors d'un mouse up en mode d'interaction souris.
- * Est appelé dans le fichier :
- * mosaic > fonction loadMosaic, attachée à l'événement jQuery mousemove.
-*/
-Mosaic.prototype.onMouseUp = function()
-{
-	this.isMouseDown = false;
-	
-	//Si on était en train de tracer une courbe.
-	if(this.isSearchByCurvesOn)
-	{
-		//On quitte la zone de recherche.
-		/*this.isUserInSearchZone = false;
-		
-		//On regarde si ce qu'on a tracé correspond à une courbe en particulier.
-		var gesture_match = this.gestureWithSameCode(this.actualCode);
-		this.actualCode = '';
-		
-		//Si oui.
-		if(gesture_match.length > 0)
-		{
-			//Si on est en mode recherche dans une vidéo et que le player est prêt.
-			if(this.currentMode == "SEARCH" && this.playerIsReady)
-			{
-				//On effectue une recherche dans cette vidéo.
-				this.player.widgets[0].searchByGesture(gesture_match);
-				this.isCurrentlyInASearchByGesture = this.player.widgets[0].isCurrentlyInASearchByGesture;
-				
-				//On va au premier marqueur trouvé.
-				if(this.player && this.player.widgets[0] && this.timeToGoAt[this.centerId] === 0 && this.player.widgets[0].atLeastOneSearchMarker(this.currentSearchGesture[this.centerId]))
-				{
-					this.player.widgets[0].goToFirstSearchedMarker(this.currentSearchGesture[this.centerId]);
-				}
-				
-				//On affiche la notification de gesture de recherche.
-				this.removeNotifications();
-				this.currentSearchGesture[this.centerId] = gesture_match;
-				this.searchGesture(gesture_match, 'valid');
-				this.curvesGesturesFound = false;
-			}
-			//Si on est en mode de filtrage de mosaique.
-			else if(this.currentMode == "FILTER")
-			{
-				if(this.isMosaicFiltered)
-				{
-					//On notifie la recherche par filtrage.
-					this.removeNotifications();
-					this.filterSearchedType = gesture_match;
-					this.filterGesture(gesture_match, 'valid');
-					//On filtre la mosaique.
-					this.searchFilter(gesture_match);
-					this.curvesGesturesFound = false;
-				}
-			}
-		}
-		//Si aucune gesture ne matche dans le dictionnaire.
-		else
-		{
-			//Si on était en mode filtrage de la mosaïque et qu'aucune gesture de filtrage n'avait été détectée avant ca, on revient en mode mosaïque.
-			if(this.currentMode == "FILTER" && this.filterSearchedType == "")
-			{
-				this.currentMode = "MOSAIC";
-				this.isMosaicFiltered = false;
-			}
-			//Sinon si on était en mode recherche dans une video et qu'aucune gesture n'avait été détectée avant ca, on revient en mode video.
-			if(this.currentMode == "SEARCH" && this.currentSearchGesture[this.centerId] == "")
-			{
-				this.currentMode = "VIDEO";
-			}
-		}*/
-		//On dit au module de recherche qu'on arrête de tracer des courbes.
-		this.searchCanvas.onPointerOut();
-	}
-	
-	this.mousePosLastX = null;
-	this.mousePosLastY = null;
-	
-	//Si la distance parcourue par la souris entre le mouse down et le mouse up est inférieure ou égale au seuil.
-	if(this.mouseUpDownDelta <= this.config.mouseUpDownDeltaTreshold)
-	{
-		//Si on est sur un snapshot prézoomé.
-		if(this.isOnAPrezoomSN && this.previousZoomedSN != '' && (this.currentMode == 'MOSAIC' || this.currentMode == 'FILTER') && !this.isPrezooming)
-		{
-			this.zoom();
-		}
-	}
-	
-	//On réinitialise le delta, on quitte la recherche par courbes.
-	this.mouseUpDownDelta = 0;
-	this.isSearchByCurvesOn = false;
-	this.leaveSearch();
-	
-	//Si on est en mode de filtrage et qu'on a une gesture de filtrage trouvée.
-	if(this.currentMode == 'FILTER' && this.filterSearchedType != '')
-	{
-		//On notifie.
-		this.removeNotifications();
-		this.filterGesture(this.filterSearchedType, 'valid');
-	}
-}
-
-/*
- * Fonction appelée lors d'un clic en mode d'interaction souris.
- * Est appelé dans le fichier :
- * mosaic > fonction loadMosaic.
-*/
-Mosaic.prototype.onClick = function(x, y)
-{
-	//Si la position de la souris entre le mouse down et le mouse up change de plus de 10px, on part.
-	if(!this.mouseDownPosX || !this.mouseDownPosY || Math.sqrt((this.mouseDownPosX - x) * (this.mouseDownPosX - x) + (this.mouseDownPosY - y) * (this.mouseDownPosY - y)) > 10)
-	{
-		return;
-	}
-	
-	//Si on est dans un mode autre qu'un mode zoomé et qu'on n'affiche pas l'aide, on part.
-	if(this.currentMode != "VIDEO" && this.currentMode != "SEARCH" && this.currentMode != "TIMELINE" && !this.helpDisplayed)
-	{
-		return;
-	}
-	
-	//Si on clique en dehors de la video centrale, alors on dézoome.
-	var TL = $('.Ldt-Timeline');
-	var TLwidth = TL.width(), TLheight = TL.height();
-	var Ptop = $('.LdtPlayer').position().top, Pleft = $('.LdtPlayer').position().left;
-	var Pheight = $('.LdtPlayer').height();
-	var MPx = this.mousePosX, MPy = this.mousePosY;
-	
-	//On regarde si on a cliqué sur un snapshot.
-	var SN = this.pointerPositionToSN(MPx - this.notifyLeftVideo, MPy - this.notifyTopVideo, true);
-	var SNId;
-	if(SN)
-	{
-		SNId = parseInt(SN.attr('id').replace('snapshotDiv-', ''));
-	}
-	
-	//Si on n'a pas demandé à supprimé la notification de gesture.
-	if(!this.gestureDelRequested && !this.helpDisplayed)
-	{
-		//Si non, ou s'il ne fait pas partie des voisins.
-		if(!SNId || !_.include(this.neighboursIds, SNId))
-		{
-			//Si le clic a lieu en dehors du player et que l'aide n'est pas affichée, on dezoom.
-			if(MPx < Pleft || MPx > (+Pleft + TLwidth) || MPy < Ptop || MPy > (+Ptop + Pheight - TLheight))
-			{
-				this.unzoom();
-			}
-		}
-		//Si on se trouve sur un voisin, on bouge.
-		else if(SNId && _.include(this.neighboursIds, SNId) && this.canMoveToNeighbour)
-		{
-			this.moveToNeighbour($('#snapshotDiv-' + SNId));
-		}
-	}
-	//Si on l'a demandé, on enlève la demande de suppression.
-	else
-	{
-		this.gestureDelRequested = false;
-	}
-	
-	//Si l'aide est affichée, un clic la ferme.
-	if(this.helpDisplayed && !this.isHelpIconZoomed && !this.isHelpIconZooming)
-	{
-		this.removeHelp();
-	}
-}
-
-/*
  * Permet de raffraichir la mosaïque.
  * Est appelé dans le fichier :
  * mosaic > fonction loadFromJson, afin de charger la mosaique une fois que les fichiers de métadonnées ont été lus.
@@ -675,6 +378,8 @@
     this.previousZoomedSN;
     //On met à jour la mosaïque.
     $('#mainPanel').html(createMosaic);
+	//On ajoute le panneau de protection (principalement pour le mode tablettes).
+	$('body').append('<div id="ghostPanel"></div>');
     //On récupère la taille des bordures.
     this.marginWidth = $('.snapshotDivs').css('margin-bottom');
     this.marginWidth = parseFloat(this.marginWidth)*2;
@@ -683,7 +388,7 @@
     //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.config.imagesByLine - this.marginWidth;
     this.snapshotHeight = this.snapshotWidth*9/16;
-    $('.snapshotDivs').css('width', this.snapshotWidth).css('height', this.snapshotHeight).css('margin', this.marginWidth/2);
+    $('.snapshotDivs').css('width', this.snapshotWidth).css('height', this.snapshotHeight).css('margin-left', this.marginWidth/2);
     
     this.height = $('#mainPanel').innerHeight();
     //On centre verticalement la mosaïque.
@@ -730,14 +435,8 @@
                 //Si on gère les interactions à la souris.
                 if(_this.config.mouseInteractions)
                 {
-                    //On met à jour la position estimée de la souris.
-                    $(window).mousemove(function(e)
-                    {
-                        // _this.refreshPointers(e.pageX, e.pageY, _this, true);
-                        _this.refreshPointers(e.pageX, e.pageY, true);
-                        _this.mousePosX = e.pageX;
-                        _this.mousePosY = e.pageY;
-                    });
+					//On bind les événements utiles.
+					_this.eventBinder();
                 }
                 
                 //Si on a activé la préphase mais qu'on est en mode Kinect.
@@ -760,34 +459,94 @@
             }
         });
     }
-    
-    //Si on est en mode d'intéraction souris.
-    if(this.config.mouseInteractions)
-    {
-		//On affiche l'icone d'aide.
-		this.helpIcon();
-		
-        //Si on fait un mouse down sur le body, on vérifie enregistre le déplacement de la souris jusqu'au prochain mouse up.
-        $(window).mousedown(function (e)
-        {
+}
+
+/*
+ * Bind les événements souris ou touch dans le mode d'interaction souris.
+*/
+Mosaic.prototype.eventBinder = function()
+{
+	var _this = this;
+	
+	//On affiche l'icone d'aide.
+	this.helpIcon();
+	
+	//Si on est sur tablette, on utilise l'événement touch start.
+	if(this.isTablet)
+	{
+		document.addEventListener('touchstart', function(e)
+		{
+			if(e.touches.length == 1)
+			{
+				var touch = e.touches[0];
+				_this.onTouchStart(touch);
+			}
+			e.preventDefault();
+		}, false);
+	}
+	//Sinon souris.
+	else
+	{
+		//Si on fait un mouse down sur le body, on vérifie enregistre le déplacement de la souris jusqu'au prochain mouse up.
+		$(window).mousedown(function (e)
+		{
 			_this.onMouseDown(e);
 			return false;
-        });
-		
+		});
+	}
+	
+	//Si on est sur tablette, on utilise l'événement touch start.
+	if(this.isTablet)
+	{
+		document.addEventListener('touchmove', function(e)
+		{
+			if(e.touches.length == 1)
+			{
+				var touch = e.touches[0];
+				_this.refreshPointers(touch.pageX, touch.pageY, true);
+				_this.mousePosX = touch.pageX;
+				_this.mousePosY = touch.pageY;
+				_this.onTouchMove(touch);
+			}
+			e.preventDefault();
+		}, false);
+	}
+	//Sinon souris.
+	else
+	{
 		//On écoute le déplacement de la souris.
 		$(window).mousemove(function(e)
 		{
+			_this.refreshPointers(e.pageX, e.pageY, true);
+			_this.mousePosX = e.pageX;
+			_this.mousePosY = e.pageY;
 			_this.onMouseMove(e);
 			return false;
 		});
-		
+	}
+	
+	//Si on est sur tablette, on utilise l'événement touch start.
+	if(this.isTablet)
+	{
+		document.addEventListener('touchend', function(e)
+		{
+			_this.onTouchEnd(e);
+			e.preventDefault();
+		}, false);
+	}
+	//Sinon souris.
+	else
+	{
 		//Si on fait un mouse up après ce mouse down.
 		$(window).mouseup(function()
 		{
 			_this.onMouseUp();
 			return false;
 		});
-		
+	}
+	
+	if(!this.isTablet)
+	{
 		//Si on fait un clic.
 		$(window).click(function(e)
 		{
@@ -797,20 +556,20 @@
 		});
 		
 		$(window).on('mousewheel', function(event, delta, deltaX, deltaY)
-        {
+		{
 			//Si on est dans un mode autre qu'on mode zoomé ou que l'aide est affichée, on part.
 			if(_this.currentMode != "VIDEO" && _this.currentMode != "SEARCH" && _this.currentMode != "TIMELINE" || _this.helpDisplayed)
 			{
 				return;
 			}
 			
-            //Quand on "tire" la molette vers soi, on dezoom.
-            if (delta < 0)
-            {
-                _this.unzoom();
-            }
-        });
-    }
+			//Quand on "tire" la molette vers soi, on dezoom.
+			if (delta < 0)
+			{
+				_this.unzoom();
+			}
+		});
+	}
 }
 
 /*
@@ -823,7 +582,7 @@
     var _this = this;
     
     //Variables censées être des ints.
-    var supposedToBeInt = ['imagesByLine', 'imagesToShow', 'totalImages', 'timeReloadAfterResize', 'timePrezoom', 'timePreUnzoom', 'zoomTime', 'timeUnzoom', 'timeNeighbourGlowing', 'timeNeighbourUnglowing', 'timeMovingToNeighbour', 'timeSearchFade', 'timeNotifyFade', 'timeFilterFade', 'timeANFade', 'timeFilling', 'zoomedMargin', 'timeoutZoom', 'timeoutUnzoom', 'timeoutMoveToNeighbour', 'timeoutPointersIdle', 'timeoutAreBothPointersHere', 'timeoutRemoveNotificationByGesture', 'timeoutNotifySwipe', 'timeoutSelectTL', 'timeoutSlideTL', 'timeoutCanNotifyHelp', 'timeoutRemoveSpinner', 'timeoutNouser', 'timeoutNextDrawCurve', 'mouseUpDownDeltaTreshold', 'kinectUpDownDeltaTreshold', 'helpBorderSize'];
+    var supposedToBeInt = ['imagesByLine', 'imagesToShow', 'totalImages', 'timeReloadAfterResize', 'timePrezoom', 'timePreUnzoom', 'zoomTime', 'timeUnzoom', 'timeNeighbourGlowing', 'timeNeighbourUnglowing', 'timeMovingToNeighbour', 'timeSearchFade', 'timeNotifyFade', 'timeFilterFade', 'timeANFade', 'timeFilling', 'zoomedMargin', 'timeoutZoom', 'timeoutUnzoom', 'timeoutMoveToNeighbour', 'timeoutPointersIdle', 'timeoutAreBothPointersHere', 'timeoutRemoveNotificationByGesture', 'timeoutNotifySwipe', 'timeoutSelectTL', 'timeoutSlideTL', 'timeoutCanNotifyHelp', 'timeoutRemoveSpinner', 'timeoutNouser', 'timeoutNextDrawCurve', 'touchUpDownDeltaTreshold', 'mouseUpDownDeltaTreshold', 'kinectUpDownDeltaTreshold', 'helpBorderSize'];
     //Variables censées êtres des floats.
     var supposedToBeFloat = ['zoomPercentage', 'prezoomPercentage'];
     
@@ -1222,6 +981,12 @@
 {
 	var _this = this;
 	
+	//Si on est sur une tablette, on affiche les controls.
+	if(this.isTablet)
+	{
+		$('video').attr('controls', 'controls');
+	}
+	
 	if(this.currentMode == 'NO-USER')
 	{
 		//On peut s'approcher de la kinect.
@@ -1362,6 +1127,7 @@
         },
         player:{
             type: 'html5', // player type
+            // type: 'jwplayer', // player type
             video: videoToPlay,
             live: true,
             height: newSnHeight,
@@ -1376,7 +1142,8 @@
         position: 'absolute',
         'background-color': '#000000',
         top: newZoomTop,
-        left: newZoomLeft
+        left: newZoomLeft,
+		'z-index': 500
     });
     
     //On démarre le player.