diff -r 8393d3473b98 -r 0e29ae4568a0 front_idill/src/mosaic/js/mosaic.js --- a/front_idill/src/mosaic/js/mosaic.js Fri Jun 29 16:16:24 2012 +0200 +++ b/front_idill/src/mosaic/js/mosaic.js Thu Jul 05 16:04:33 2012 +0200 @@ -25,11 +25,11 @@ function mosaic(config, default_conf) { //Interactions souris/kinect. - this.mouseInteractions = false; + 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"]; + 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; @@ -47,6 +47,9 @@ this.fillingIds = []; this.currentRandomVideoIdx = 0; + //Dictionnaire pour les courbes de recherche. + this.dictionary = []; + //Dernières positions des pointeurs. this.mainPointerLastX; this.mainPointerLastY; @@ -58,6 +61,15 @@ 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; @@ -68,95 +80,103 @@ this.marginWidth; //Booléens permettant ou non certaines intéractions selon le contexte. - this.zoomed; - this.fullscreen; - this.canMoveToNeighbour; - this.mainPointerExitBorder; - this.secondPointerExitBorder; - this.isMainPointerDisplayed; - this.isSecondPointerDisplayed; - this.helpDisplayed; + 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; + this.userPaused = false; //Indique si on est en train de se déplacer vers un voisin. - this.currentlyMoving; + this.currentlyMoving = false; //Indique si on est en train de dézoomer vers la mosaïque. - this.currentlyUnzooming; + this.currentlyUnzooming = false; //Indique si on peut s'approcher de kinect. - this.canStart; + this.canStart = false; //Indique si on est actuellement sur un snapshot. - this.isOnASnapshot; + this.isOnASnapshot = false; //Indique si l'idle des pointeurs est disponible (deux mains détectées). - this.pointersIdleAvailable; + this.pointersIdleAvailable = false; //Indique si le timeout pour l'idle des pointeurs à besoin d'être lancé. - this.pointersIdleNeedLaunch; + this.pointersIdleNeedLaunch = false; //Indique si les deux mains sont là. - this.areBothPointersHere; + this.areBothPointersHere = false; //Indique si le timeout pour la détection de deux pointeurs a été lancé. - this.areBothPointersTimeoutLaunched; + this.areBothPointersTimeoutLaunched = false; //Indique si la mosaïque a été filtrée. - this.isMosaicFiltered; + this.isMosaicFiltered = false; //Indique si on est actuellement dans une recherche par gesture. - this.isCurrentlyInASearchByGesture; + this.isCurrentlyInASearchByGesture = false; //Indique si un pointeur est déjà sur une notification de recherche par gesture. - this.alreadyOnNotification; + this.alreadyOnNotification = false; //Si on a fait un swipe. - this.isSwipe; + this.isSwipe = false; //On peut swiper. - this.canSwipe; + this.canSwipe = false; //On passe vers une autre video automatiquement à la fin d'une lecture. - this.autoMove; + this.autoMove = false; //Si l'utilisateur a demandé à sélectionner la TL. - this.isTLRequested; + this.isTLRequested = false; //Le pointeur gauche a sélectionné la TL. - this.isTLSelectedBySecondPointer; + this.isTLSelectedBySecondPointer = false; //Le pointeur droit a sélectionné la TL. - this.isTLSelectedByMainPointer; + this.isTLSelectedByMainPointer = false; //On peut afficher l'aide. - this.canNotifyHelp; + this.canNotifyHelp = false; //Indique si la mosaique est en train d'être filtrée. - this.isMosaicFiltering; + this.isMosaicFiltering = false; this.arrowLeftLoading = false; this.arrowRightLoading = false; this.arrowUpLoading = false; this.arrowDownLoading = false; //On est dans une recherche par courbes. - this.isSearchByCurvesOn; + 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 = ''; //Timeout (attente) pour le zoom après un préZoom. - this.zoomTimeout; + this.zoomTimeout = null; //Timeout (attente) pour le passage vers un voisin. - this.moveToNeighbourTimeout; - this.mainPointerExitBorderTimeout; - this.secondPointerExitBorderTimeout; + 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; + this.pointersSearchIdleTimeout = null; //Vérifie toutes les N ms que les deux pointeurs sont détectés. - this.areBothPointersHereTimeout; + this.areBothPointersHereTimeout = null; //Délai de suppression d'une notification de recherche par gesture. - this.removeNotificationByGestureTimeout; + this.removeNotificationByGestureTimeout = null; //Délai de suppression d'une notification de recherche par gesture infructueuse. - this.removeFailedNotificationByGestureTimeout; + this.removeFailedNotificationByGestureTimeout = null; //Délai avant la suppression de notification swipe. - this.notifySwipeTimeout; + this.notifySwipeTimeout = null; //Délai pour la sélection de la TL. - this.selectTLTimeout; + this.selectTLTimeout = null; //Délai pour slider sur la TL. - this.canSlideInTLTimeout; + this.canSlideInTLTimeout = null; //Délai pour afficher l'aide. - this.canNotifyHelpTimeout; - this.arrowLeftTimeout; - this.arrowRightTimeout; - this.arrowUpTimeout; - this.arrowDownTimeout; + this.canNotifyHelpTimeout = null; + this.arrowLeftTimeout = null; + this.arrowRightTimeout = null; + this.arrowUpTimeout = null; + this.arrowDownTimeout = null; - this.arrowSpinnerTimeout; - this.nouserTimeout; - this.nextDrawCurveTimeout; + this.arrowSpinnerTimeout = null; + this.nouserTimeout = null; + this.nextDrawCurveTimeout = null; //Dernier message INCOMING (pour éviter d'effectuer n fois la même action. - this.lastIncomingMessage; + this.lastIncomingMessage = ''; //Type de marqueur recherché dans la mosaïque (en mode filter). this.filterSearchedType = ""; @@ -165,8 +185,10 @@ 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; + this.previousId = null; //Dernier snapshot prézoomé non null. this.lastNonNullSN = null; //Largeur de la marge pour le centrage vertical de la mosaïque. @@ -174,8 +196,8 @@ this.top_margin; //Gesture actuellement cherchée. - this.currentSearchGesture; - + this.currentSearchGesture = ''; + //Mosaïque locale. this.localMos; //Position des voisins lors d'un zoom. @@ -191,9 +213,9 @@ this.snapshotsToShow = 1; //Lecteur. - this.player; + this.player = null; //Si le lecteur est prêt. - this.playerIsReady; + this.playerIsReady = false; //Annotations (pour les marqueurs los d'un filtrage). this.annotations = []; @@ -240,34 +262,6 @@ //S'il s'agit d'un rectangle. if(imgs % len == 0) { - this.previousZoomedSN = null; - this.previousPrezoomDiv = null; - this.fullscreen = false; - this.canMoveToNeighbour = false; - this.currentlyZooming = false; - this.currentlyUnzooming = false; - this.helpDisplayed = false; - this.canStart = false; - this.isOnASnapshot = false; - this.isMosaicFiltered = false; - this.areBothPointersHere = false; - this.areBothPointersTimeoutLaunched = false; - this.isCurrentlyInASearchByGesture = false; - this.alreadyOnNotification = false; - this.playerIsReady = false; - this.currentSearchGesture = ''; - this.isMainPointerDisplayed = false; - this.isSecondPointerDisplayed = false; - this.isSwipe = false; - this.canSwipe = false; - this.autoMove = false; - this.isTLRequested = false; - this.isTLSelectedByMainPointer = false; - this.isTLSelectedBySecondPointer = false; - this.canNotifyHelp = false; - this.isMosaicFiltering = false; - this.isSearchByCurvesOn = false; - this.lastIncomingMessage = 'INCOMING-0'; var str = ''; @@ -281,7 +275,7 @@ } } - return str; + return str + '
'; } else { @@ -307,6 +301,7 @@ //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. @@ -326,7 +321,6 @@ //On fait coincider le background du body avec celui de la mosaïque. $('body').css('background-position', '0px ' + this.MPTop_margin + 'px'); - console.log(this.MPTop_margin); /*$('.snapshotDivs').mouseover(function () { @@ -374,12 +368,15 @@ //Si on gère les interactions à la souris. if(_this.mouseInteractions) { - $('body').mousemove(function(e){_this.refreshMainPointer(e.pageX, e.pageY, _this)}); + $('body').mousemove(function(e) + { + _this.refreshMainPointer(e.pageX, e.pageY, _this); + _this.mousePosX = e.pageX; + _this.mousePosY = e.pageY; + }); } - // if(false) - // { - if(_this.prephaseEnabled) + if(_this.prephaseEnabled && !_this.mouseInteractions) { _this.init(); _this.showNImages(0); @@ -390,7 +387,6 @@ _this.showNImages(20); _this.currentMode = "MOSAIC"; } - // } // /!\ // // _this.currentMode = "FILTER"; @@ -408,6 +404,197 @@ } }); } + + if(this.mouseInteractions) + { + //On bind le clic pour supprimer une recherche. + $('body').click(function(e) + { + _this.removeSearchNotificationIfOnIt(e.pageX, e.pageY); + }); + + //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 () + { + if(_this.isSearchByCurvesOn) + { + _this.searchCanvas.onPointerIn(_this.mousePosX, _this.mousePosY, null, null); + } + + 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) + { + $('.notifications').remove(); + _this.filterSearch(); + } + + _this.searchCanvas.onPointerIn(_this.mousePosX, _this.mousePosY - _this.MPTop_margin, null, null); + } + else if(_this.currentMode == "FILTER" && !_this.isSearchByCurvesOn) + { + 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) + { + $('.notifications').remove(); + _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) + { + 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; + + $('.notifications').remove(); + _this.searchGesture(gesture_match, 'valid'); + _this.curvesGesturesFound = false; + } + else if(_this.currentMode == "FILTER") + { + if(_this.isMosaicFiltered) + { + $('.notifications').remove(); + _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. + $('body').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 != '')//if(_this.currentSearchGesture != '') + { + $('.notifications').remove(); + _this.filterGesture(_this.currentSearchGesture, 'valid'); + } + + }); + }); + } } /* @@ -417,7 +604,7 @@ { 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']; + 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) @@ -489,7 +676,12 @@ } //On initialise le client. - _this.client = new client(_this.config['host'], _this.config['port'], _this); + if(!_this.mouseInteractions) + { + _this.client = new client(_this.config['host'], _this.config['port'], _this); + } + + _this.getDictionary(); }); } @@ -554,8 +746,12 @@ // this.unzoom(); if(this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING-") > -1) { - this.currentMode = "INCOMING-20"; - this.unzoom(); + if(!this.mouseInteractions) + { + this.currentMode = "INCOMING-20"; + this.unzoom(); + } + this.currentMode = "MOSAIC"; $('.notifications').remove(); this.mosaicSelectionAndSearch(); @@ -565,8 +761,8 @@ //On affiche les notifications. // this.notifySelectionSearchMosaicFull(); - // $('#mainPointer').fadeTo(this.config['timePrezoom'], 1); - // $('#secondPointer').fadeTo(this.config['timePrezoom'], 1); + //$('#mainPointer').fadeTo(this.config['timePrezoom'], 1); + //$('#secondPointer').fadeTo(this.config['timePrezoom'], 1); } //Pour les snapshots à afficher. @@ -939,6 +1135,7 @@ // 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) { @@ -987,6 +1184,11 @@ { _this.playerIsReady = true; + if(_this.player.widgets[0]) + { + _this.player.widgets[0].setMouseInteractions(_this.mouseInteractions); + } + if(_this.currentMode == 'VIDEO' || _this.currentMode == 'SEARCH' || _this.currentMode == 'TIMELINE') { _this.canSwipe = true;