--- a/front_idill/src/mosaic/js/mosaic.js Mon Jul 23 10:52:41 2012 +0200
+++ b/front_idill/src/mosaic/js/mosaic.js Mon Jul 23 16:59:35 2012 +0200
@@ -21,291 +21,584 @@
* 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.
+ * Est appelé dans :
+ * la page d'index, afin de créer la mosaique.
*/
-function mosaic(config, default_conf)
+function Mosaic(config, default_conf)
{
- //Interactions souris/kinect.
- this.mouseInteractions = true;
- //Interactions avec/sans préphase.
- this.prephaseEnabled = true;
-
- this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "pendulum", "knee-up", "right-angle", "wave", "slow", "hello", "no-motion", "wheel", "contact", "run", "up-down", "grand-jete"];
+ this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "pendulum", "knee-up", "right-angle", "wave", "slow", "hello", "no-motion", "wheel", "contact", "run", "up-down", "grand-jete"];
- //Chemin du fichier de configuration.
- this.config_path = config;
- //Configuration par défaut en cas de valeur erronnée.
- this.default_config = default_conf;
- this.config = new Object();
- //Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque.
- this.videos = [];
- this.urls = [];
- this.sources = [];
- this.imgs = [];
- this.opacities = [];
- this.timeToGoAt = [];
- this.ids = [];
- this.fillingIds = [];
- this.currentRandomVideoIdx = 0;
-
- //Dictionnaire pour les courbes de recherche.
- this.dictionary = [];
-
- //Dernières positions des pointeurs.
- this.mainPointerLastX;
- this.mainPointerLastY;
- this.secondPointerLastX;
- this.secondPointerLastY;
- //Dernières positions avant le lancement de la fonction d'idle.
- this.mainPointerIdleStartX;
- this.mainPointerIdleStartY;
- this.secondPointerIdleStartX;
- this.secondPointerIdleStartY;
-
- //Coordonnées de la souris dans le mode d'interaction souris.
- this.mousePosX;
- this.mousePosY;
- //Coordonnées précédentes de la souris dans le mode d'interaction souris.
- this.mousePosLastX;
- this.mousePosLastY;
- //Valeur du déplacement entre un mouse up et un mouse down.
- this.mouseUpDownDelta = 0;
-
- //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;
-
- //Booléens permettant ou non certaines intéractions selon le contexte.
- this.zoomed = false;
- this.fullscreen = false;
- this.canMoveToNeighbour = false;
- this.mainPointerExitBorder = false;
- this.secondPointerExitBorder = false;
- this.isMainPointerDisplayed = false;
- this.isSecondPointerDisplayed = false;
- this.helpDisplayed = false;
- //Indique si l'utilisateur a manuellement pausé la vidéo.
- this.userPaused = false;
- //Indique si on est en train de se déplacer vers un voisin.
- this.currentlyMoving = false;
- //Indique si on est en train de dézoomer vers la mosaïque.
- this.currentlyUnzooming = false;
- //Indique si on peut s'approcher de kinect.
- this.canStart = false;
- //Indique si on est actuellement sur un snapshot.
- this.isOnASnapshot = false;
- //Indique si l'idle des pointeurs est disponible (deux mains détectées).
- this.pointersIdleAvailable = false;
- //Indique si le timeout pour l'idle des pointeurs à besoin d'être lancé.
- this.pointersIdleNeedLaunch = false;
- //Indique si les deux mains sont là.
- this.areBothPointersHere = false;
- //Indique si le timeout pour la détection de deux pointeurs a été lancé.
- this.areBothPointersTimeoutLaunched = false;
- //Indique si la mosaïque a été filtrée.
- this.isMosaicFiltered = false;
- //Indique si on est actuellement dans une recherche par gesture.
- this.isCurrentlyInASearchByGesture = false;
- //Indique si un pointeur est déjà sur une notification de recherche par gesture.
- this.alreadyOnNotification = false;
- //Si on a fait un swipe.
- this.isSwipe = false;
- //On peut swiper.
- this.canSwipe = false;
- //On passe vers une autre video automatiquement à la fin d'une lecture.
- this.autoMove = false;
- //Si l'utilisateur a demandé à sélectionner la TL.
- this.isTLRequested = false;
- //Le pointeur gauche a sélectionné la TL.
- this.isTLSelectedBySecondPointer = false;
- //Le pointeur droit a sélectionné la TL.
- this.isTLSelectedByMainPointer = false;
- //On peut afficher l'aide.
- this.canNotifyHelp = false;
- //Indique si la mosaique est en train d'être filtrée.
- this.isMosaicFiltering = false;
- this.arrowLeftLoading = false;
- this.arrowRightLoading = false;
- this.arrowUpLoading = false;
- this.arrowDownLoading = false;
- //On est dans une recherche par courbes.
- this.isSearchByCurvesOn = false;
- this.canDrawNextCurve = false;
- //Dans le mode d'interaction souris, indique si on se situe actuellement sur un snapshot entièrement prézoomé.
- this.isOnAPrezoomSN = false;
- //Indique si une courbe de recherche donne au moins un résultat.
- this.curvesGesturesFound = false;
- //Indique si on souhaite supprimer la recherche en cours.
- this.gestureDelRequested = false;
- //Code de gesture actuellement calculé par les détecteurs de courbes.
- this.actualCode = '';
- //Indique si l'utilisateur est entré dans la zone de recherche.
- this.isUserInSearchZone = false;
-
- //Timeout (attente) pour le zoom après un préZoom.
- this.zoomTimeout = null;
- //Timeout (attente) pour le passage vers un voisin.
- this.moveToNeighbourTimeout = null;
- this.mainPointerExitBorderTimeout = null;
- this.secondPointerExitBorderTimeout = null;
- //Idle time pour les pointeurs afin d'informer le front qu'on souhaite faire une recherche.
- this.pointersSearchIdleTimeout = null;
- //Vérifie toutes les N ms que les deux pointeurs sont détectés.
- this.areBothPointersHereTimeout = null;
- //Délai de suppression d'une notification de recherche par gesture.
- this.removeNotificationByGestureTimeout = null;
- //Délai de suppression d'une notification de recherche par gesture infructueuse.
- this.removeFailedNotificationByGestureTimeout = null;
- //Délai avant la suppression de notification swipe.
- this.notifySwipeTimeout = null;
- //Délai pour la sélection de la TL.
- this.selectTLTimeout = null;
- //Délai pour slider sur la TL.
- this.canSlideInTLTimeout = null;
- //Délai pour afficher l'aide.
- this.canNotifyHelpTimeout = null;
- this.arrowLeftTimeout = null;
- this.arrowRightTimeout = null;
- this.arrowUpTimeout = null;
- this.arrowDownTimeout = null;
-
- this.arrowSpinnerTimeout = null;
- this.nouserTimeout = null;
- this.nextDrawCurveTimeout = null;
-
- //Dernier message INCOMING (pour éviter d'effectuer n fois la même action.
- this.lastIncomingMessage = '';
-
- //Type de marqueur recherché dans la mosaïque (en mode filter).
- this.filterSearchedType = "";
-
- //Mode actuel.
- this.currentMode = "NO-USER";
- //Snapshot sur lequel on a zoomé.
- this.previousZoomedSN = null;
- //Snapshot sur lequel on a prezoomé.
- this.previousPrezoomDiv = null;
- //Son ID.
- this.previousId = null;
- //Dernier snapshot prézoomé non null.
- this.lastNonNullSN = null;
- //Largeur de la marge pour le centrage vertical de la mosaïque.
- this.MPTop_margin;
- this.top_margin;
-
- //Gestures actuellement cherchées dans les vidéos.
- this.currentSearchGesture = [];
-
- //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;
-
- //Voisins sélectionnés par les pointeurs.
- this.mainPointerNeighbourSelectedId = null;
- this.secondPointerNeighbourSelectedId = null;
-
- //Snapshots a afficher.
- this.snapshotsToShow = 1;
-
- //Lecteur.
- this.player = null;
- //Si le lecteur est prêt.
- this.playerIsReady = false;
-
- //Annotations (pour les marqueurs los d'un filtrage).
- this.annotations = [];
-
- //Client websocket pour recevoir les notifications du Middleware.
- this.client;
-
- //Coordonnées et dimensions d'un snapshot zoomé.
- this.snTop = 0;
- this.snLeft = 0;
- this.snWidth = 0;
- this.snHeight = 0;
-
- this.searchCanvas;
- //Position actuelle de la vidéo zoomée.
- this.notifyTopVideo;
- this.notifyLeftVideo;
- this.loadParameters(this.config_path);
+ //Chemin du fichier de configuration.
+ this.config_path = config;
+ //Configuration par défaut en cas de valeur erronnée.
+ this.default_config = default_conf;
+ this.config = new Object();
+ //Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque.
+ this.videos = [];
+ this.urls = [];
+ this.sources = [];
+ this.imgs = [];
+ this.opacities = [];
+ this.timeToGoAt = [];
+ this.ids = [];
+ this.fillingIds = [];
+ this.currentRandomVideoIdx = 0;
+
+ //Dictionnaire pour les courbes de recherche.
+ this.dictionary = [];
+
+ //Dernières positions des pointeurs.
+ this.mainPointerLastX = null;
+ this.mainPointerLastY = null;
+ this.secondPointerLastX = null;
+ this.secondPointerLastY = null;
+ //Dernières positions avant le lancement de la fonction d'idle.
+ this.mainPointerIdleStartX = null;
+ this.mainPointerIdleStartY = null;
+ this.secondPointerIdleStartX = null;
+ this.secondPointerIdleStartY = null;
+
+ //Coordonnées de la souris dans le mode d'interaction souris.
+ this.mousePosX = null;
+ this.mousePosY = null;
+ //Coordonnées précédentes de la souris dans le mode d'interaction souris.
+ this.mousePosLastX = null;
+ this.mousePosLastY = null;
+ //Valeur du déplacement entre un mouse up et un mouse down.
+ this.mouseUpDownDelta = 0;
+ //Coordonnées de la souris au dernier mouse down.
+ this.mouseDownPosX = null;
+ this.mouseDownPosY = null;
+
+ //Dimensions de la mosaïque en pixels.
+ this.width = null;
+ this.height = null;
+ //Dimensions d'un snapshot en pixels.
+ this.snapshotWidth = null;
+ this.snapshotHeight = null;
+ //Espacement entre les snapshots en pixels.
+ this.marginWidth = null;
+
+ //Booléens permettant ou non certaines intéractions selon le contexte.
+ this.zoomed = false;
+ this.fullscreen = false;
+ this.canMoveToNeighbour = false;
+ this.mainPointerExitBorder = false;
+ this.secondPointerExitBorder = false;
+ this.isMainPointerDisplayed = false;
+ this.isSecondPointerDisplayed = false;
+ this.helpDisplayed = false;
+ //Indique si l'utilisateur a manuellement pausé la vidéo.
+ this.userPaused = false;
+ //Indique si on est en train de se déplacer vers un voisin.
+ this.currentlyMoving = false;
+ //Indique si on est en train de dézoomer vers la mosaïque.
+ this.currentlyUnzooming = false;
+ //Indique si on peut s'approcher de kinect.
+ this.canStart = false;
+ //Indique si on est actuellement sur un snapshot.
+ this.isOnASnapshot = false;
+ //Indique si l'idle des pointeurs est disponible (deux mains détectées).
+ this.pointersIdleAvailable = false;
+ //Indique si le timeout pour l'idle des pointeurs à besoin d'être lancé.
+ this.pointersIdleNeedLaunch = false;
+ //Indique si les deux mains sont là.
+ this.areBothPointersHere = false;
+ //Indique si le timeout pour la détection de deux pointeurs a été lancé.
+ this.areBothPointersTimeoutLaunched = false;
+ //Indique si la mosaïque a été filtrée.
+ this.isMosaicFiltered = false;
+ //Indique si on est actuellement dans une recherche par gesture.
+ this.isCurrentlyInASearchByGesture = false;
+ //Indique si un pointeur est déjà sur une notification de recherche par gesture.
+ this.alreadyOnNotification = false;
+ //Si on a fait un swipe.
+ this.isSwipe = false;
+ //On peut swiper.
+ this.canSwipe = false;
+ //On passe vers une autre video automatiquement à la fin d'une lecture.
+ this.autoMove = false;
+ //Si l'utilisateur a demandé à sélectionner la TL.
+ this.isTLRequested = false;
+ //Le pointeur gauche a sélectionné la TL.
+ this.isTLSelectedBySecondPointer = false;
+ //Le pointeur droit a sélectionné la TL.
+ this.isTLSelectedByMainPointer = false;
+ //On peut afficher l'aide.
+ this.canNotifyHelp = false;
+ //Indique si la mosaique est en train d'être filtrée.
+ this.isMosaicFiltering = false;
+ this.arrowLeftLoading = false;
+ this.arrowRightLoading = false;
+ this.arrowUpLoading = false;
+ this.arrowDownLoading = false;
+ //On est dans une recherche par courbes.
+ this.isSearchByCurvesOn = false;
+ this.canDrawNextCurve = false;
+ //Dans le mode d'interaction souris, indique si on se situe actuellement sur un snapshot entièrement prézoomé.
+ this.isOnAPrezoomSN = false;
+ //Indique si une courbe de recherche donne au moins un résultat.
+ this.curvesGesturesFound = false;
+ //Indique si on souhaite supprimer la recherche en cours.
+ this.gestureDelRequested = false;
+ //Code de gesture actuellement calculé par les détecteurs de courbes.
+ this.actualCode = '';
+ //Indique si l'utilisateur est entré dans la zone de recherche.
+ this.isUserInSearchZone = false;
+ this.isMouseDown = false;
+ //Indique si on est en train de prézoomer.
+ this.isPrezooming = false;
+
+ //Timeout (attente) pour le zoom après un préZoom.
+ this.zoomTimeout = null;
+ //Timeout (attente) pour le passage vers un voisin.
+ this.moveToNeighbourTimeout = null;
+ this.mainPointerExitBorderTimeout = null;
+ this.secondPointerExitBorderTimeout = null;
+ //Idle time pour les pointeurs afin d'informer le front qu'on souhaite faire une recherche.
+ this.pointersSearchIdleTimeout = null;
+ //Vérifie toutes les N ms que les deux pointeurs sont détectés.
+ this.areBothPointersHereTimeout = null;
+ //Délai de suppression d'une notification de recherche par gesture.
+ this.removeNotificationByGestureTimeout = null;
+ //Délai de suppression d'une notification de recherche par gesture infructueuse.
+ this.removeFailedNotificationByGestureTimeout = null;
+ //Délai avant la suppression de notification swipe.
+ this.notifySwipeTimeout = null;
+ //Délai pour la sélection de la TL.
+ this.selectTLTimeout = null;
+ //Délai pour slider sur la TL.
+ this.canSlideInTLTimeout = null;
+ //Délai pour afficher l'aide.
+ this.canNotifyHelpTimeout = null;
+ this.arrowLeftTimeout = null;
+ this.arrowRightTimeout = null;
+ this.arrowUpTimeout = null;
+ this.arrowDownTimeout = null;
+
+ this.arrowSpinnerTimeout = null;
+ this.nouserTimeout = null;
+ this.nextDrawCurveTimeout = null;
+
+ //Dernier message INCOMING (pour éviter d'effectuer n fois la même action.
+ this.lastIncomingMessage = '';
+
+ //Type de marqueur recherché dans la mosaïque (en mode filter).
+ this.filterSearchedType = "";
+
+ //Mode actuel.
+ this.currentMode = "NO-USER";
+ //Snapshot sur lequel on a zoomé.
+ this.previousZoomedSN = null;
+ //Snapshot sur lequel on a prezoomé.
+ this.previousPrezoomDiv = null;
+ //Son ID.
+ this.previousId = null;
+ //Dernier snapshot prézoomé non null.
+ this.lastNonNullSN = null;
+ //Largeur de la marge pour le centrage vertical de la mosaïque.
+ this.MPTop_margin = null;
+ this.top_margin = null;
+
+ //Gestures actuellement cherchées dans les vidéos.
+ this.currentSearchGesture = [];
+
+ //Position des voisins lors d'un zoom.
+ this.neighboursIds = [];
+ //ID du snapshot du milieu lors d'un zoom.
+ this.centerId = null;
+
+ //Voisins sélectionnés par les pointeurs.
+ this.mainPointerNeighbourSelectedId = null;
+ this.secondPointerNeighbourSelectedId = null;
+
+ //Snapshots a afficher.
+ this.snapshotsToShow = 1;
+
+ //Lecteur.
+ this.player = null;
+ //Si le lecteur est prêt.
+ this.playerIsReady = false;
+
+ //Annotations (pour les marqueurs los d'un filtrage).
+ this.annotations = [];
+
+ //Client websocket pour recevoir les notifications du Middleware.
+ this.client = null;
+
+ //Coordonnées et dimensions d'un snapshot zoomé.
+ this.snTop = 0;
+ this.snLeft = 0;
+ this.snWidth = 0;
+ this.snHeight = 0;
+
+ this.searchCanvas = null;
+ //Position actuelle de la vidéo zoomée.
+ this.notifyTopVideo = null;
+ this.notifyLeftVideo = null;
+ this.loadParameters(this.config_path);
}
/*
* Méthode d'affichage de la mosaïque.
* Génère une matrice de imgs.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadMosaic, afin de créer les éléments visuels de la mosaique.
*/
-mosaic.prototype.createMosaic = function()
+Mosaic.prototype.createMosaic = function()
{
- // console.log('CREATE');
- // this.currentMode = "NO-USER";
- var initPanel = '<div id="initPanel"></div>';
- var mp = $('#mainPanel');
- mp.append(initPanel);
- $('#initPanel').css(
+ var _this = this;
+
+ //On ajoute le player au body pour le lancer la première fois qu'on zoom.
+ $('body').append('<div class="player" id="video"></div><div class="LdtPlayer" id="LdtPlayer"></div>');
+
+ //On recharge la fenêtre si sa taille a changé.
+ $(window).resize(function()
{
- background: 'transparent',
- width: mp.width(),
- height: mp.height(),
- top: mp.position().top,
- left: mp.position().left,
- 'margin-top': this.MPTop_margin
+ _.debounce(window.location.reload(), _this.config.timeReloadAfterResize);
});
- var len = this.config['length'], imgs = this.config['imagesToShow'], imgsTotal = this.config['imagesTotal'];
-
- //S'il s'agit d'un rectangle.
+ var initPanel = '<div id="initPanel"></div>';
+ var mp = $('#mainPanel');
+ mp.append(initPanel);
+ $('#initPanel').css(
+ {
+ background: 'transparent',
+ width: mp.width(),
+ height: mp.height(),
+ top: mp.position().top,
+ left: mp.position().left,
+ 'margin-top': this.MPTop_margin
+ });
+
+ var len = this.config.length, imgs = this.config.imagesToShow, imgsTotal = this.config.imagesTotal;
+
+ //S'il s'agit d'un rectangle.
if(imgs % len == 0)
{
- this.lastIncomingMessage = 'INCOMING-0';
-
- var str = '';
-
- if(this.imgs.length >= imgs)
- {
- for(var i = 0 ; i < imgs ; i++)
- {
- //On charge les images de petite taille pour ne pas surcharger la mosaïque lors de l'affichage global.
- str += '<div id="snapshotDiv-' + i + '" class="snapshotDivs" style="opacity: 0;"><img id="snapshot-' + i + '" class="snapshots" src="snapshots-little/' + this.imgs[i] + '" /></div>';
- //Au départ aucune vidéo n'a de gesture de recherche.
- this.currentSearchGesture[i] = '';
- }
- }
-
- return str + '<div id="ghostPanel"></div>';
- }
- else
+ this.lastIncomingMessage = 'INCOMING-0';
+
+ var str = '';
+
+ if(this.imgs.length >= imgs)
+ {
+ for(var i = 0 ; i < imgs ; i++)
+ {
+ //On charge les images de petite taille pour ne pas surcharger la mosaïque lors de l'affichage global.
+ str += '<div id="snapshotDiv-' + i + '" class="snapshotDivs" style="opacity: 0;"><img id="snapshot-' + i + '" class="snapshots" src="snapshots-little/' + this.imgs[i] + '" /></div>';
+ //Au départ aucune vidéo n'a de gesture de recherche.
+ this.currentSearchGesture[i] = '';
+ }
+ }
+
+ return str + '<div id="ghostPanel"></div>';
+ }
+ else
+ {
+ alert("Le nombre d'images a afficher doit être divisible par la longueur de la mosaïque !");
+ }
+}
+
+/*
+ * 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;
+
+ //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)
{
- alert("Le nombre d'images a afficher doit être divisible par la longueur de la mosaïque !");
+ this.searchCanvas.onPointerIn(this.mousePosX, this.mousePosY, null, null);
}
}
/*
- * Permet de raffraichir la mosaïque.
- */
-mosaic.prototype.loadMosaic = function()
+ * 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)
{
- // console.log('LOAD');
- var createMosaic = this.createMosaic();
-
- if(createMosaic == '')
+ //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.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.
+ */
+Mosaic.prototype.loadMosaic = function()
+{
+ // console.log('LOAD');
+ var createMosaic = this.createMosaic();
+
+ if(createMosaic == '')
+ {
+ return;
+ }
+
+ var _this = this;
+
//On affecte les chemins vers les images à la mosaïque.
this.previousZoomedSN;
- //this.width =
- // console.log(createMosaic);
//On met à jour la mosaïque.
$('#mainPanel').html(createMosaic);
//On récupère la taille des bordures.
@@ -314,7 +607,7 @@
//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.config['length'] - this.marginWidth;
+ this.snapshotWidth = this.width / this.config.length - this.marginWidth;
this.snapshotHeight = this.snapshotWidth*9/16;
$('.snapshotDivs').css('width', this.snapshotWidth).css('height', this.snapshotHeight).css('margin', this.marginWidth/2);
@@ -322,936 +615,774 @@
//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);
-
- //On fait coincider le background du body avec celui de la mosaïque.
- $('body').css('background-position', '0px ' + this.MPTop_margin + 'px');
-
- /*$('.snapshotDivs').mouseover(function ()
- {
- //On effectue un prézoom dès qu'on va sur une image.
- _this.preZoom($(this));
- });*/
-
- this.addPointers();
-
- //Si dans le metadata player _ n'est pas déclaré, on le déclare.
- if(typeof _ !== "undefined" && typeof IriSP._ === "undefined")
- {
- IriSP._ = _;
- }
-
- if(typeof $ !== "undefined" && typeof IriSP.jQuery === "undefined")
- {
- IriSP.jQuery = $;
- }
-
- //On charge les marqueurs.
- var sourceManager = new IriSP.Model.Directory(),
- globalAnnotations = new IriSP.Model.List(sourceManager),
- nbFichiers = _this.urls.length,
- fichiersCharges = 0;
-
- for (var i = 0; i < nbFichiers; i++)
- {
- // console.log('url : ' + _this.urls[i]);
- _this.sources[i] = sourceManager.remoteSource({url: _this.urls[i], serializer: IriSP.serializers.ldt});
- _this.sources[i].onLoad(function()
+
+ //On fait coincider le background du body avec celui de la mosaïque.
+ $('body').css('background-position', '0px ' + this.MPTop_margin + 'px');
+
+ this.addPointers();
+
+ //Si dans le metadata player _ n'est pas déclaré, on le déclare.
+ if(typeof _ !== "undefined" && typeof IriSP._ === "undefined")
+ {
+ IriSP._ = _;
+ }
+
+ if(typeof $ !== "undefined" && typeof IriSP.jQuery === "undefined")
+ {
+ IriSP.jQuery = $;
+ }
+
+ //On charge les marqueurs.
+ var sourceManager = new IriSP.Model.Directory(),
+ globalAnnotations = new IriSP.Model.List(sourceManager),
+ nbFichiers = _this.urls.length,
+ fichiersCharges = 0;
+
+ //Récupère les annotations.
+ for (var i = 0; i < nbFichiers; i++)
+ {
+ _this.sources[i] = sourceManager.remoteSource({url: _this.urls[i], serializer: IriSP.serializers.ldt});
+ _this.sources[i].onLoad(function()
+ {
+ var source = this;
+ globalAnnotations.addElements(source.getAnnotations());
+ fichiersCharges++;
+ if (fichiersCharges == nbFichiers)
+ {
+ //Instructions à exécuter quand tout est chargé.
+ _this.annotations = globalAnnotations;
+ // console.log(_this.annotations.length + ' annotations loaded from ' + nbFichiers + ' files.');
+
+ //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;
+ });
+ }
+
+ //Si on a activé la préphase mais qu'on est en mode Kinect.
+ if(_this.config.noUserModeEnabled && !_this.config.mouseInteractions)
+ {
+ //On active la préphase.
+ _this.init();
+ _this.showNImages(0);
+ _this.currentMode = "NO-USER";
+ }
+ else
+ {
+ //Sinon on affiche directement la mosaique.
+ _this.showNImages(20);
+ _this.currentMode = "MOSAIC";
+ }
+
+ //Le premier snapshot sur lequel on zoom en préphase.
+ _this.previousZoomedSN = $('#snapshotDiv-' + _this.fillingIds[0]);
+ }
+ });
+ }
+
+ //Si on est en mode d'intéraction souris.
+ if(this.config.mouseInteractions)
+ {
+ //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;
+ });
+
+ //On écoute le déplacement de la souris.
+ $(window).mousemove(function(e)
{
- var source = this;
- // console.log(source);
- globalAnnotations.addElements(source.getAnnotations());
- // console.log(source.url + ' ' + source.getAnnotations().length);
- fichiersCharges++;
- if (fichiersCharges == nbFichiers)
+ _this.onMouseMove(e);
+ return false;
+ });
+
+ //Si on fait un mouse up après ce mouse down.
+ $(window).mouseup(function()
+ {
+ _this.onMouseUp();
+ return false;
+ });
+
+ //Si on fait un clic.
+ $(window).click(function(e)
+ {
+ _this.onClick(e.pageX, e.pageY);
+ _this.removeSearchNotificationIfOnIt(e.pageX, e.pageY);
+ return false;
+ });
+
+ $(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)
{
- // instructions à exécuter quand tout est chargé
- _this.annotations = globalAnnotations;
- // console.log(_this.annotations.length + ' ' + nbFichiers);
- console.log(_this.annotations.length + ' annotations loaded from ' + nbFichiers + ' files.');
-
- //Si on gère les interactions à la souris.
- if(_this.mouseInteractions)
- {
- $(window).mousemove(function(e)
- {
- _this.refreshMainPointer(e.pageX, e.pageY, _this);
- _this.mousePosX = e.pageX;
- _this.mousePosY = e.pageY;
- });
- }
-
- if(_this.prephaseEnabled && !_this.mouseInteractions)
- {
- _this.init();
- _this.showNImages(0);
- _this.currentMode = "NO-USER";
- }
- else
- {
- _this.showNImages(20);
- _this.currentMode = "MOSAIC";
- }
-
- // /!\ //
- // _this.currentMode = "FILTER";
- // _this.showNImages(20);
- //_this.isSearchByCurvesOn = true;
- // _this.startSearch();
- // console.log('CANVAS READY');
- // /!\ //
-
- _this.previousZoomedSN = $('#snapshotDiv-' + _this.fillingIds[0]);
- }
- });
- }
-
- if(this.mouseInteractions)
- {
- //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.removeSearchNotificationIfOnIt(e.pageX, e.pageY);
-
- _this.isUserInSearchZone = true;
- if(_this.isSearchByCurvesOn)
- {
- _this.searchCanvas.onPointerIn(_this.mousePosX, _this.mousePosY, null, null);
+ return;
}
- console.log('mdown');
- //On écoute le déplacement de la souris.
- $(window).mousemove(function(e)
- {
- 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)));
-
- // console.log(_this.mouseUpDownDelta, _this.mousePosLastX, e.pageX);
-
- 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;
-
- console.log(_this.date() + ' - ENTRE EN MODE FILTRAGE');
-
- _this.isSearchByCurvesOn = true;
- _this.startSearch();
-
- /*if(!_this.curvesGesturesFound)
- {
- this.removeNotifications();
- _this.filterSearch();
- }*/
-
- _this.searchCanvas.onPointerIn(_this.mousePosX, _this.mousePosY - _this.MPTop_margin, null, null);
- }
- else if(_this.currentMode == "FILTER" && !_this.isSearchByCurvesOn && _this.isUserInSearchZone)
- {
- console.log('after search');
- _this.preUnzoom();
- _this.isSearchByCurvesOn = true;
- _this.startSearch();
- _this.searchCanvas.onPointerIn(_this.mousePosX, _this.mousePosY - _this.MPTop_margin, null, null);
- }
- //Si on est dans une vidéo, on entre en recherche.
- else if(_this.currentMode == "VIDEO" || _this.currentMode == "TIMELINE")
- {
- _this.currentMode = "SEARCH";
-
- console.log(_this.date() + ' - ENTRE EN MODE RECHERCHE');
-
- _this.isSearchByCurvesOn = true;
- _this.startSearch();
-
- /*if(!_this.curvesGesturesFound)
- {
- this.removeNotifications();
- _this.searchSearch();
- }*/
-
- _this.searchCanvas.onPointerIn(_this.mousePosX, _this.mousePosY - _this.MPTop_margin, null, null);
- }
- else if(_this.currentMode == "SEARCH" && !_this.isSearchByCurvesOn)
- {
- _this.isSearchByCurvesOn = true;
- _this.startSearch();
- _this.searchCanvas.onPointerIn(_this.mousePosX, _this.mousePosY - _this.MPTop_margin, null, null);
- }
-
- //Il est possible d'afficher l'aide.
- if(!_this.canNotifyHelp)
- {
- _this.canNotifyHelpTimeout = setTimeout(function()
- {
- _this.canNotifyHelp = true;
- }, _this.config['timeoutCanNotifyHelp']);
- }
- }
- });
-
- //Si on fait un mouse up après ce mouse down.
- $(window).mouseup(function()
- {
- console.log('mup');
-
- if(_this.isSearchByCurvesOn)
- {
- _this.isUserInSearchZone = false;
-
- var gesture_match = _this.gestureWithSameCode(_this.actualCode);
- _this.actualCode = '';
-
- if(gesture_match.length > 0)
- {
- if(_this.currentMode == "SEARCH" && _this.playerIsReady)
- {
- _this.player.widgets[0].searchByGesture(gesture_match);
- _this.isCurrentlyInASearchByGesture = _this.player.widgets[0].isCurrentlyInASearchByGesture;
-
- 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]);
- }
-
- _this.removeNotifications();
- _this.currentSearchGesture[_this.centerId] = gesture_match;
- _this.searchGesture(gesture_match, 'valid');
- _this.curvesGesturesFound = false;
- }
- else if(_this.currentMode == "FILTER")
- {
- if(_this.isMosaicFiltered)
- {
- _this.removeNotifications();
- _this.filterSearchedType = gesture_match;
- _this.filterGesture(gesture_match, 'valid');
- _this.searchFilter(gesture_match);
- _this.curvesGesturesFound = false;
- }
- }
- }
-
- _this.searchCanvas.onPointerOut();
- }
-
- //On unbind ce qui a été bindé après le mouse up.
- $(window).unbind('mousemove');
- $(window).unbind('mouseup');
- //On rebind le mousemove principal du body, car ils ont tous été unbindés.
- $(window).mousemove(function(e)
- {
- _this.refreshMainPointer(e.pageX, e.pageY, _this);
- _this.mousePosX = e.pageX;
- _this.mousePosY = e.pageY;
- });
-
- _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.zoom();
- }
- }
-
- _this.mouseUpDownDelta = 0;
- _this.isSearchByCurvesOn = false;
- _this.leaveSearch();
-
- if(_this.currentMode == 'FILTER' && _this.filterSearchedType != '')
- {
- _this.removeNotifications();
- _this.filterGesture(_this.filterSearchedType, 'valid');
- }
- });
- });
- }
+ //Quand on "tire" la molette vers soi, on dezoom.
+ if (delta < 0)
+ {
+ _this.unzoom();
+ }
+ });
+ }
}
/*
* Charge les paramètres du Front. Local (true/false) est le mode de chargement des données.
+ * Est appelé dans le fichier :
+ * mosaic > fonction Mosaic, est appelée dans le constructeur de manière à charger les paramètres de configuration avant la création de la mosaique.
*/
-mosaic.prototype.loadParameters = function(file_path)
+Mosaic.prototype.loadParameters = function(file_path)
{
- var _this = this;
-
- var supposedToBeInt = ['length', 'imagesToShow', 'totalImages', 'timePrezoom', 'timePreUnzoom', 'timeZoom', 'zoomTime', 'timeUnzoom', 'timeNeighbourGlowing', 'timeNeighbourUnglowing', 'timeMovingToNeighbour', 'timeSearchFade', 'timeNotifyFade', 'timeFilterFade', 'timeANFade', 'timeFilling', 'zoomedMargin', 'timeoutZoom', 'timeoutUnzoom', 'timeoutMoveToNeighbour', 'timeoutPointersIdle', 'timeoutAreBothPointersHere', 'timeoutRemoveNotificationByGesture', 'timeoutRemoveFailedNotificationByGesture', 'timeoutNotifySwipe', 'timeoutSelectTL', 'timeoutSlideTL', 'timeoutCanNotifyHelp', 'timeoutRemoveSpinner', 'timeoutNouser', 'timeoutNextDrawCurve', 'mouseUpDownDeltaTreshold'];
- var supposedToBeFloat = ['zoomPercentage', 'prezoomPercentage'];
-
- $.getJSON(file_path, function(data)
- {
- for(key in data)
- {
- var val = data[key];
-
- if(_.include(supposedToBeInt, key))
- {
- var intVal = parseInt(val);
- if(isNaN(intVal))
- {
- // console.log(_this.default_config);
- _this.config[key] = _this.default_config[key];
- console.log("param[" + key + "] : Valeur " + val + " incorrecte (non Int). Valeur par défaut " + _this.default_config[key] + " chargée à la place.");
- }
- else
- {
- _this.config[key] = intVal;
- }
- }
- else if(_.include(supposedToBeFloat, key))
- {
- var floatVal = parseFloat(val);
- if(isNaN(floatVal))
+ var _this = this;
+
+ //Variables censées être des ints.
+ var supposedToBeInt = ['length', 'imagesToShow', 'totalImages', 'timeReloadAfterResize', 'timePrezoom', 'timePreUnzoom', 'timeZoom', 'zoomTime', 'timeUnzoom', 'timeNeighbourGlowing', 'timeNeighbourUnglowing', 'timeMovingToNeighbour', 'timeSearchFade', 'timeNotifyFade', 'timeFilterFade', 'timeANFade', 'timeFilling', 'zoomedMargin', 'timeoutZoom', 'timeoutUnzoom', 'timeoutMoveToNeighbour', 'timeoutPointersIdle', 'timeoutAreBothPointersHere', 'timeoutRemoveNotificationByGesture', 'timeoutRemoveFailedNotificationByGesture', 'timeoutNotifySwipe', 'timeoutSelectTL', 'timeoutSlideTL', 'timeoutCanNotifyHelp', 'timeoutRemoveSpinner', 'timeoutNouser', 'timeoutNextDrawCurve', 'mouseUpDownDeltaTreshold'];
+ //Variables censées êtres des floats.
+ var supposedToBeFloat = ['zoomPercentage', 'prezoomPercentage'];
+
+ //On lit le fichier de configuration.
+ $.getJSON(file_path, function(data)
+ {
+ //Pour chaque ligne du fichier.
+ for(key in data)
+ {
+ var val = data[key];
+
+ //Si la valeur est prise pour un int.
+ if(_.include(supposedToBeInt, key))
+ {
+ //On la parse et s'il y a une erreur, on l'indique dans la console avant d'affecter la valeur par défaut.
+ //Sinon on lui affecte la valeur lue.
+ var intVal = parseInt(val);
+ if(isNaN(intVal))
+ {
+ _this.config[key] = _this.default_config[key];
+ console.log("param[" + key + "] : Valeur " + val + " incorrecte (non Int). Valeur par défaut " + _this.default_config[key] + " chargée à la place.");
+ }
+ else
+ {
+ _this.config[key] = intVal;
+ }
+ }
+ //Si la valeur est prise pour un float.
+ else if(_.include(supposedToBeFloat, key))
+ {
+ //On la parse et s'il y a une erreur, on l'indique dans la console avant d'affecter la valeur par défaut.
+ //Sinon on lui affecte la valeur lue.
+ var floatVal = parseFloat(val);
+ if(isNaN(floatVal))
+ {
+ _this.config[key] = _this.default_config[key];
+ console.log("param[" + key + "] : Valeur " + val + " incorrecte (non Float). Valeur par défaut " + _this.default_config[key] + " chargée à la place.");
+ }
+ else
+ {
+ _this.config[key] = floatVal;
+ }
+ }
+ else
+ {
+ //S'il s'agit de la langue, on met par défaut si la valeur est nulle.
+ if(key == 'lang' && val == '')
{
_this.config[key] = _this.default_config[key];
- console.log("param[" + key + "] : Valeur " + val + " incorrecte (non Float). Valeur par défaut " + _this.default_config[key] + " chargée à la place.");
}
+ //Sinon si c'est une string, on l'affecte.
else
{
- _this.config[key] = floatVal;
+ _this.config[key] = val;
}
- }
- else
- {
- _this.config[key] = val;
- }
- }
-
- //On remplit le tableau d'ids.
- for(var i = 0 ; i < _this.config['totalImages'] ; i++)
- _this.ids.push(i);
- //On les mélange.
- _this.ids.sort(function()
- {
- return 0.5 - Math.random()
- });
-
- //On remplit le tableau d'ids destiné à afficher les snapshots au fur et à mesure.
- for(var i = 0 ; i < _this.config['imagesToShow'] ; i++)
- _this.fillingIds.push(i);
- //On les mélange.
- _this.fillingIds.sort(function()
- {
- return 0.5 - Math.random()
- });
-
- if(_this.config['local'] == 'true')
- {
- // console.log("Loading local metadata.");
- _this.loadFromJson('./player/json/local_videos.json');
- }
- else
- {
- // console.log("Loading online metadata.");
- _this.loadFromJson('./player/json/online_videos.json');
- }
-
- //On initialise le client.
- if(!_this.mouseInteractions)
- {
- _this.client = new client(_this.config['host'], _this.config['port'], _this);
- }
-
- _this.getDictionary();
- _this.getLang();
- });
+ }
+ }
+
+ //On remplit le tableau d'ids.
+ for(var i = 0 ; i < _this.config.totalImages ; i++)
+ _this.ids.push(i);
+ //On les mélange.
+ _this.ids = _.shuffle(_this.ids);
+
+ //On remplit le tableau d'ids destiné à afficher les snapshots au fur et à mesure.
+ for(var i = 0 ; i < _this.config.imagesToShow ; i++)
+ _this.fillingIds.push(i);
+ //On les mélange.
+ _this.fillingIds = _.shuffle(_this.fillingIds);
+
+ //Si la config spécifie le chargement comme étant local/en ligne, on charge le fichier des vidéos approprié.
+ if(_this.config.local)
+ {
+ _this.loadFromJson(_this.config.videoConfigFileLocal);
+ }
+ else
+ {
+ _this.loadFromJson(_this.config.videoConfigFileOnline);
+ }
+
+ //On initialise le client dans le cas d'intéractions Kinect.
+ if(!_this.config.mouseInteractions)
+ {
+ _this.client = new Client(_this.config.host, _this.config.port, _this);
+ }
+
+ //On prend le dictionnaire stockant les codes des courbes de recherche.
+ _this.getDictionary();
+ //On charge le fichier des langues.
+ _this.getLang();
+ });
}
/*
* Phase principale (utilisateur non détecté). Une vidéo se lance aléatoirement.
* L'interface est identique à celle du zoom, mais sans interaction possible avec les voisins, ni les controles timeline.
* Lors de la fin d'une lecture, on dézoome vers la mosaïque, puis on rezoome vers un autre snapshot (aléatoire).
+ * Est appelé dans les fichiers :
+ * mosaic > fonction loadMosaic.
+ * zoomInteractions > fonction unzoom.
*/
-mosaic.prototype.init = function()
+Mosaic.prototype.init = function()
{
- var _this = this;
-
- if(this.currentRandomVideoIdx > this.config['imagesToShow'])
- {
- this.currentRandomVideoIdx = 0;
- }
-
-
- this.previousZoomedSN = $('#snapshotDiv-' + this.fillingIds[this.currentRandomVideoIdx]);
- this.previousId = $('img', this.previousZoomedSN).attr('id');
-
- // console.log('CURRENT MODE : ' + _this.currentMode);
- // console.log('ids', this.fillingIds[this.currentRandomVideoIdx]);
-
- this.previousZoomedSN.fadeTo(this.config['timePrezoom'], 1, function()
- {
- // console.log('CURRENT MODE : ' + _this.currentMode);
- _this.zoom();
- _this.currentRandomVideoIdx++;
- });
+ var _this = this;
+
+ //Si l'index de lecture des vidéos en mode sans utilisateur excède le nombre maximal de vidéos, il est remis à 0 pour tourner en boucle.
+ if(this.currentRandomVideoIdx > this.config.imagesToShow)
+ {
+ this.currentRandomVideoIdx = 0;
+ }
+
+ //Le snapshot sur lequel on doit zoomé a pour id le tableau de lecture aléatoire à l'index de lecture.
+ this.previousZoomedSN = $('#snapshotDiv-' + this.fillingIds[this.currentRandomVideoIdx]);
+ this.previousId = $('img', this.previousZoomedSN).attr('id');
+
+ //On fait apparaître le snapshot avant de zoomer dessus.
+ this.previousZoomedSN.fadeTo(this.config.timePrezoom, 1, function()
+ {
+ _this.zoom();
+ _this.currentRandomVideoIdx++;
+ });
}
/*
* Remplissage de la mosaïque en fonction du nombre d'images à afficher.
+ * Est appelé dans le fichier :
+ * mosaic > fonctions loadMosaic et manageControlEvents.
*/
-mosaic.prototype.showNImages = function(n)
+Mosaic.prototype.showNImages = function(n)
+{
+ //Si on bouge vers un voisin, on n'utilise pas cette fonction.
+ if(this.currentlyMoving)
+ {
+ return;
+ }
+
+ //Si il y a plus d'un snapshot à afficher, on entre dans le mode INCOMING avec en paramètre le nombre à afficher.
+ if(n > 1 && n < this.config.imagesToShow)
+ {
+ //On met en mode incoming avec le nombre de snapshots à afficher.
+ this.currentMode = "INCOMING-" + n;
+ //On dézoom.
+ this.unzoom();
+
+ //On initialise les gestures de recherche.
+ for(var i = 0 ; i < this.config.imagesToShow ; i++)
+ {
+ this.currentSearchGesture[i] = '';
+ }
+
+ //On enlève les notifications.
+ this.removeNotifications();
+ //On annule les recherches.
+ this.isMosaicFiltered = false;
+ this.isCurrentlyInASearchByGesture = false;
+ //On masque les pointeurs.
+ $('#mainPointer').fadeTo(this.config.timePrezoom, 0);
+ $('#secondPointer').fadeTo(this.config.timePrezoom, 0);
+ //On enlève le spinner.
+ $('#spinner').remove();
+ //On déselectionne tous les voisins.
+ this.deselectAllNeighbours();
+ //On enlève tous les prézooms en cours.
+ $('.prezoomContainers').remove();
+ }
+
+ //Si on doit afficher la mosaique complète.
+ if(n >= this.config.imagesToShow)
+ {
+ //Si on est en mode sans utilisateur ou bien en mode d'utilisateur approchant.
+ if(this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING-") > -1)
+ {
+ //Si on est en intéractions Kinect.
+ if(!this.config.mouseInteractions)
+ {
+ //On met le mode à jour.
+ this.currentMode = "INCOMING-20";
+ //On dézoom.
+ this.unzoom();
+ }
+
+ //On passe en mode mosaique.
+ this.currentMode = "MOSAIC";
+ //On enlève les notifications, et on met les notifications de sélection et de recherche.
+ this.removeNotifications();
+ this.mosaicSelectionAndSearch();
+ //On retarde le mécanisme de redémarrage.
+ clearTimeout(this.nouserTimeout);
+ }
+ }
+
+ //Pour les snapshots à afficher.
+ for(var i = 0 ; i < n ; i++)
+ {
+ //Si les snapshots ne sont pas affichés.
+ if($('#snapshotDiv-' + this.fillingIds[i]).css('opacity') < 1)
+ {
+ //On les fait apparaître.
+ $('#snapshotDiv-' + this.fillingIds[i]).fadeTo(this.config.timeFilling, '1');
+ }
+ }
+ //Pour ceux à masquer.
+ for(var i = n ; i < this.config.imagesToShow ; i++)
+ {
+ //Si les snapshots ne sont pas masqués et qu'il ne s'agit pas du dernier snapshot en lecture aléatoire (mode NO-USER).
+ if($('#snapshotDiv-' + this.fillingIds[i]).css('opacity') > 0 && this.fillingIds[i] != this.currentRandomVideoIdx)
+ {
+ //On les masque.
+ $('#snapshotDiv-' + this.fillingIds[i]).fadeTo(this.config.timeFilling, '0');
+ }
+ }
+}
+
+/*
+ * Gère les événements de contrôle dans la mosaïque.
+ * Est appelé dans le fichier :
+ * client > fonction processMsg.
+*/
+Mosaic.prototype.manageControlEvents = function(event)
{
- if(this.currentlyMoving)
+ var _this = this;
+
+ if(typeof event === 'undefined')
+ {
+ return;
+ }
+
+ var gestureReceived = '';
+
+ //Si l'utilisateur arrive et qu'on a la préphase activée.
+ if(event.indexOf("INCOMING-") != -1 && this.config.noUserModeEnabled)
+ {
+ //Si on peut démarrer.
+ if(this.canStart)
+ {
+ //Si on veut afficher plus de snapshots que disponibles, on affiche le maximum.
+ if(this.snapshotsToShow > this.config.imagesToShow)
+ {
+ this.snapshotsToShow = this.config.imagesToShow;
+ }
+ else
+ {
+ //On récupère le nombre de snapshots à afficher.
+ var params = event.split('-');
+ this.snapshotsToShow = params[1];
+ }
+
+ //Si la position de l'utilisateur a changé.
+ if(event != this.lastIncomingMessage)
+ {
+ //On la met à jour et on affiche la mosaique en conséquence.
+ this.lastIncomingMessage = event;
+ this.showNImages(this.snapshotsToShow);
+ }
+ }
+
+ //On retarde le mécanisme de redémarrage.
+ clearTimeout(this.nouserTimeout);
+
+ //Après un délai d'absence de l'utilisateur on redémarre.
+ this.nouserTimeout = setTimeout(function()
+ {
+ window.location.reload();
+ }, this.config.timeoutNouser);
+ }
+ //S'il n'y a qu'un snapshot à afficher et qu'on est en préphase, on redémarre.
+ else if((event == "NO-USER" || event == "INCOMING-0" || event == "INCOMING-1") && this.config.noUserModeEnabled)
+ {
+ window.location.reload();
+ }
+ //Si on a fait un swipe.
+ else if(event.indexOf("SWIPE") != -1)
+ {
+ //Si le player est près et qu'on n'est pas en train de faire un swipe.
+ if(this.player && this.player.widgets && this.playerIsReady && !this.isSwipe)
+ {
+ //On est en train de faire un swipe.
+ this.isSwipe = true;
+
+ //Si on est en mode de recherche, que la mosaique est filtrée et qu'on est arrivé au dernier marqueur.
+ if(this.currentMode == 'SEARCH' && this.isMosaicFiltered && !this.player.widgets[0].isAMarkerAhead(this.currentSearchGesture[this.centerId]))
+ {
+ //On passe à la prochaine vidéo qui contient des résultats.
+ this.playNextVideo();
+ }
+
+ //On spécifie s'il s'agit d'un swipe left ou right.
+ var swipeType = ((event.indexOf("LEFT") != -1) ? 'left' : 'right');
+ var isSwipeLeft = ((event.indexOf("LEFT") != -1) ? true : false);
+
+ //On passe au marqueur suivant/précédent en fonction du type de swipe.
+ this.player.widgets[0].switchToMarker(isSwipeLeft, this.currentSearchGesture[this.centerId]);
+ //Si on est en mode vidéo.
+ if(this.currentMode == 'VIDEO')
+ {
+ //On affiche la notification.
+ this.removeNotifications();
+ this.videoSwipe(swipeType);
+ }
+ //Si on est en mode recherche dans une vidéo et qu'on n'a pas de gesture de recherche.
+ else if(this.currentMode == 'SEARCH' && this.currentSearchGesture[this.centerId] == '')
+ {
+ //On affiche la notification.
+ this.removeNotifications();
+ this.searchSearchAndSwipe(swipeType);
+ }
+ //Si on est en mode recherche dans une vidéo et qu'on a une gesture de recherche.
+ else if(this.currentMode == 'SEARCH' && this.currentSearchGesture[this.centerId] != '')
+ {
+ //On affiche la notification.
+ this.removeNotifications();
+ this.searchGestureAndSwipe(this.currentSearchGesture[this.centerId], 'valid', swipeType);
+ }
+
+ //On le fait disparaitre au bout d'un certain temps.
+ this.notifySwipeTimeout = setTimeout(function()
+ {
+ _this.isSwipe = false;
+ _this.removeNotifications();
+
+ //Si on est en mode de recherche dans une vidéo et qu'aucune gesture n'est recherchée.
+ if(_this.currentMode == 'SEARCH' && _this.currentSearchGesture[_this.centerId] == '')
+ {
+ _this.searchSearch();
+ }
+ //Si on est en mode de recherche dans une vidéo et qu'on a une recherche par gesture.
+ else if(_this.currentMode == 'SEARCH' && _this.currentSearchGesture[_this.centerId] != '')
+ {
+ _this.searchGesture(_this.currentSearchGesture[_this.centerId], 'valid');
+ }
+
+ }, this.config.timeoutNotifySwipe);
+ }
+ }
+ //Si on reçoit l'instruction correspondant à une des quatre gestures de recherche corporelle.
+ else if(event.indexOf("BEND") != -1 || event.indexOf('KNEE-UP') != -1 || event.indexOf('FALL') != -1 || event.indexOf('JUMP') != -1)
+ {
+ //On la met en minuscule.
+ gestureReceived = event.toLowerCase();
+ //On met à jour la gesture recherchée.
+ this.currentSearchGesture[centerId] = gestureReceived;
+ }
+ //Si on a effectué un hello, qu'on peut notifier l'aide et que les deux mains ne sont pas dans la zone de recherche.
+ else if(event.indexOf("HELLO") != -1 && this.canNotifyHelp && !this.areBothPointersHere)
+ {
+ //On affiche différentes aides en fonction de si on se trouve dans une vidéo ou non.
+ if(this.currentMode == 'SEARCH')
+ {
+ this.notifyHelp(false);
+ }
+ else if(this.currentMode == 'FILTER')
+ {
+ this.notifyHelp(true);
+ }
+ }
+
+ //Si on a reçu une gesture.
+ if(gestureReceived != '')
+ {
+ //Si on est en mode recherche et que le player est prêt.
+ if(this.currentMode == "SEARCH" && this.playerIsReady)
+ {
+ //On recherche dans la vidéo.
+ this.player.widgets[0].searchByGesture(gestureReceived);
+ this.isCurrentlyInASearchByGesture = this.player.widgets[0].isCurrentlyInASearchByGesture;
+ //On notifie.
+ this.removeNotifications();
+ this.searchGesture(gestureReceived, 'valid');
+ }
+ //Si on est dans un filtrage.
+ else if(this.currentMode == "FILTER")
+ {
+ if(this.isMosaicFiltered)
+ {
+ //On notifie et on filtre.
+ this.removeNotifications();
+ this.filterGesture(gestureReceived, 'valid');
+ this.searchFilter(gestureReceived);
+ }
+ }
+
+ //Si l'aide est affichée, on l'enlève.
+ if(this.helpDisplayed)
+ {
+ this.removeHelp();
+ }
+ }
+}
+
+/*
+ * Fonction qui s'exécute lorsque le player a chargé.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadPlayer.
+*/
+Mosaic.prototype.onPlayerLoad = function()
+{
+ var _this = this;
+
+ if(this.currentMode == 'NO-USER')
{
- return;
+ //On peut s'approcher de la kinect.
+ this.canStart = true;
}
- // console.log('INCOMING ----- ' + n);
- //Si il y a plus d'un snapshot à afficher, on entre dans le mode INCOMING avec en paramètre le nombre à afficher.
- if(n > 1 && n < this.config['imagesToShow'])
+ //Lorsque le player est en pause (par exemple lorsque le curseur arrive à la fin de la timeline).
+ if(this.player.popcorn)
{
- this.currentMode = "INCOMING-" + n;
- this.unzoom();
-
- for(var i = 0 ; i < this.config['imagesToShow'] ; i++)
+ this.player.popcorn.listen('pause', function()
{
- this.currentSearchGesture[i] = '';
- }
+ //Si la pause est naturelle (fin de la timeline, dézoom, déplacement vers un voisin).
+ if(!_this.userPaused)
+ {
+ //Si c'est en mode sans utilisateur.
+ if(_this.currentMode == 'NO-USER')
+ {
+ //On dézoome.
+ _this.unzoom();
+ }
+ //Sinon, si ce n'est pas causé par un déplacement ou un dézoom.
+ else if(!_this.currentlyMoving && !_this.currentlyUnzooming)
+ {
+ //Si on est en mode timeline et qu'on est en pause, c'est probablement que l'user a placé le curseur à la fin.
+ if(_this.currentMode != 'TIMELINE')
+ {
+ _this.playNextVideo();
+ }
+ }
+ }
+ });
- this.removeNotifications();
- this.isMosaicFiltered = false;
- this.isCurrentlyInASearchByGesture = false;
- $('#mainPointer').fadeTo(this.config['timePrezoom'], 0);
- $('#secondPointer').fadeTo(this.config['timePrezoom'], 0);
- $('#spinner').remove();
- this.deselectAllNeighbours();
- $('.prezoomContainers').remove();
+ //Si les marqueurs ont été chargés.
+ this.player.popcorn.on("markersready", function()
+ {
+ _this.onMarkersReady();
+ });
}
- // console.log('n : ' + n);
- if(n >= this.config['imagesToShow'])
+}
+
+/*
+ * Fonction qui s'exécute lorsque les marqueurs d'une video on été placés.
+ * Est appelé dans le fichier :
+ * mosaic > fonction onPlayerLoad.
+*/
+Mosaic.prototype.onMarkersReady = function()
+{
+ var _this = this;
+
+ //Le player est prêt.
+ this.playerIsReady = true;
+
+ if(this.player.widgets[0])
{
- // this.unzoom();
- if(this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING-") > -1)
+ //On spécifie à la timeline dans quel mode d'intéraction on est.
+ this.player.widgets[0].setMouseInteractions(this.config.mouseInteractions);
+ //Idem pour la langue.
+ if(this.gesturesText.length > 0)
{
- if(!this.mouseInteractions)
- {
- this.currentMode = "INCOMING-20";
- this.unzoom();
- }
-
- this.currentMode = "MOSAIC";
- this.removeNotifications();
- this.mosaicSelectionAndSearch();
- clearTimeout(this.nouserTimeout);
- console.log('OK');
+ this.player.widgets[0].setLang(this.gesturesText);
}
- //On affiche les notifications.
- // this.notifySelectionSearchMosaicFull();
-
- //$('#mainPointer').fadeTo(this.config['timePrezoom'], 1);
- //$('#secondPointer').fadeTo(this.config['timePrezoom'], 1);
}
- //Pour les snapshots à afficher.
- for(var i = 0 ; i < n ; i++)
+ //Si on est en mode video ou recherche ou timeline.
+ if(this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH' || this.currentMode == 'TIMELINE')
+ {
+ //On peut faire des swipes.
+ this.canSwipe = true;
+ }
+
+ //Si aucune recherche par gesture n'est effectuée.
+ if(this.currentSearchGesture[this.centerId] == '')
{
- //Si les snapshots ne sont pas affichés.
- if($('#snapshotDiv-' + this.fillingIds[i]).css('opacity') < 1)
+ //On enlève le filtre.
+ this.removeFilter();
+ }
+ //Sinon.
+ else
+ {
+ //On entre en mode recherche dans une vidéo.
+ this.currentMode = 'SEARCH';
+ //On recherche la gesture.
+ this.player.widgets[0].searchByGesture(this.currentSearchGesture[this.centerId]);
+ this.isCurrentlyInASearchByGesture = this.player.widgets[0].isCurrentlyInASearchByGesture;
+
+ //On va au premier marqueur trouvé.
+ if(this.timeToGoAt[this.centerId] === 0 && this.player.widgets[0].atLeastOneSearchMarker(this.currentSearchGesture[this.centerId]))
{
- //On les fait apparaître.
- $('#snapshotDiv-' + this.fillingIds[i]).fadeTo(this.config['timeFilling'], '1');
+ this.player.widgets[0].goToFirstSearchedMarker(this.currentSearchGesture[this.centerId]);
}
- }
- //Pour ceux à masquer.
- for(var i = n ; i < this.config['imagesToShow'] ; i++)
- {
- //Si les snapshots ne sont pas masqués et qu'il ne s'agit pas du dernier snapshot en lecture aléatoire (mode NO-USER).
- if($('#snapshotDiv-' + this.fillingIds[i]).css('opacity') > 0 && this.fillingIds[i] != this.currentRandomVideoIdx)
+ //Si aucun marqueur n'est trouvé.
+ else
{
- //On les masque.
- $('#snapshotDiv-' + this.fillingIds[i]).fadeTo(this.config['timeFilling'], '0');
+ //On va juste là où on était la dernière fois qu'on a joué la vidéo.
+ this.player.popcorn.currentTime(this.timeToGoAt[this.centerId]);
}
}
}
/*
- * Gère les événements de contrôle dans la mosaïque.
+ * Chargement du player basé sur le metadataplayer.
+ * Est appelé dans les fichiers :
+ * neighbours > fonction moveToNeighbour.
+ * zoomInteractions > zoom.
*/
-mosaic.prototype.manageControlEvents = function(event)
+Mosaic.prototype.loadPlayer = function(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, zoomTop, zoomLeft, timeToGo)
{
- // console.log('manage');
-
- var _this = this;
-
- if(typeof event === 'undefined')
- {
- return;
- }
-
- var gestureReceived = '';
-
- if(event.indexOf("INCOMING-") != -1 && this.prephaseEnabled)
- {
- // console.log(this.date() + ' ' + event);
- // console.log('CAN START : ' + this.canStart);
- if(this.canStart)
- {
- if(this.snapshotsToShow > this.config['imagesToShow'])
- {
- this.snapshotsToShow = this.config['imagesToShow'];
- }
- else
- {
- var params = event.split('-');
- // console.log(event);
- this.snapshotsToShow = params[1];
- }
-
- //Si la position de l'utilisateur a changé.
- if(event != this.lastIncomingMessage)
- {
- console.log(this.snapshotsToShow);
- this.lastIncomingMessage = event;
- this.showNImages(this.snapshotsToShow);
- }
- }
-
- clearTimeout(this.nouserTimeout);
- this.nouserTimeout = setTimeout(function()
- {
- /*_this.showNImages(0);
- _this.init();
- _this.canStart = false;
- _this.currentMode = "NO-USER";*/
-
- window.location.reload();
- // mos = new mosaic('./config.json', default_parameters);
-
- console.log('NOUSER');
- }, this.config['timeoutNouser']);
- }
- else if((event == "NO-USER" || event == "INCOMING-0" || event == "INCOMING-1") && this.prephaseEnabled)
- {
- /*this.showNImages(0);
- this.init();
- this.canStart = false;
- this.currentMode = "NO-USER";*/
-
- window.location.reload();
- // mos = new mosaic('./config.json', default_parameters);
-
- console.log('NOUSER');
-
- /*this.currentMode = "NO-USER";
- this.showNImages(0);
- this.canStart = false;
- this.init();*/
- }
- // /!\/!\ //
- else if(event.indexOf("SWIPE") != -1)
- {
- if(this.player && this.player.widgets && this.playerIsReady && !this.isSwipe)
- {
- this.isSwipe = true;
-
- if(this.currentMode == 'SEARCH' && this.isMosaicFiltered && !this.player.widgets[0].isAMarkerAhead(this.currentSearchGesture[this.centerId]))
- {
- this.playNextVideo();
- }
-
- //L'utilisateur a fait un swipe left.
- if(event.indexOf("LEFT") != -1)
- {
- this.player.widgets[0].switchToMarker(true, this.currentSearchGesture[this.centerId]);
- if(this.currentMode == 'VIDEO')
- {
- this.removeNotifications();
- this.videoSwipe('left');
- }
- else if(this.currentMode == 'SEARCH' && !this.currentSearchGesture[this.centerId])
- {
- this.removeNotifications();
- this.searchSearchAndSwipe('left');
- }
- else if(this.currentMode == 'SEARCH' && this.currentSearchGesture[this.centerId])
- {
- this.removeNotifications();
- this.searchGestureAndSwipe(this.currentSearchGesture[this.centerId], 'valid', 'left');
- }
- }
- //L'utilisateur a fait un swipe right.
- else if(event.indexOf("RIGHT") != -1)
- {
- this.player.widgets[0].switchToMarker(false, this.currentSearchGesture[this.centerId]);
- if(this.currentMode == 'VIDEO')
- {
- this.removeNotifications();
- this.videoSwipe('right');
- }
- else if(this.currentMode == 'SEARCH' && !this.currentSearchGesture[this.centerId])
- {
- this.removeNotifications();
- this.searchSearchAndSwipe('right');
- }
- else if(this.currentMode == 'SEARCH' && this.currentSearchGesture[this.centerId])
- {
- this.removeNotifications();
- this.searchGestureAndSwipe(this.currentSearchGesture[this.centerId], 'valid', 'right');
- }
- }
-
- //On le fait disparaitre au bout d'un certain temps.
- this.notifySwipeTimeout = setTimeout(function()
- {
- _this.isSwipe = false;
-
- // /!\ //
- _this.removeNotifications();
-
- if(_this.currentMode == 'SEARCH' && !_this.currentSearchGesture[_this.centerId])
- {
- _this.searchSearch();
- }
- else if(_this.currentMode == 'SEARCH' && _this.currentSearchGesture[_this.centerId])
- {
- _this.searchGesture(_this.currentSearchGesture[_this.centerId], 'valid');
- }
-
- }, this.config['timeoutNotifySwipe']);
- }
- }
- else if(event.indexOf("BEND") != -1 || event.indexOf('KNEE-UP') != -1 || event.indexOf('FALL') != -1 || event.indexOf('JUMP') != -1)
- {
- gestureReceived = event.toLowerCase();
- gestureReceived = gestureReceived.replace('wave', 'hello');
- this.currentSearchGesture[centerId] = gestureReceived;
- }
- else if(event.indexOf("HELLO") != -1 && this.canNotifyHelp && !this.areBothPointersHere)
- {
- if(this.currentMode == 'SEARCH')
- {
- this.notifyHelp(false);
- }
- else if(this.currentMode == 'FILTER')
- {
- this.notifyHelp(true);
- }
- }
-
- if(gestureReceived != '')
- {
- if(this.currentMode == "SEARCH" && this.playerIsReady)
- {
- this.player.widgets[0].searchByGesture(gestureReceived);
- this.isCurrentlyInASearchByGesture = this.player.widgets[0].isCurrentlyInASearchByGesture;
-
- this.removeNotifications();
- this.searchGesture(gestureReceived, 'valid');
- }
- else if(this.currentMode == "FILTER")
- {
- if(this.isMosaicFiltered)
- {
- // console.log('FILTER !!!');
- // this.notifySearch1Gesture(gestureReceived, 'valid');
- this.removeNotifications();
- this.filterGesture(gestureReceived, 'valid');
- this.searchFilter(gestureReceived);
- }
- }
-
- if(this.helpDisplayed)
- {
- this.removeHelp();
- }
- }
- // /!\/!\ //
-}
-
-/*
- * Chargement du player basé sur le metadataplayer.
-*/
-mosaic.prototype.loadPlayer = function(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, zoomTop, zoomLeft, timeToGo)
-{
- var _this = this;
-
- //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];
-
- var _metadata = {
- url: currentMetadata,
- format: 'ldt'
- };
-
- var _config = {
- gui: {
- zoomTop: zoomTop - this.marginWidth*2,
- zoomLeft: zoomLeft,
- 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);
-
- this.player.onLoad(function()
- {
- if(_this.currentMode == 'NO-USER')
- {
- //On peut s'approcher de la kinect.
- _this.canStart = true;
- console.log('CAN START !');
- // console.log(_this.player);
- // console.log(_this.player.popcorn);
- }
-
- //Lorsque le player est en pause (par exemple lorsque le curseur arrive à la fin de la timeline).
- if(_this.player.popcorn)
- {
- _this.player.popcorn.listen('pause', function()
- {
- //Si l'utilisateur a mis en pause.
- if(_this.userPaused)
- {
-
- }
- //Si la pause est naturelle (fin de la timeline, dézoom, déplacement vers un voisin).
- else
- {
- //Si c'est en mode sans utilisateur.
- if(_this.currentMode == 'NO-USER')
- {
- //On dézoome.
- _this.unzoom();
- }
- //Sinon.
- else
- {
- //Si ce n'est pas causé par un déplacement ou un dézoom.
- if(!_this.currentlyMoving && !_this.currentlyUnzooming)
- {
- //On réinitialise la position du curseur à la prochaine lecture de la vidéo.
- console.log('REINIT');
- //On passe a la video suivante.
- console.log('AUTOMOVE');
-
- //Si on est en mode timeline et qu'on est en pause, c'est probablement que l'user a placé le curseur à la fin.
- if(_this.currentMode != 'TIMELINE')
- {
- _this.playNextVideo();
- }
- //_this.timeToGoAt[parseInt(_this.centerId)] = 0;
- console.log('time to go at to 0');
- // return;
- }
- }
- }
- });
- // console.log('mosaic filtered : ' + _this.isMosaicFiltered);
-
- _this.player.popcorn.on("markersready", function()
- {
- _this.playerIsReady = true;
-
- if(_this.player.widgets[0])
- {
- _this.player.widgets[0].setMouseInteractions(_this.mouseInteractions);
- if(_this.gesturesText.length > 0)
- {
- _this.player.widgets[0].setLang(_this.gesturesText);
- }
- }
-
- if(_this.currentMode == 'VIDEO' || _this.currentMode == 'SEARCH' || _this.currentMode == 'TIMELINE')
- {
- _this.canSwipe = true;
- }
-
- console.log('TIME TO GO AT : ' + _this.timeToGoAt[_this.centerId], _this.centerId, _this.imgs[_this.centerId]);
-
- // if(_this.isMosaicFiltered)
- // {
- if(_this.currentSearchGesture[_this.centerId] == '')
- {
- _this.removeFilter();
- }
- else
- {
- _this.currentMode = 'SEARCH';
- // console.log(_this.currentSearchGesture);
- _this.player.widgets[0].searchByGesture(_this.currentSearchGesture[_this.centerId]);
- _this.isCurrentlyInASearchByGesture = _this.player.widgets[0].isCurrentlyInASearchByGesture;
-
- if(_this.timeToGoAt[_this.centerId] === 0 && _this.player.widgets[0].atLeastOneSearchMarker(_this.currentSearchGesture[_this.centerId]))
- {
- _this.player.widgets[0].goToFirstSearchedMarker(_this.currentSearchGesture[_this.centerId]);
- }
- else
- {
- _this.player.popcorn.currentTime(_this.timeToGoAt[_this.centerId]);
- }
- }
- // }
- // /!\ //
- /*else
- {
- if(_this.player.popcorn)
- {
- _this.player.popcorn.currentTime(_this.timeToGoAt[_this.centerId]);
- }
- }*/
- });
- }
- });
-}
-
-/*
- * 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)
+ var _this = this;
+
+ //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];
+
+ var _metadata = {
+ url: currentMetadata,
+ format: 'ldt'
+ };
+
+ var _config = {
+ gui: {
+ zoomTop: zoomTop - this.marginWidth*2,
+ zoomLeft: zoomLeft,
+ 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(
{
- return false;
- }
- for (var i=0; i<this .length; i++)
+ position: 'absolute',
+ 'background-color': '#000000',
+ top: newZoomTop,
+ left: newZoomLeft
+ });
+
+ //On démarre le player.
+ this.player = null;
+
+ this.player = new IriSP.Metadataplayer(_config, _metadata);
+
+ this.player.onLoad(function()
{
- if (this[i]!==compareTo[i])
- {
- return false;
- }
- }
- return true;
+ _this.onPlayerLoad();
+ });
}
/*
* Charge les vidéos, les snapshots et les annotations depuis un fichier json.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadParameters.
*/
-mosaic.prototype.loadFromJson = function(path)
+Mosaic.prototype.loadFromJson = function(path)
{
- var _this = this;
- var i = 0;
-
- $.getJSON(path, function(data)
- {
- $.each(data, function(key, val)
- {
- $.each(val, function(key_video, val_video)
- {
- $.getJSON(val_video.metadata, function(meta)
- {
- if(_this.config['local'] == 'true')
- {
- _this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://media.iri.centrepompidou.fr/ddc_player/', './player/videos/').replace('mp4:', '').replace('video/', '').replace('ldtplatform/', '').replace('.m4v', '.mp4'));
- // console.log(meta.medias[0].url.replace('rtmp://media.iri.centrepompidou.fr/ddc_player/', './player/videos/').replace('mp4:', '').replace('video/', '').replace('ldtplatform/', '').replace('.m4v', '.mp4'));
- }
- else
- {
- _this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/').replace('mp4:', '').replace('.m4v', '.mp4'));
- // console.log(meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/').replace('mp4:', '').replace('.m4v', '.mp4'));
- }
- });
- _this.imgs[_this.ids[i]] = val_video.snapshot;
- _this.urls[_this.ids[i]] = val_video.metadata;
- //Au départ, on commence à 0 ms dans les vidéos.
- _this.timeToGoAt[_this.ids[i]] = 0;
- // console.log('ids : ' + _this.ids[i]);
- i++;
- });
- });
- // console.log('rdy');
- _this.loadMosaic();
- });
+ var _this = this;
+ var i = 0;
+
+ //On ouvre le fichier contenant les vidéos et les adresses des métadonnées.
+ $.getJSON(path, function(data)
+ {
+ $.each(data, function(key, val)
+ {
+ $.each(val, function(key_video, val_video)
+ {
+ //On extrait les métadonnées.
+ $.getJSON(val_video.metadata, function(meta)
+ {
+ //Si on est en chargement local.
+ if(_this.config.local)
+ {
+ //On cherche les vidéos dans les métadonnées.
+ _this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://media.iri.centrepompidou.fr/ddc_player/', './player/videos/').replace('mp4:', '').replace('video/', '').replace('ldtplatform/', '').replace('.m4v', '.mp4'));
+ }
+ //Si on est en chargement en ligne.
+ else
+ {
+ //On met l'adresse des videos en ligne.
+ _this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/').replace('mp4:', '').replace('.m4v', '.mp4'));
+ }
+ });
+
+ //On affecte les images et métadonnées.
+ _this.imgs[_this.ids[i]] = val_video.snapshot;
+ _this.urls[_this.ids[i]] = val_video.metadata;
+ //Au départ, on commence à 0 ms dans les vidéos.
+ _this.timeToGoAt[_this.ids[i]] = 0;
+ i++;
+ });
+ });
+
+ //On charge la mosaique.
+ _this.loadMosaic();
+ });
}
/*
- * Affecte une vidéo au tableau des vidéos selon son id
+ * Affecte une vidéo au tableau des vidéos selon son id.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadFromJson.
*/
-mosaic.prototype.affectVideoById = function(metadata_id, video)
+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;
- }
- }
+ for (i = 0 ; i < this.urls.length ; i++)
+ {
+ if(this.urls[i] == metadata_id)
+ {
+ this.videos[i] = video;
+ break;
+ }
+ }
}
/*
- * Rebind keypress pour body.
+ * Affiche la date actuelle pour l'affichage de messages dans la console.
+ * Est appelé dans chaque console.log() où on veut afficher la date à laquelle l'instruction est exécutée.
*/
-mosaic.prototype.reaffectKeyPress = function()
-{
- var _this = this;
-
- $('body').keypress(function (event)
- {
- _this.manageControlEvents(event);
- });
-}
-
-mosaic.prototype.date = function()
+Mosaic.prototype.date = function()
{
var date, h, min, s;
date = new Date();