front_idill/src/mosaic/js/zoomInteractions.js
changeset 44 8393d3473b98
child 45 0e29ae4568a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/mosaic/js/zoomInteractions.js	Fri Jun 29 16:16:24 2012 +0200
@@ -0,0 +1,510 @@
+/*
+ * 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.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING") > -1 || snapshot == null || this.helpDisplayed || this.isMosaicFiltering)
+	{
+		return;
+	}
+	
+    if(this.fullscreen)
+	{
+        return;
+	}
+	this.preUnzoom();
+	//On enlève les notifications initiales si elles existent.
+	this.removeSelectionSearchMosaicFull();
+	
+    //Mosaïque.
+    var _this = 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.config['length'], imgs = this.config['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.config['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)
+	{
+		/*var currentSN = this.pointerPositionToSN(pointerX, pointerY);
+		if(currentSN != null && currentSN.attr('id') != snapshot.attr('id'))
+		{
+			this.preUnzoom();
+		}*/
+        // if($('#preZoomContainer-' + currentId) != $(this) && this.previousZoomedSN != '' && this.previousId != '')
+        /*if(this.previousZoomedSN.attr('id') !== snapshot.attr('id'))
+		{
+            this.preUnzoom();
+		}
+        else
+		{
+            return;
+		}*/
+		this.preUnzoom();
+		// 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 = '<img id="fake-' + currentId + '" class="snapshots" src="' + fakeImg.attr('src').replace('-little/', '/') + '" />';
+    //On génère un faux snapshot identique au précédent et qu'on va coller dessus.
+    var fakeSnapshot = '<div id="prezoomContainer-' + currentId + '" class="prezoomContainers"><div id="prezoomSnapshot-' + currentId + '" class="snapshotDivs">' + fakeImg + '</div></div>';
+    
+    //On l'ajoute à la mosaïque.
+    $('#mainPanel').append(fakeSnapshot);
+    //On modifie ses attributs.
+	// console.log('cid : ' + currentId, $('#fake-' + currentId).length);
+    $('#fake-' + currentId).load(function()
+    {
+	// snapshot.fadeTo(400, '0.5').delay(200).fadeTo(400, '1');
+		$('#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 = '<div id="red"></div>';
+        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.config['timePrezoom']);
+        $('#prezoomContainer-' + currentId).animate(
+        {
+            width: finalDivWidth + margin*2,
+            height: finalDivHeight - margin,
+            top: finalDivTop + margin,
+            left: finalDivLeft
+        }, _this.config['timePrezoom'], function()
+		{
+			//On met le spinner gif sur le pointeur, s'il n'existe pas déjà.
+			if($('#spinner').length == 0)
+			{
+				//On repère le pointeur ayant provoqué le prezoom.
+				var prezoomPointer;
+				if(!this.isMainPointerDisplayed)
+				{
+					prezoomPointer = $('#secondPointer');
+				}
+				if(!this.isSecondPointerDisplayed)
+				{
+					prezoomPointer = $('#mainPointer');
+				}
+				
+				var spinner = "<img id='spinner'></div>";
+				$('body').append(spinner);
+				$('#spinner').css(
+				{
+					position: 'absolute',
+					top: prezoomPointer.position().top,
+					left: prezoomPointer.position().left,
+					width: 85,
+					height: 85,
+					'z-index': 600
+				});
+				$('#spinner').attr('src', './img/cursors/selector_anim_2.gif');
+			}
+			
+			if(_this.currentMode == 'MOSAIC')
+			{
+				$('.notifications').remove();
+				_this.mosaicSelection();
+			}
+			else if(_this.currentMode == 'FILTER' && !_this.filterSearchedType)
+			{
+				$('.notifications').remove();
+				_this.filterSearchAndSelection();
+			}
+			else if(_this.currentMode == 'FILTER' && _this.filterSearchedType)
+			{
+				$('.notifications').remove();
+				_this.filterGestureAndSelection(_this.filterSearchedType, 'valid');
+			}
+		});
+		
+		
+    });
+    
+	this.zoomTimeout = setTimeout(function()
+	{
+		_this.zoom();
+	}, this.config['timeoutZoom']);
+    //Si on clique sur le snapshot prézoomé, on enclenche un zoom total sur ce snapshot.
+    /*$('#prezoomContainer-' + currentId).click(function ()
+    {
+        if(this.previousZoomedSN != '')
+		{
+            _this.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;
+	}*/
+	
+	/*if(this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING") > -1)
+	{
+		return;
+	}*/
+	
+	$('#spinner').remove();
+	
+	var _this = this;
+	
+	clearTimeout(this.zoomTimeout);
+	
+	if(this.currentMode == 'MOSAIC')
+	{
+		$('.notifications').remove();
+		this.mosaicSelectionAndSearch();
+	}
+	else if(_this.currentMode == 'FILTER' && !this.filterSearchedType)
+	{
+		$('.notifications').remove();
+		this.filterSearch();
+	}
+	else if(_this.currentMode == 'FILTER' && this.filterSearchedType)
+	{
+		$('.notifications').remove();
+		this.filterGesture(this.filterSearchedType, 'valid');
+	}
+	/*this.removePointMosaicPrezoom();
+	this.notifySelectionSearchMosaicFull();*/
+    
+    //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.
+	for(var i = 0 ; i < this.config['imagesToShow'] ; i++)
+	{
+		if($('#prezoomContainer-snapshot-' + i).length > 0)
+		{
+			$('#prezoomContainer-snapshot-' + i).animate(
+			{
+				width: this.snapshotWidth + margin,
+				height: this.snapshotHeight + margin,
+				top: $('#snapshotDiv-' + i).position().top,//this.previousZoomedSN.position().top,
+				left: $('#snapshotDiv-' + i).position().left//this.previousZoomedSN.position().left
+			}, this.config['preUnzoomTime'], function(){ $(this).remove(); _this.zoomed = false; });
+			$('#prezoomSnapshot-snapshot-' + i).animate(
+			{
+				width: this.snapshotWidth,
+				height: this.snapshotHeight,
+				top: $('#snapshotDiv-' + i).position().top,//this.previousZoomedSN.position().top,
+				left: $('#snapshotDiv-' + i).position().left//this.previousZoomedSN.position().left
+			}, this.config['preUnzoomTime']);
+		}
+	}
+	
+    /*$('#prezoomSnapshot-' + id).animate(
+    {
+        width: this.snapshotWidth,
+        height: this.snapshotHeight,
+        top: this.previousZoomedSN.position().top,
+        left: this.previousZoomedSN.position().left
+    }, this.config['preUnzoomTime']);
+    $('#prezoomContainer-' + id).animate(
+    {
+        width: this.snapshotWidth + margin,
+        height: this.snapshotHeight + margin,
+        top: this.previousZoomedSN.position().top,
+        left: this.previousZoomedSN.position().left
+    }, this.config['preUnzoomTime'], function(){ $(this).remove(); _this.zoomed = false; });*/
+}
+
+
+/*
+ * Zoom d'un snapshot en plein écran.
+ */
+mosaic.prototype.zoom = function()
+{
+    var _this = this;
+    
+    //Si la mosaïque est en pleine écran, pas la peine de zoomer.
+    if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH" || this.currentMode.indexOf("INCOMING") > -1 || this.helpDisplayed)
+	{
+        return;
+	}
+    
+    //On prend les attributs nécessaires au calculs.
+    var margin = this.marginWidth, len = this.config['length'], imgs = this.config['imagesToShow'], zoomedMargin = this.config['zoomedMargin'];
+	var zoomPercentage = this.config['zoomPercentage'];
+    var initMPWidth = this.previousZoomedSN.width() * len + margin*len, initMPHeight = this.previousZoomedSN.height() * (imgs / len) + margin*(imgs / len);
+    var newMPWidth = initMPWidth * len + zoomedMargin * (len), newMPHeight = initMPHeight * (imgs / len) + zoomedMargin * ((imgs / len));
+    var newPreMPWidth = initMPWidth * len * zoomPercentage + zoomedMargin * (len), newPreMPHeight = initMPHeight * (imgs / len) * zoomPercentage + 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 * (zoomPercentage+1), finalDivHeight = initialDivHeight * (zoomPercentage+1);
+    var newZoomTop = -this.previousZoomedSN.position().top*(newPreMPHeight/initMPHeight) - zoomedMargin/2 + (initMPHeight - initMPHeight * zoomPercentage)/2, newZoomLeft = -this.previousZoomedSN.position().left*(newPreMPWidth/initMPWidth) - zoomedMargin/2 + (initMPWidth - initMPWidth * zoomPercentage)/2;
+    var newSnWidth = initMPWidth * zoomPercentage, newSnHeight = initMPHeight * 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 = _this.previousId.split('-');
+    zoomedImgId = tab[1];
+	
+	//On donne les dimensions des snapshots.
+	$('.snapshotDivs').animate(
+	{
+		width: newSnWidth,
+		height: newSnHeight,
+		margin: zoomedMargin/2 + 'px',
+	}, this.config['zoomTime']);
+	
+	if(this.currentMode != 'NO-USER')
+	{
+		//Les snapshots baissent alors en opacité, donnant l'impression qu'ils sont grisés.
+		$('.snapshotDivs').animate(
+		{
+			opacity: '0.4'
+		}, this.config['zoomTime']);
+		//Le snapshot du milieu revient à une opacité optimale, ce qui attire l'attention de l'utilisateur.
+		$(this.previousZoomedSN).animate(
+		{
+			opacity: '1'
+		}, this.config['zoomTime']);
+	}
+	// console.log('BBB1 : ' + this.currentMode);
+    //On zoome sur la mosaïque.
+    $('#mainPanel').animate(
+    {
+        width: newPreMPWidth,
+        height: newPreMPHeight,
+        top: newZoomTop,
+        left: newZoomLeft
+    }, this.config['zoomTime'], function()
+    {
+        _this.snTop = (zoomedImg.position().top + newZoomTop + _this.MPTop_margin), _this.snLeft = (zoomedImg.position().left + newZoomLeft);
+		_this.snWidth = newSnWidth + 1, _this.snHeight = newSnHeight + 1;
+		
+		_this.notifyTopVideo = newZoomTop;
+		_this.notifyLeftVideo = newZoomLeft;
+		
+		//On charge les interactions avec les voisins.
+        _this.centerId = zoomedImgId;
+		// console.log('BBB2 : ' + _this.currentMode);
+		if(_this.currentMode != "NO-USER")
+		{
+			// console.log('PROBLEM');
+			_this.currentMode = 'VIDEO';
+			_this.listenToNeighbours();
+		}
+		
+		$('#spinner').remove();
+		$('#mainPointer').css('background-image', 'url(./img/cursors/pointer.png)');
+		$('#secondPointer').css('background-image', 'url(./img/cursors/pointer2.png)');
+		
+		// console.log('BBB3 : ' + _this.currentMode);
+		_this.loadPlayer(_this.snTop, _this.snLeft, _this.snWidth, _this.snHeight, newZoomTop, newZoomLeft, _this.timeToGoAt[_this.centerId]);
+    });
+}
+
+/*
+ * Retour à la taille normale de la mosaïque.
+ */
+mosaic.prototype.unzoom = function()
+{
+    //Si on n'est pas en plein écran, on quitte.
+	// console.log("'" + this.currentMode + "'");
+    if(this.currentMode != "SEARCH" && this.currentMode != "VIDEO" && this.currentMode != "NO-USER" && this.currentMode.indexOf("INCOMING") == -1)
+	{
+        return;
+	}
+	
+	this.canSwipe = false;
+	
+	//Si la TL avait été sélectionnée, on la déselectionne.
+	if(this.currentMode == 'TIMELINE')
+	{
+		this.exitTimeline('move');
+	}
+	
+	this.currentlyUnzooming = true;
+	
+	this.removeAdditionalNeighbours();
+	this.deselectAllNeighbours();
+	
+	this.snTop = 0;
+	this.snLeft = 0;
+	this.Width = 0;
+	this.snHeight = 0;
+    
+    //On charge les attributs nécessaires aux calculs.
+    var sWidth = this.snapshotWidth, sHeight = this.snapshotHeight;
+    var mpWidth = this.width, mpHeight = this.height;
+    var _this = 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/'));
+	
+	if(_this.player.widgets && _this.player.widgets[0])
+	{
+		// console.log(Math.floor(_this.player.popcorn.currentTime()));
+		_this.timeToGoAt[_this.centerId] = Math.floor(_this.player.popcorn.currentTime());
+		_this.player.widgets[0].freePlayer();
+	}
+	
+	_this.playerIsReady = false;
+	$('.LdtPlayer').remove();
+	$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
+	_this.reaffectKeyPress();
+    
+    //On rend leur opacité aux snapshots. Qui ne sont alors plus grisés.
+    $('.snapshotDivs').animate(
+    {
+        width: sWidth,
+        height: sHeight,
+        margin: this.marginWidth/2 + 'px'
+    }, this.config['unzoomTime'], function()
+	{
+		_this.neighboursIds.length = 0;
+		_this.currentlyUnzooming = false;
+	});
+	
+	if(this.currentMode != 'NO-USER')
+	{
+		if(this.currentMode.indexOf("INCOMING") == -1 && !this.isMosaicFiltered)
+		{
+			$('.snapshotDivs').animate(
+			{
+				opacity: '1'
+			}, this.config['unzoomTime']);
+		}
+		else if(this.currentMode.indexOf("INCOMING") == -1 && this.isMosaicFiltered)
+		{
+			for(var i = 0 ; i < this.config['imagesToShow'] ; i++)
+			{
+				$('#snapshotDiv-' + i).animate(
+				{
+					opacity: this.opacities[i]
+				}, this.config['unzoomTime']);
+			}
+		}
+	}
+	else
+	{
+		// console.log('init');
+		this.previousZoomedSN.fadeTo(this.config['unzoomTime'], 0, function()
+		{
+			_this.init();
+		});
+	}
+	
+    //On dézoom sur la mosaïque.
+    $('#mainPanel').animate(
+    {
+        width: mpWidth,
+        height: mpHeight,
+        top: '0px',
+        left: '0px'
+    }, this.config['unzoomTime'], function()
+    {
+        //On n'est plus en plein écran, et on ne peut plus se déplacer vers le prochain voisin.
+        _this.fullscreen = false;
+        _this.canMoveToNeighbour = false;
+		
+		if(_this.currentMode != 'NO-USER' && _this.currentMode.indexOf('INCOMING-') == -1)
+		{
+			if(_this.isMosaicFiltered)
+			{
+				//On revient en mode FILTER.
+				_this.currentMode = 'FILTER';
+			}
+			else
+			{
+				//On revient en mode MOSAIC.
+				_this.currentMode = 'MOSAIC';
+			}
+			
+			//On ne permet plus le déplacement vers les voisins.
+			/*$('.snapshotDivs').unbind('mouseover', function()
+			{
+				_this.selectNeighbour();
+			});*/
+			
+			//On remet les notifications initiales si on n'est pas dans une recherche par filtrage.
+			if(_this.currentMode == 'MOSAIC' && !_this.filterSearchedType)
+			{
+				$('.notifications').remove();
+				// _this.notifySelectionSearchMosaicFull();
+				_this.mosaicSelectionAndSearch();
+			}
+		}
+		
+		this.currentlyUnzooming = false;
+    });
+}
\ No newline at end of file