')
+ .addClass("Ldt-TimelineMiddle")
.css(this.calculateTimelineMiddleCss(this.minimized_height, this.middle_height));
-
- /*this.$timelineContainer = IriSP.jQuery('
')
- .addClass("Ldt-TimelineContainer");
- this.$timelineContainer.append(this.$timeline);
- this.$timelineContainer.append(this.$timelineMiddle);*/
-
-
+
+ //On l'ajoute au widget.
this.$.append(this.$timeline);
this.$.append(this.$timelineMiddle);
-
+
var _this = this;
+ //On définit le slider.
this.$timeline.slider({
range: "min",
value: 0,
min: 0,
max: this.source.getDuration().milliseconds,
slide: function(event, ui) {
- if(_this.player.popcorn)
- {
- _this.player.popcorn.currentTime(Math.floor(ui.value/1000));
- _this.player.popcorn.trigger("IriSP.Mediafragment.setHashToTime");
- }
-
- // console.log("manual " + _this.previousMarkerIdx);
- //On supprime le marqueur précédemment affiché si c'est le cas.
- if(_this.previousMarkerIdx > -1)
- {
- // /!\ var annotations = _this.source.getAnnotations();
-
- // console.log("EXT hide idx " + _this.previousMarkerIdx);
- // /!\ var previousMarker = IriSP.jQuery("#" + annotations[_this.previousMarkerIdx].id.replace(":", "_"));
- var previousMarker = IriSP.jQuery("#" + _this.annotations[_this.previousMarkerIdx].id.replace(":", "_"));
- _this.hideMarkerBig(previousMarker);
- // console.log("EXT hide " + _this.previousMarkerIdx);
- }
+ if(_this.player.popcorn)
+ {
+ _this.player.popcorn.currentTime(Math.floor(ui.value/1000));
+ _this.player.popcorn.trigger("IriSP.Mediafragment.setHashToTime");
+ }
+
+ //On supprime le marqueur précédemment affiché.
+ if(_this.previousMarkerIdx > -1)
+ {
+ var previousMarker = IriSP.jQuery("#" + _this.annotations[_this.previousMarkerIdx].id.replace(":", "_"));
+ _this.hideMarkerBig(previousMarker);
+ }
}
});
-
+
this.$handle = this.$timeline.find('.ui-slider-handle');
this.$handle.css(this.calculateHandleCss(this.minimized_height));
-
- this.$
- .mouseover(this.functionWrapper("onMouseover"))
- .mouseout(this.functionWrapper("onMouseout"));
- IriSP.jQuery('body').keypress(function(evt) {_this.keyPress(evt)});
+
+ //On wrapp mouseover et mouse out.
+ this.$.mouseover(this.functionWrapper("onMouseover")).mouseout(this.functionWrapper("onMouseout"));
+ //On bind keypress.
+ IriSP.jQuery('body').keypress(function(evt) {_this.keyPress(evt)});
this.maximized = false;
this.timeoutId = false;
@@ -163,856 +170,818 @@
* Starts playing the video when it's ready.
*/
IriSP.Widgets.Timeline.prototype.ready = function() {
- this.player.popcorn.play();
- this.player.popcorn.mute();
- this.processMarkers();
+ this.player.popcorn.play();
+ this.player.popcorn.mute();
+ this.processMarkers();
}
/*
- * Scale a value from [A, B] to [C, D].
+ * Met à l'échelle une valeur de [A, B] vers [C, D].
+ * Est appelé dans les fichiers :
+ * pointers > fonction pointersTimelineSelection.
+ * search > fonction searchFilter.
+ * Timeline > fonctions processMarkers, onTimeupdate et timeDisplayUpdater.
*/
IriSP.Widgets.Timeline.prototype.scaleIntervals = function(A, B, C, D, val) {
- if(C == D)
- {
- return C;
- }
- if(B != A)
- {
- return D / (B - A) * (val - A);
- }
- else
- {
- //If A and B have the same sign.
- if(A * B > 0)
- {
- //If they are positive.
- if(A > 0)
- {
- return (D - C)/2;
- }
- else
- {
- return (C - D)/2;
- }
- }
- else
- {
- return (C + D)/2;
- }
- }
+ if(C == D)
+ {
+ return C;
+ }
+ if(B != A)
+ {
+ return D / (B - A) * (val - A);
+ }
+ else
+ {
+ //Si A et B ont le même signe.
+ if(A * B > 0)
+ {
+ //S'ils sont positifs.
+ if(A > 0)
+ {
+ return (D - C)/2;
+ }
+ else
+ {
+ return (C - D)/2;
+ }
+ }
+ else
+ {
+ return (C + D)/2;
+ }
+ }
}
/*
- * Process the markers.
+ * On calcule les marqueurs.
+ * Est appelé dans le fichier :
+ * Timeline > fonction ready.
*/
IriSP.Widgets.Timeline.prototype.processMarkers = function() {
- var _this = this;
- var markers = "";
- var timelineMiddleTop = this.$timelineMiddle.position().top;
-
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- markers += "
";
- }
-
- this.$.append(markers);
- var markerHeight = IriSP.jQuery(".Ldt-Marker").height();
- IriSP.jQuery(".Ldt-Marker").css("z-align", "150");
-
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- IriSP.jQuery("#" + this.annotations[i].id.replace(":", "_")).css(
- {
- top: timelineMiddleTop + "px",
- left: Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), this.annotations[i].begin/1000) + this.$timeline.position().left) + "px",
- "margin-top": (-_this.$timeline.height()/2 - markerHeight/2) - this.top_epsilon + "px"
- });
- }
-
- //On lance l'événement pour dire à popcorn que les marqueurs sont utilisables.
- // this.player.popcorn.trigger(IriSP.Widgets.Timeline.onMarkersReady);
- this.player.popcorn.trigger("markersready");
- //console.log('markers processed');
+ var _this = this;
+ var markers = "";
+ //On calcule la position en Y de la timeline.
+ var timelineMiddleTop = this.$timelineMiddle.position().top;
+
+ //Pour toutes les annotations, on crée les marqueurs.
+ for(var i = 0 ; i < this.annotations.length ; i++)
+ {
+ markers += "
";
+ }
+
+ //On les ajoute.
+ this.$.append(markers);
+ var markerHeight = IriSP.jQuery(".Ldt-Marker").height();
+ IriSP.jQuery(".Ldt-Marker").css("z-align", "150");
+
+ //Pour toutes les annotations.
+ for(var i = 0 ; i < this.annotations.length ; i++)
+ {
+ //On les place sur la timeline.
+ IriSP.jQuery("#" + this.annotations[i].id.replace(":", "_")).css(
+ {
+ top: timelineMiddleTop + "px",
+ left: Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), this.annotations[i].begin/1000) + this.$timeline.position().left) + "px",
+ "margin-top": (-_this.$timeline.height()/2 - markerHeight/2) - this.top_epsilon + "px"
+ });
+ }
+
+ //On lance l'événement pour dire à popcorn que les marqueurs sont utilisables.
+ this.player.popcorn.trigger("markersready");
}
/*
- * Fonction de recherche par gesures.
+ * Fonction de recherche par gestures.
+ * Est appelé dans les fichiers :
+ * mosaic > fonctions onMouseUp, manageControlEvents et onMarkersReady.
+ * curvesDetector > fonction updateDists.
*/
IriSP.Widgets.Timeline.prototype.searchByGesture = function(typeName)
{
- if(typeName != '' || typeName != undefined)
- {
- if(_.include(this.gestures, typeName))
- {
- this.currentMode = "SEARCH";
- this.hideMarkersSearch(typeName);
- this.isCurrentlyInASearchByGesture = true;
- }
- }
+ //Si le type existe.
+ if(typeName != '' || typeName != undefined)
+ {
+ if(_.include(this.gestures, typeName))
+ {
+ //On entre en mode recherche et on affiche les marqueurs sélectionnés.
+ this.currentMode = "SEARCH";
+ this.hideMarkersSearch(typeName);
+ this.isCurrentlyInASearchByGesture = true;
+ }
+ }
}
/*
* Fonction de suppression de recherche par gesures.
+ * Est appelé dans le fichier :
+ * pointers > checkIfPointerIsOnSearchNotification et removeSearchNotificationIfOnIt.
*/
IriSP.Widgets.Timeline.prototype.removeSearchByGesture = function()
{
- this.hideMarkersSearch();
- this.isCurrentlyInASearchByGesture = false;
+ this.hideMarkersSearch();
+ this.isCurrentlyInASearchByGesture = false;
+}
+
+/*
+ * Place le curseur sur la timeline en fonction de la touche pressée.
+ * Est appelé dans le fichier :
+*/
+IriSP.Widgets.Timeline.prototype.keyPress = function(e) {
+ var key = this.whichKey(e.which);
+ var time = 0;
+
+ //Entre 0 et 10, on met à jour la position du curseur dans la video.
+ if(key > -1 && key < 11)
+ {
+ time = this.source.getDuration().getSeconds()/10*key;
+ this.$timeline.slider("value",time);
+ this.player.popcorn.currentTime(time);
+
+ //On supprime le marqueur précédemment affiché.
+ if(this.previousMarkerIdx > -1)
+ {
+ var previousMarker = IriSP.jQuery("#" + this.annotations[this.previousMarkerIdx].id.replace(":", "_"));
+ this.hideMarkerBig(previousMarker);
+ }
+ }
+
+ //p ou P pour mettre en pause.
+ if(key == 21)
+ {
+ if(!this.paused)
+ {
+ this.paused = true;
+ this.player.popcorn.pause();
+ }
+ else
+ {
+ this.paused = false;
+ this.player.popcorn.play();
+ }
+ }
}
/*
- * Place the cursor on the timeline depending on the keytyped.
+ * Donne une clé correspondante à une touche donnée.
+ * Est appelé dans le fichier :
+ * Timeline > fonction keyPress.
+*/
+IriSP.Widgets.Timeline.prototype.whichKey = function(code) {
+ var key;
+
+ if(code > 47 && code < 58)
+ {
+ return (code - 48);
+ }
+
+ if(code == 115 || code == 83)
+ {
+ return 11;
+ }
+
+ //p ou P pour mettre la vidéo en pause.
+ if(code == 112 || code == 80)
+ {
+ return 21;
+ }
+
+ switch(code)
+ {
+ case 224:
+ key = 0;
+ break;
+ case 38:
+ key = 1;
+ break;
+ case 233:
+ key = 2;
+ break;
+ case 34:
+ key = 3;
+ break;
+ case 39:
+ key = 4;
+ break;
+ case 40:
+ key = 5;
+ break;
+ case 45:
+ key = 6;
+ break;
+ case 232:
+ key = 7;
+ break;
+ case 95:
+ key = 8;
+ break;
+ case 231:
+ key = 9;
+ break;
+ default:
+ key = -1;
+ }
+
+ return key;
+}
+
+/*
+ * Fonction de sélection de la timeline.
+ * Est appelé dans le fichier :
+ * pointers > fonction pointersTimelineSelection.
*/
-IriSP.Widgets.Timeline.prototype.keyPress = function(e) {
- var key = this.whichKey(e.which);
- var time = 0;
-
- // console.log($(this));
-
- if(key > -1 && key < 11)
- {
- time = this.source.getDuration().getSeconds()/10*key;
- this.$timeline.slider("value",time);
- this.player.popcorn.currentTime(time);
-
- //On supprime le marqueur précédemment affiché si c'est le cas.
- if(this.previousMarkerIdx > -1)
- {
- // console.log("EXT hide idx " + this.previousMarkerIdx);
- var previousMarker = IriSP.jQuery("#" + this.annotations[this.previousMarkerIdx].id.replace(":", "_"));
- this.hideMarkerBig(previousMarker);
- // console.log("EXT hide " + this.previousMarkerIdx);
- }
- }
-
- if(key == 11)
- {
- if(!this.timelineSelected)
- {
- this.currentMode = "TIMELINE";
- this.selectTimeline();
- }
- else
- {
- this.currentMode = "VIDEO";
- this.deselectTimeline();
- }
- }
-
- if(key == 12)
- {
- this.hideMarkersSearch();
- }
-
- if(key == 13)
- {
- var gesturesStr = '';
- for(var i = 0 ; i < this.gestures.length ; i++)
- {
- gesturesStr += this.gestures[i] + ", ";
- }
- gesturesStr = gesturesStr.substr(0, gesturesStr.length - 2);
-
- var typeName = prompt("Please enter a type name among (" + gesturesStr + ").", "");
-
- if(typeName != '' || typeName != undefined)
- {
- if(_.include(this.gestures, typeName))
- {
- this.currentMode = "SEARCH";
- this.hideMarkersSearch(typeName);
- }
- }
- }
-
- if(key == 21)
- {
- // console.log(this);
- if(!this.paused)
- {
- this.paused = true;
- this.player.popcorn.pause();
- }
- else
- {
- this.paused = false;
- this.player.popcorn.play();
- }
- }
+IriSP.Widgets.Timeline.prototype.selectTimeline = function() {
+ //On crée les bordures.
+ this.timelineSelected = true;
+ this.$timelineBorderUp = "
";
+ this.$timelineBorderDown = "
";
+ this.$timelineBorderLeft = "
";
+ this.$timelineBorderRight = "
";
+ //Les flèches verticales aussi.
+ this.$arrowUp = "
";
+ this.$arrowDown = "
";
+ //On les ajoute.
+ this.$.append(this.$timelineBorderUp + this.$timelineBorderDown + this.$timelineBorderLeft + this.$timelineBorderRight + this.$arrowUp + this.$arrowDown);
+ //On calcule la position en Y de la timeline.
+ var timelineTop = IriSP.jQuery("#LdtPlayer").position().top + IriSP.jQuery("#LdtPlayer").height();
+ //On met les styles à jour.
+ IriSP.jQuery("#TL_BorderUp").css(
+ {
+ "margin-top": -this.$timeline.height() - this.top_epsilon,
+ left: this.$timeline.position().left,
+ width: this.$timeline.width(),
+ height: this.timelineBorderLength
+ });
+ IriSP.jQuery("#TL_BorderDown").css(
+ {
+ "margin-top": -this.timelineBorderLength - 2 - this.top_epsilon,
+ left: this.$timeline.position().left,
+ width: this.$timeline.width(),
+ height: this.timelineBorderLength
+ });
+ IriSP.jQuery("#TL_BorderLeft").css(
+ {
+ "margin-top": -this.$timeline.height() - this.top_epsilon,
+ left: this.$timeline.position().left,
+ width: this.timelineBorderLength,
+ height: this.$timeline.height()
+ });
+ IriSP.jQuery("#TL_BorderRight").css(
+ {
+ "margin-top": -this.$timeline.height() - this.top_epsilon,
+ left: +this.$timeline.position().left + this.$timeline.width() - this.timelineBorderLength - 2,
+ width: this.timelineBorderLength,
+ height: this.$timeline.height()
+ });
+
+ IriSP.jQuery("#TL_ArrowUp").css(
+ {
+ "background-image": "url(" + this.imgDir + "arrow_up.png)",
+ "margin-top": -this.$timeline.height() - IriSP.jQuery("#TL_ArrowUp").height() - this.top_epsilon,
+ left: this.$timeline.position().left - IriSP.jQuery("#TL_ArrowUp").width()/2,
+ });
+ IriSP.jQuery("#TL_ArrowDown").css(
+ {
+ "background-image": "url(" + this.imgDir + "arrow_down.png)",
+ "margin-top": -this.timelineBorderLength + this.timelineBorderLength - this.top_epsilon,
+ left: this.$timeline.position().left - IriSP.jQuery("#TL_ArrowUp").width()/2,
+ });
+
+ IriSP.jQuery(".Ldt-Timeline .ui-slider-range").css("background-image", "url(" + this.imgDir + "past_timeline.png)");
+}
+
+/*
+ * Déselectionne la timeline.
+ * Est appelé dans le fichier :
+ * playerControl > fonction exitTimeline.
+*/
+IriSP.Widgets.Timeline.prototype.deselectTimeline = function() {
+ //On supprime les éléments qui faisaient que la timeline était sélectionnée.
+ this.timelineSelected = false;
+ IriSP.jQuery(".TL_Borders").remove();
+ IriSP.jQuery(".TL_Arrows").remove();
+ IriSP.jQuery(".Ldt-Timeline .ui-slider-range").css("background-image", "url(" + this.imgDir + "selected_timeline.png)");
}
/*
- * Find the key corresponding to a given code.
+ * Se met à jour durant la lecture d'une video.
+ * Est appelé dans le fichier :
+ * Timeline
*/
-IriSP.Widgets.Timeline.prototype.whichKey = function(code) {
- var key;
-
- console.log(code);
-
- if(code > 47 && code < 58)
- {
- return (code - 48);
- }
-
- if(code == 115 || code == 83)
- {
- return 11;
- }
-
- //m ou M pour quitter une recherche.
- if(code == 109 || code == 77)
- {
- return 12;
- }
-
- //p ou P pour mettre la vidéo en pause.
- if(code == 112 || code == 80)
- {
- return 21;
- }
-
- //n ou N pour une recherche par type.
- if(code == 110 || code == 78)
- {
- return 13;
- }
-
- switch(code)
- {
- case 224:
- key = 0;
- break;
- case 38:
- key = 1;
- break;
- case 233:
- key = 2;
- break;
- case 34:
- key = 3;
- break;
- case 39:
- key = 4;
- break;
- case 40:
- key = 5;
- break;
- case 45:
- key = 6;
- break;
- case 232:
- key = 7;
- break;
- case 95:
- key = 8;
- break;
- case 231:
- key = 9;
- break;
- default:
- key = -1;
- }
-
- return key;
+IriSP.Widgets.Timeline.prototype.onTimeupdate = function() {
+ //On récupère la position du curseur en secondes.
+ var _time = this.player.popcorn.currentTime();
+ //Position des flèches au cas où la timeline serait sélectionnée.
+ var arrowLeft = Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), _time) + this.$timeline.position().left) - IriSP.jQuery("#TL_ArrowUp").width()/2 + "px";
+ //On met à jour la position du slider en ms.
+ this.$timeline.slider("value",_time*1000);
+ //On affiche les flèches si la timeline est sélectionnée.
+ IriSP.jQuery(".TL_Arrows").css("display", "block");
+ IriSP.jQuery("#TL_ArrowUp").css("left", arrowLeft);
+ IriSP.jQuery("#TL_ArrowDown").css("left", arrowLeft);
+
+ //Si on a une distance de 500 ms à un marqueur, on l'affiche.
+ var nearestMarkerIdx = 0;
+ for(var i = 0 ; i < this.annotations.length ; i++)
+ {
+ //S'il existe des marqueurs dans l'intervalle de temps actuel (ici 500ms).
+ if(Math.abs(_time*1000 - this.annotations[i].begin.milliseconds) <= 250)
+ {
+ //On sélectionne le plus proche marqueur (dans les cas où il en existe plusieurs dans l'intervalle des 1s) ou bien le premier marqueur.
+ if(Math.abs(_time*1000 - this.annotations[i].begin.milliseconds) < Math.abs(_time*1000 - this.annotations[nearestMarkerIdx].begin.milliseconds) || i == nearestMarkerIdx)
+ {
+ //Si le prochain marqueur se situe après le curseur de lecture, on passe donc au marqueur le plus proche.
+ if(_time*1000 < this.annotations[i].begin.milliseconds)
+ {
+ nearestMarkerIdx = i;
+ //S'il y a un changement de marqueur (marqueur actuel différent du précédent).
+ if(nearestMarkerIdx != this.previousMarkerIdx)
+ {
+ var currentMarker = IriSP.jQuery("#" + this.annotations[nearestMarkerIdx].id.replace(":", "_"));
+ //S'il existe un marqueur précédent, on le cache.
+ if(this.previousMarkerIdx > -1)
+ {
+ var previousMarker = IriSP.jQuery("#" + this.annotations[this.previousMarkerIdx].id.replace(":", "_"));
+ this.hideMarkerBig(previousMarker);
+ }
+
+ this.showMarkerBig(currentMarker, this.annotations[nearestMarkerIdx].annotationType.contents.title);
+ //Mise à jour du marqueur précédent s'il y a un changement.
+ this.previousMarkerIdx = nearestMarkerIdx;
+ }
+ }
+ }
+ this.currentMarkerIdx = nearestMarkerIdx;
+ }
+ }
}
-IriSP.Widgets.Timeline.prototype.selectTimeline = function() {
- this.timelineSelected = true;
- this.$timelineBorderUp = "
";
- this.$timelineBorderDown = "
";
- this.$timelineBorderLeft = "
";
- this.$timelineBorderRight = "
";
-
- this.$arrowUp = "
";
- this.$arrowDown = "
";
-
- this.$.append(this.$timelineBorderUp + this.$timelineBorderDown + this.$timelineBorderLeft + this.$timelineBorderRight + this.$arrowUp + this.$arrowDown);
-
- var timelineTop = IriSP.jQuery("#LdtPlayer").position().top + IriSP.jQuery("#LdtPlayer").height();
-
- IriSP.jQuery("#TL_BorderUp").css(
- {
- "margin-top": -this.$timeline.height() - this.top_epsilon,
- left: this.$timeline.position().left,
- width: this.$timeline.width(),
- height: this.timelineBorderLength
- });
- IriSP.jQuery("#TL_BorderDown").css(
- {
- "margin-top": -this.timelineBorderLength - 2 - this.top_epsilon,
- left: this.$timeline.position().left,
- width: this.$timeline.width(),
- height: this.timelineBorderLength
- });
- IriSP.jQuery("#TL_BorderLeft").css(
- {
- "margin-top": -this.$timeline.height() - this.top_epsilon,
- left: this.$timeline.position().left,
- width: this.timelineBorderLength,
- height: this.$timeline.height()
- });
- IriSP.jQuery("#TL_BorderRight").css(
- {
- "margin-top": -this.$timeline.height() - this.top_epsilon,
- left: +this.$timeline.position().left + this.$timeline.width() - this.timelineBorderLength - 2,
- width: this.timelineBorderLength,
- height: this.$timeline.height()
- });
-
- IriSP.jQuery("#TL_ArrowUp").css(
- {
- "background-image": "url(" + this.imgDir + "arrow_up.png)",
- "margin-top": -this.$timeline.height() - IriSP.jQuery("#TL_ArrowUp").height() - this.top_epsilon,
- left: this.$timeline.position().left - IriSP.jQuery("#TL_ArrowUp").width()/2,
- });
- IriSP.jQuery("#TL_ArrowDown").css(
- {
- "background-image": "url(" + this.imgDir + "arrow_down.png)",
- "margin-top": -this.timelineBorderLength + this.timelineBorderLength - this.top_epsilon,
- left: this.$timeline.position().left - IriSP.jQuery("#TL_ArrowUp").width()/2,
- });
-
- IriSP.jQuery(".Ldt-Timeline .ui-slider-range").css("background-image", "url(" + this.imgDir + "past_timeline.png)");
-}
-
-IriSP.Widgets.Timeline.prototype.deselectTimeline = function() {
- this.timelineSelected = false;
- IriSP.jQuery(".TL_Borders").remove();
- IriSP.jQuery(".TL_Arrows").remove();
- IriSP.jQuery(".Ldt-Timeline .ui-slider-range").css("background-image", "url(" + this.imgDir + "selected_timeline.png)");
+/*
+ * Met à jour l'affichage régulièrement.
+ * Est appelé dans le fichier :
+ * Timeline
+*/
+IriSP.Widgets.Timeline.prototype.timeDisplayUpdater = function() {
+ //On récupère la position du curseur en secondes.
+ var _time = this.player.popcorn.currentTime();
+ //Position des flèches au cas où la timeline serait sélectionnée.
+ var arrowLeft = Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), _time) + this.$timeline.position().left) -
+ this.$timeline.slider("value",_time*1000);
+ //On affiche les flèches si la timeline est sélectionnée.
+ IriSP.jQuery(".TL_Arrows").css("display", "block");
+ IriSP.jQuery("#TL_ArrowUp").css("left", arrowLeft);
+ IriSP.jQuery("#TL_ArrowDown").css("left", arrowLeft);
}
-IriSP.Widgets.Timeline.prototype.onTimeupdate = function() {
- var _time = this.player.popcorn.currentTime();
- var arrowLeft = Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), _time) + this.$timeline.position().left) - IriSP.jQuery("#TL_ArrowUp").width()/2 + "px";
-
- this.$timeline.slider("value",_time*1000);
- IriSP.jQuery(".TL_Arrows").css("display", "block");
- IriSP.jQuery("#TL_ArrowUp").css("left", arrowLeft);
- IriSP.jQuery("#TL_ArrowDown").css("left", arrowLeft);
- // this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: 1000 * _time});
- //Si on a une distance de 500 ms à un marqueur, on l'affiche.
- var nearestMarkerIdx = 0;
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- //S'il existe des marqueurs dans l'intervalle de temps actuel (ici 500ms).
- if(Math.abs(_time*1000 - this.annotations[i].begin.milliseconds) <= 250)
- {
- // console.log("1) i = " + i + " " + Math.abs(_time*1000 - annotations[i].begin.milliseconds));
-
- //On sélectionne le plus proche marqueur (dans les cas où il en existe plusieurs dans l'intervalle des 1s) ou bien le premier marqueur.
- if(Math.abs(_time*1000 - this.annotations[i].begin.milliseconds) < Math.abs(_time*1000 - this.annotations[nearestMarkerIdx].begin.milliseconds) || i == nearestMarkerIdx)
- {
- // console.log("2) " + Math.abs(_time*1000 - annotations[i].begin.milliseconds) + " < " + Math.abs(_time*1000 - annotations[nearestMarkerIdx].begin.milliseconds));
- //Si le prochain marqueur se situe après le curseur de lecture, on passe donc au marqueur le plus proche.
- if(_time*1000 < this.annotations[i].begin.milliseconds)
- {
- // console.log("3) " + _time*1000 + " < " + annotations[i].begin.milliseconds);
- // console.log("4) " + "nearest = " + i);
- nearestMarkerIdx = i;
- // console.log("5a0) before");
- //S'il y a un changement de marqueur (marqueur actuel différent du précédent).
- if(nearestMarkerIdx != this.previousMarkerIdx)
- {
- var currentMarker = IriSP.jQuery("#" + this.annotations[nearestMarkerIdx].id.replace(":", "_"));
- //S'il existe un marqueur précédent, on le cache.
- if(this.previousMarkerIdx > -1)
- {
- // console.log("hide idx " + this.previousMarkerIdx);
- var previousMarker = IriSP.jQuery("#" + this.annotations[this.previousMarkerIdx].id.replace(":", "_"));
- this.hideMarkerBig(previousMarker);
- // console.log("5a) hide " + this.previousMarkerIdx);
- }
-
- // console.log("5b) show " + nearestMarkerIdx);
- this.showMarkerBig(currentMarker, this.annotations[nearestMarkerIdx].annotationType.contents.title);
- //Mise à jour du marqueur précédent s'il y a un changement.
- this.previousMarkerIdx = nearestMarkerIdx;
- // console.log("MAJ : " + this.previousMarkerIdx);
- }
- }
- }
- // nearestMarker = (Math.abs(_time*1000 - annotations[i].begin.milliseconds) < Math.abs(_time*1000 - annotations[nearestMarker].begin.milliseconds) && annotations[i].begin.milliseconds >= annotations[nearestMarker].begin.milliseconds && annotations[i].begin.milliseconds >= _time*1000) ? i : nearestMarker;
- this.currentMarkerIdx = nearestMarkerIdx;
- // this.showMarkerBig(IriSP.jQuery("#" + annotations[i].id.replace(":", "_")), annotations[i].annotationType.contents.title);
- }
- }
-}
-
-IriSP.Widgets.Timeline.prototype.timeDisplayUpdater = function() {
- var _time = this.player.popcorn.currentTime();
- var arrowLeft = Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), _time) + this.$timeline.position().left) -
- this.$timeline.slider("value",_time*1000);
-
- IriSP.jQuery(".TL_Arrows").css("display", "block");
- IriSP.jQuery("#TL_ArrowUp").css("left", arrowLeft);
- IriSP.jQuery("#TL_ArrowDown").css("left", arrowLeft);
- // this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: 1000 * _time});
-}
-
+/*
+ * Fonction appelée quand la souris est au dessus de la timeline.
+*/
IriSP.Widgets.Timeline.prototype.onMouseover = function() {}
+/*
+ * Fonction appelée quand la souris est hors de la timeline.
+*/
IriSP.Widgets.Timeline.prototype.onMouseout = function() {}
+/*
+ * Fonction appelée pour modifier la hauteur de la timeline.
+*/
IriSP.Widgets.Timeline.prototype.animateToHeight = function(_height) {}
+/*
+ * Calcule le css de la timeline.
+ * Est appelé dans le fichier :
+ * Timeline > fonction draw.
+*/
IriSP.Widgets.Timeline.prototype.calculateTimelineCss = function(_size) {
- var middleWidth = this.player.config.gui.width;
+ //Longueur du player.
+ var middleWidth = this.player.config.gui.width;
+ //On met à jour la marge, les coordonnées et positions de la timeline.
return {
- position: "absolute",
- top: "0px",
- left: "0px",
- width: middleWidth + "px",
+ position: "absolute",
+ top: "0px",
+ left: "0px",
+ width: middleWidth + "px",
height: _size + "px",
"margin-top": (-this.minimized_height - this.top_epsilon) + "px",
- "z-align": "50"
+ "z-align": "50"
};
}
+/*
+ * Calcule le css de la barre grise de milieu de la timeline.
+ * Est appelé dans le fichier :
+ * Timeline > fonction draw.
+*/
IriSP.Widgets.Timeline.prototype.calculateTimelineMiddleCss = function(_size, _middleSize) {
- var middleWidth = this.player.config.gui.width;
+ //Longueur du player.
+ var middleWidth = this.player.config.gui.width;
+ //On met à jour la marge, les coordonnées et positions de la barre grise de milieu de la timeline.
return {
- position: "absolute",
- top: "0px",
- left: "0px",
- width: middleWidth + "px",
+ position: "absolute",
+ top: "0px",
+ left: "0px",
+ width: middleWidth + "px",
height: _middleSize + "px",
"margin-top": (-this.minimized_height/2 - _middleSize/2 - this.top_epsilon) + "px",
- "z-align": "100"
+ "z-align": "100"
};
}
+/*
+ * Calcule le css de la portion de la timeline qui a déjà été lue.
+ * Est appelé dans le fichier :
+ * Timeline > fonction draw.
+*/
IriSP.Widgets.Timeline.prototype.calculateHandleCss = function(_size) {
return {
- position: "absolute",
- top: "0px",
- left: "0px",
+ position: "absolute",
+ top: "0px",
+ left: "0px",
height: (2 + _size) + "px",
width: (2 + _size) + "px",
"margin-left": -Math.ceil(2 + _size / 2) + "px",
- "z-align": "60"
+ "z-align": "60"
}
}
+/*
+ * Affiche les marqueurs lorsqu'ils sont affichés au passage du curseur.
+ * Est appelé dans le fichier :
+ * Timeline > fonction onTimeupdate.
+*/
IriSP.Widgets.Timeline.prototype.showMarkerBig = function(marker, type) {
- // console.log("avant");
- if(this.markerBigShown)
- {
- return;
- }
- // console.log("apres");
-
- clearTimeout(this.hideTimeout);
-
- var _this = this;
-
- var markerTop, markerLeft;
-
- if(marker.position() == null)
- {
- markerTop = 0;
- markerLeft = 0;
- }
- else
- {
- markerTop = marker.position().top;
- markerLeft = marker.position().left;
- }
-
- var markerWidth = marker.width(), markerHeight = marker.height();
-
- this.markerBigShown = true;
- var markerBig = "
" + this.gesturesText[IriSP.jQuery.inArray(type, this.gestures)] + "
";
- this.$.append(markerBig);
-
- var markerBigText = IriSP.jQuery("#MB_Text");
- var markerBigSpike = IriSP.jQuery("#MB_Spike");
- var markerBigPic = IriSP.jQuery("#MB_Pic");
-
- var markerBigTextWidth = markerBigText.outerWidth(), markerBigTextHeight = markerBigText.outerHeight();
- var markerBigSpikeWidth = markerBigSpike.width(), markerBigSpikeHeight = markerBigSpike.height();
- var markerBigPicWidth = markerBigPic.width(), markerBigPicHeight = markerBigPic.height();
- var markerBigPicTop = +parseFloat(marker.css("margin-top")) + markerHeight, markerBigPicLeft = (markerLeft - markerBigPicWidth/2 + markerWidth/2);
- var markerBigTextTop = (parseFloat(marker.css("margin-top")) - markerBigTextHeight - markerBigSpikeHeight), markerBigTextLeft = (markerLeft - (markerBigTextWidth - markerBigSpikeWidth)/2);
- var markerBigSpikeLeft = ((markerBigTextWidth - markerBigSpikeWidth)/2);
-
- marker.css("background-image", "url(" + this.imgDir + "selected_marker.png)");
- IriSP.jQuery("#MB_Text").css(
- {
- top: markerBigTextTop,
- left: markerBigTextLeft
- });
- IriSP.jQuery("#MB_Spike").css(
- {
- left: markerBigSpikeLeft
- });
- IriSP.jQuery("#MB_Pic").css(
- {
- "background-image": "url(" + this.markersDir + type + ".png)",
- top: markerBigPicTop,
- left: markerBigPicLeft,
- "z-index": "400"
- });
-
- IriSP.jQuery(".TL_MarkersBig").fadeTo(this.markerShowTime, "1");
-
- //On rajoute un timeout pour supprimer le marqueur après un certain temps.
- this.hideTimeout = setTimeout(function()
- {
- _this.hideMarkerBig(marker);
- }, this.markerLastTime);
+ //Si le marqueur est déjà affiché, on part.
+ if(this.markerBigShown)
+ {
+ return;
+ }
+
+ //On annule le masquage du pointeur.
+ clearTimeout(this.hideTimeout);
+
+ var _this = this;
+ //On met à jour la position du marqueur.
+ var markerTop, markerLeft;
+
+ if(marker.position() == null)
+ {
+ markerTop = 0;
+ markerLeft = 0;
+ }
+ else
+ {
+ markerTop = marker.position().top;
+ markerLeft = marker.position().left;
+ }
+ //Ses dimensions aussi.
+ var markerWidth = marker.width(), markerHeight = marker.height();
+ //On spécifie qu'il est affiché.
+ this.markerBigShown = true;
+ //On le crée.
+ var markerBig = "
" + this.gesturesText[IriSP.jQuery.inArray(type, this.gestures)] + "
";
+ //On l'ajoute.
+ this.$.append(markerBig);
+ //On forme ses éléments.
+ var markerBigText = IriSP.jQuery("#MB_Text");
+ var markerBigSpike = IriSP.jQuery("#MB_Spike");
+ var markerBigPic = IriSP.jQuery("#MB_Pic");
+ //On spécifie leurs coordonnées et dimensions.
+ var markerBigTextWidth = markerBigText.outerWidth(), markerBigTextHeight = markerBigText.outerHeight();
+ var markerBigSpikeWidth = markerBigSpike.width(), markerBigSpikeHeight = markerBigSpike.height();
+ var markerBigPicWidth = markerBigPic.width(), markerBigPicHeight = markerBigPic.height();
+ var markerBigPicTop = +parseFloat(marker.css("margin-top")) + markerHeight, markerBigPicLeft = (markerLeft - markerBigPicWidth/2 + markerWidth/2);
+ var markerBigTextTop = (parseFloat(marker.css("margin-top")) - markerBigTextHeight - markerBigSpikeHeight), markerBigTextLeft = (markerLeft - (markerBigTextWidth - markerBigSpikeWidth)/2);
+ var markerBigSpikeLeft = ((markerBigTextWidth - markerBigSpikeWidth)/2);
+ //On va chercher les images correspondantes.
+ marker.css("background-image", "url(" + this.imgDir + "selected_marker.png)");
+ //On met à jour leur apparence.
+ IriSP.jQuery("#MB_Text").css(
+ {
+ top: markerBigTextTop,
+ left: markerBigTextLeft
+ });
+ IriSP.jQuery("#MB_Spike").css(
+ {
+ left: markerBigSpikeLeft
+ });
+ IriSP.jQuery("#MB_Pic").css(
+ {
+ "background-image": "url(" + this.markersDir + type + ".png)",
+ top: markerBigPicTop,
+ left: markerBigPicLeft,
+ "z-index": "400"
+ });
+ //On l'affiche.
+ IriSP.jQuery(".TL_MarkersBig").fadeTo(this.markerShowTime, "1");
+
+ //On rajoute un timeout pour supprimer le marqueur après un certain temps.
+ this.hideTimeout = setTimeout(function()
+ {
+ _this.hideMarkerBig(marker);
+ }, this.markerLastTime);
}
+/*
+ * Cache un marqueur.
+ * Est appelé dans le fichier :
+ * Timeline > fonctions draw, keyPress, onTimeupdate et showMarkerBig.
+*/
IriSP.Widgets.Timeline.prototype.hideMarkerBig = function(marker) {
- if(!this.markerBigShown)
- {
- return;
- }
-
- this.currentMarker = -1;
- this.markerBigShown = false;
- marker.css("background-image", "url(" + this.imgDir + "marker.png)");
-
- IriSP.jQuery(".TL_MarkersBig").fadeOut(this.markerShowTime).remove();
+ //S'il n'est pas affiché, on part.
+ if(!this.markerBigShown)
+ {
+ return;
+ }
+
+ //On lui remet son apparence initiale.
+ this.currentMarker = -1;
+ this.markerBigShown = false;
+ marker.css("background-image", "url(" + this.imgDir + "marker.png)");
+ //On efface ce qui était affiché du marqueur.
+ IriSP.jQuery(".TL_MarkersBig").fadeOut(this.markerShowTime).remove();
}
/*
* Affiche le bas des marqueurs correspondants à la recherche.
+ * Est appelé dans le fichier :
+ * Timeline > fonction hideMarkersSearch.
*/
IriSP.Widgets.Timeline.prototype.showMarkersSearchByType = function(type) {
- //Si on est en mode SEARCH.
- if(this.currentMode != "SEARCH")
- {
- return;
- }
-
- var _this = this;
-
- //On récupère les annotations.
- var markersSearch = "", markersPicSearch = "";
- //Pour chaque annotation, on ajoute un double.
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- //Si elle correspond à la recherche.
- if(this.annotations[i].annotationType.contents.title == type)
- {
- //On récupère le marqueur associé à l'annotation.
- var markerId = this.annotations[i].id.replace(":", "_");
-
- markersSearch += "
";
- markersPicSearch += "
";
- }
- }
-
- this.$.append(markersSearch + markersPicSearch);
-
- //On place chaque double.
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- //Si elle correspond à la recherche.
- if(this.annotations[i].annotationType.contents.title == type)
- {
- var markerId = this.annotations[i].id.replace(":", "_"), marker = IriSP.jQuery("#" + markerId);
- var markerTop = marker.position().top, markerLeft = marker.position().left, markerWidth = marker.width(), markerHeight = marker.height();
- var markerBigPicWidth = parseFloat(IriSP.jQuery(".search_MBPic").css("width")), markerBigPicHeight = parseFloat(IriSP.jQuery(".search_MBPic").css("height")), markerBigPicTop = +parseFloat(marker.css("margin-top")) + markerHeight, markerBigPicLeft = (markerLeft - markerBigPicWidth/2 + markerWidth/2);
-
- // console.log(markerLeft + " - " + IriSP.jQuery(".search_MBPic").css("width") + " " + markerBigPicWidth + "/2 " + markerWidth + "/2");
-
- IriSP.jQuery("#search_Pic_" + markerId).css(
- {
- position: "absolute",
- "background-image": "url(" + this.markersDir + type + ".png)",
- top: markerBigPicTop,
- left: markerBigPicLeft,
- "z-index": "300"
- }).fadeTo(this.markerShowTime, "1");
-
- IriSP.jQuery("#search_Marker_" + markerId).css(
- {
- position: "absolute",
- top: _this.$timelineMiddle.position().top - _this.top_epsilon,
- "margin-top": (-_this.$timeline.height()/2 - markerHeight/2),
- "background-image": "url(" + this.imgDir + "selected_marker.png)",
- //top: markerTop,
- left: markerLeft,
- "z-index": "300"
- }).fadeTo(this.markerShowTime, "1");
- }
- }
+ //Si on est en mode SEARCH.
+ if(this.currentMode != "SEARCH")
+ {
+ return;
+ }
+
+ var _this = this;
+
+ //On récupère les annotations.
+ var markersSearch = "", markersPicSearch = "";
+ //Pour chaque annotation, on ajoute un double.
+ for(var i = 0 ; i < this.annotations.length ; i++)
+ {
+ //Si elle correspond à la recherche.
+ if(this.annotations[i].annotationType.contents.title == type)
+ {
+ //On récupère le marqueur associé à l'annotation.
+ var markerId = this.annotations[i].id.replace(":", "_");
+
+ markersSearch += "
";
+ markersPicSearch += "
";
+ }
+ }
+
+ this.$.append(markersSearch + markersPicSearch);
+
+ //On place chaque double.
+ for(var i = 0 ; i < this.annotations.length ; i++)
+ {
+ //Si elle correspond à la recherche.
+ if(this.annotations[i].annotationType.contents.title == type)
+ {
+ //On calcule les coordonnées et dimensions du marqueur.
+ var markerId = this.annotations[i].id.replace(":", "_"), marker = IriSP.jQuery("#" + markerId);
+ var markerTop = marker.position().top, markerLeft = marker.position().left, markerWidth = marker.width(), markerHeight = marker.height();
+ var markerBigPicWidth = parseFloat(IriSP.jQuery(".search_MBPic").css("width")), markerBigPicHeight = parseFloat(IriSP.jQuery(".search_MBPic").css("height")), markerBigPicTop = +parseFloat(marker.css("margin-top")) + markerHeight, markerBigPicLeft = (markerLeft - markerBigPicWidth/2 + markerWidth/2);
+ //On calcule son apparence et on le fait apparaître.
+ IriSP.jQuery("#search_Pic_" + markerId).css(
+ {
+ position: "absolute",
+ "background-image": "url(" + this.markersDir + type + ".png)",
+ top: markerBigPicTop,
+ left: markerBigPicLeft,
+ "z-index": "300"
+ }).fadeTo(this.markerShowTime, "1");
+
+ IriSP.jQuery("#search_Marker_" + markerId).css(
+ {
+ position: "absolute",
+ top: _this.$timelineMiddle.position().top - _this.top_epsilon,
+ "margin-top": (-_this.$timeline.height()/2 - markerHeight/2),
+ "background-image": "url(" + this.imgDir + "selected_marker.png)",
+ left: markerLeft,
+ "z-index": "300"
+ }).fadeTo(this.markerShowTime, "1");
+ }
+ }
}
/*
* Enlever une recherche faite précédemment.
+ * Est appelé dans le fichier :
+ * Timeline > fonctions searchByGesture et removeSearchByGesture.
*/
IriSP.Widgets.Timeline.prototype.hideMarkersSearch = function(type) {
- //Si on est en mode SEARCH.
- if(this.currentMode != "SEARCH")
- {
- return;
- }
-
- // console.log('(0)');
-
- var _this = this;
-
- IriSP.jQuery(".search_MBPic").fadeOut(this.markerShowTime, function()
- {
- IriSP.jQuery("div").remove(".search_MBPic");
- });
- IriSP.jQuery(".search_Marker").fadeOut(this.markerShowTime, function()
- {
- IriSP.jQuery("div").remove(".search_Marker");
-
- if(type == undefined)
- {
- _this.currentMode = "VIDEO";
- }
- else
- {
- // console.log('(1)');
- // console.log(_this.currentMode);
- _this.showMarkersSearchByType(type);
- return;
- }
- });
-
- if(IriSP.jQuery(".search_Marker").length == 0 && type != undefined)
- {
- // console.log('(2)');
- this.showMarkersSearchByType(type);
-
- if(!_.include(this.gestures, type))
- {
- // this.notifySearch1Gesture(type, "none");
- }
- else
- {
- // _this.notifySearch1Gesture(type, "valid");
- }
- // console.log(this.currentMode);
- }
+ //Si on est en mode SEARCH.
+ if(this.currentMode != "SEARCH")
+ {
+ return;
+ }
+
+ var _this = this;
+
+ //On efface tous les marqueurs affichés.
+ IriSP.jQuery(".search_MBPic").fadeOut(this.markerShowTime, function()
+ {
+ IriSP.jQuery("div").remove(".search_MBPic");
+ });
+ IriSP.jQuery(".search_Marker").fadeOut(this.markerShowTime, function()
+ {
+ IriSP.jQuery("div").remove(".search_Marker");
+
+ //Si le type est définit, c'est qu'on souhaite remplacer cette recherche par une autre.
+ if(type == undefined)
+ {
+ _this.currentMode = "VIDEO";
+ }
+ else
+ {
+ _this.showMarkersSearchByType(type);
+ return;
+ }
+ });
+
+ //Si à la base il n'y avait pas de marqueurs affichés, on crée une nouvelle recherche si le type est définit.
+ if(IriSP.jQuery(".search_Marker").length == 0 && type != undefined)
+ {
+ this.showMarkersSearchByType(type);
+ }
}
+/*
+ * Libère le player.
+ * Est appelé dans les fichiers :
+ * neighbours > fonction moveToNeighbour.
+ * zoomInteractions > fonction unzoom.
+*/
IriSP.Widgets.Timeline.prototype.freePlayer = function()
{
- IriSP.jQuery('body').unbind('keypress');
- IriSP.jQuery('.notifications').remove();
+ IriSP.jQuery('body').unbind('keypress');
+ IriSP.jQuery('.notifications').remove();
}
/*
* Va au marqueur suivant/précédant lors d'un swipe right/left dans une lecture simple.
* Prend comme argument le fait qu'il s'agisse d'un swipe left ou non (en prenant en condition toujours vraie
* que la fonction est appelée si et seulement si il y a swipe et que l'utilisateur ne tente pas d'aller vers un voisin.
+ * Est appelé dans le fichier :
+ * mosaic > fonction manageControlEvents.
*/
IriSP.Widgets.Timeline.prototype.switchToMarker = function(isSwipeLeft, searchedGesture)
{
- console.log((isSwipeLeft == true) ? 'SWIPE LEFT' : 'SWIPE RIGHT');
-
- //On prend le temps actuel du curseur en ms.
- var currentCursorPosition = this.player.popcorn.currentTime() * 1000;
- //Position visée.
- var targetCursorPosition = currentCursorPosition;
- //Distance minimum de l'annotation par rapport au curseur et son index, ainsi que l'index - 1 pour le cas du swipe right.
- var minDistance = this.source.getDuration().milliseconds, minIdx = 0, mindIdx_1 = 0;
+ console.log((isSwipeLeft == true) ? 'SWIPE LEFT' : 'SWIPE RIGHT');
+
+ //On prend le temps actuel du curseur en ms.
+ var currentCursorPosition = this.player.popcorn.currentTime() * 1000;
+ //Position visée.
+ var targetCursorPosition = currentCursorPosition;
+ //Distance minimum de l'annotation par rapport au curseur et son index, ainsi que l'index - 1 pour le cas du swipe right.
+ var minDistance = this.source.getDuration().milliseconds, minIdx = 0, mindIdx_1 = 0;
- //Si il y a au moins 1 annotation.
- if(this.annotations && this.annotations.length > 0)
- {
- if(isSwipeLeft)
- {
- //Pour toutes les annotations, on prend celle qui est la plus proche et supérieure à la position.
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- // console.log('curr : ' + currentCursorPosition + ' ann : ' + this.annotations[i].begin);
- if(currentCursorPosition < this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin))
- {
- if(searchedGesture != '')
- {
- if(this.annotations[i].annotationType.contents.title != searchedGesture)
- {
- continue;
- }
- }
-
- minDistance = (currentCursorPosition - this.annotations[i].begin);
- minIdx = i;
- }
- }
- }
- else
- {
- //Pour toutes les annotations, on prend celle qui est la plus proche et inférieure à la position.
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- if(currentCursorPosition > this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin))
- {
- if(searchedGesture != '')
- {
- if(this.annotations[i].annotationType.contents.title != searchedGesture)
- {
- continue;
- }
- }
-
- minDistance = (currentCursorPosition - this.annotations[i].begin);
- minIdx = i;
- }
- }
- }
-
- targetCursorPosition = this.annotations[minIdx].begin;
-
- if(this.annotations[minIdx].begin > 1000)
- {
- targetCursorPosition -= 1000;
- }
- }
+ //Condition de sélection du marqueur selon le type de swipe.
+ var swipeCondition = (isSwipeLeft ? (currentCursorPosition < this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin)) : (currentCursorPosition > this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin)));
- this.player.popcorn.currentTime(targetCursorPosition / 1000);
-}
-
-/*
- * Indique s'il y a des marqueurs devant le curseur (pour une recherche)
-*/
-IriSP.Widgets.Timeline.prototype.isAMarkerAhead = function(searchedGesture)
-{
- if(searchedGesture == '')
- {
- return true;
- }
-
- //On prend le temps actuel du curseur en ms.
- var currentCursorPosition = this.player.popcorn.currentTime() * 1000;
- //Position visée.
- var targetCursorPosition = currentCursorPosition;
- //Distance minimum de l'annotation par rapport au curseur et son index, ainsi que l'index - 1 pour le cas du swipe right.
- var minDistance = this.source.getDuration().milliseconds, minIdx = 0, mindIdx_1 = 0;
-
- //Si il y a au moins 1 annotation.
- if(this.annotations && this.annotations.length > 0)
- {
+ //Si il y a au moins 1 annotation.
+ if(this.annotations && this.annotations.length > 0)
+ {
//Pour toutes les annotations, on prend celle qui est la plus proche et supérieure à la position.
for(var i = 0 ; i < this.annotations.length ; i++)
{
- // console.log('curr : ' + currentCursorPosition + ' ann : ' + this.annotations[i].begin);
- if(this.annotations[i].annotationType.contents.title == searchedGesture && currentCursorPosition < this.annotations[i].begin)
+ if(swipeCondition)
{
- return true;
- }
- }
- }
-
- return false;
-}
-
-/*
- * Indique, après un swipe, si on est au dernier marqueur d'un type recherché dans la vidéo.
-*/
-IriSP.Widgets.Timeline.prototype.switchToMarker2 = function(isSwipeLeft, searchedGesture)
-{
- /*if(isSwipeLeft)
- {
- //Pour toutes les annotations, on prend celle qui est la plus proche et supérieure à la position.
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- // console.log('curr : ' + currentCursorPosition + ' ann : ' + this.annotations[i].begin);
- if(currentCursorPosition < this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin))
- {
+ //Si on recherche une gesture.
if(searchedGesture != '')
{
+ //Si l'annotation actuelle ne correspond pas à la gesture recherchée, on passe.
if(this.annotations[i].annotationType.contents.title != searchedGesture)
{
continue;
}
}
+ //On calcule la plus petite distance entre le marqueur marqueur actuel et les autres.
minDistance = (currentCursorPosition - this.annotations[i].begin);
minIdx = i;
}
}
- }
- else
- {
- //Pour toutes les annotations, on prend celle qui est la plus proche et inférieure à la position.
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- if(currentCursorPosition > this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin))
- {
- if(searchedGesture != '')
- {
- if(this.annotations[i].annotationType.contents.title != searchedGesture)
- {
- continue;
- }
- }
-
- minDistance = (currentCursorPosition - this.annotations[i].begin);
- minIdx = i;
- }
- }
- }*/
+
+ //On obtient la position du plus proche marqueur.
+ targetCursorPosition = this.annotations[minIdx].begin;
+
+ //Si le marqueur est situé minimum à 1s du début de la video, on place la position cible à 1s avant celle du marqueur recherché.
+ if(this.annotations[minIdx].begin > 1000)
+ {
+ targetCursorPosition -= 1000;
+ }
+ }
+
+ //On place le marqueur au niveau de la position cible.
+ this.player.popcorn.currentTime(targetCursorPosition / 1000);
+}
+
+/*
+ * Indique s'il y a des marqueurs devant le curseur (pour une recherche).
+ * Est appelé dans le fichier :
+ * mosaic > fonction manageControlEvents.
+*/
+IriSP.Widgets.Timeline.prototype.isAMarkerAhead = function(searchedGesture)
+{
+ if(searchedGesture == '')
+ {
+ return true;
+ }
+
+ //On prend le temps actuel du curseur en ms.
+ var currentCursorPosition = this.player.popcorn.currentTime() * 1000;
+ //Position visée.
+ var targetCursorPosition = currentCursorPosition;
+ //Distance minimum de l'annotation par rapport au curseur et son index, ainsi que l'index - 1 pour le cas du swipe right.
+ var minDistance = this.source.getDuration().milliseconds, minIdx = 0, mindIdx_1 = 0;
+
+ //Si il y a au moins 1 annotation.
+ if(this.annotations && this.annotations.length > 0)
+ {
+ //Pour toutes les annotations, on prend celle qui est la plus proche et supérieure à la position.
+ for(var i = 0 ; i < this.annotations.length ; i++)
+ {
+ if(this.annotations[i].annotationType.contents.title == searchedGesture && currentCursorPosition < this.annotations[i].begin)
+ {
+ return true;
+ }
+ }
+ }
+
+ //Si elle n'a pas été trouvée on renvoie faux.
+ return false;
}
/*
* Quand on entre dans la vidéo après un filtrage, on va au premier marqueur correspondant à la recherche (à l'exception d'une recherche infructueuse).
+ * Est appelé dans les fichiers :
+ * mosaic > fonctions onMouseUp et onMarkersReady.
+ * curvesDetector > fonction updateDists.
*/
IriSP.Widgets.Timeline.prototype.goToFirstSearchedMarker = function(gesture)
{
- if(_.include(this.gestures, gesture))
- {
- if(this.annotations && this.annotations.length > 0)
- {
- var minIdx = 0, minPosition = this.source.getDuration().milliseconds, targetCursorPosition = 0;
-
- //On parcourt les annotations, pour chaque correspondant à la gesture recherchée, on trouve celle qui se trouve à la position minimum.
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- //Si le marker n'est pas du type recherché, on passe.
- if(this.annotations[i].annotationType.contents.title != gesture)
- {
- continue;
- }
- else if(minPosition > this.annotations[i].begin)
- {
- minPosition = this.annotations[i].begin;
- minIdx = i;
- }
- }
-
- targetCursorPosition = this.annotations[minIdx].begin;
-
- console.log('pos : ' + targetCursorPosition);
-
- if(this.annotations[minIdx].begin > 1000)
- {
- targetCursorPosition -= 1000;
- }
-
- this.player.popcorn.currentTime(targetCursorPosition / 1000);
- }
- }
+ if(_.include(this.gestures, gesture))
+ {
+ if(this.annotations && this.annotations.length > 0)
+ {
+ var minIdx = 0, minPosition = this.source.getDuration().milliseconds, targetCursorPosition = 0;
+
+ //On parcourt les annotations, pour chaque correspondant à la gesture recherchée, on trouve celle qui se trouve à la position minimum.
+ for(var i = 0 ; i < this.annotations.length ; i++)
+ {
+ //Si le marker n'est pas du type recherché, on passe.
+ if(this.annotations[i].annotationType.contents.title != gesture)
+ {
+ continue;
+ }
+ else if(minPosition > this.annotations[i].begin)
+ {
+ minPosition = this.annotations[i].begin;
+ minIdx = i;
+ }
+ }
+
+ targetCursorPosition = this.annotations[minIdx].begin;
+
+ //Si le marqueur est situé minimum à 1s du début de la video, on place la position cible à 1s avant celle du marqueur recherché.
+ if(this.annotations[minIdx].begin > 1000)
+ {
+ targetCursorPosition -= 1000;
+ }
+
+ //On place le marqueur au niveau de la position cible.
+ this.player.popcorn.currentTime(targetCursorPosition / 1000);
+ }
+ }
}
/*
* Renvoie vrai si il y a au moins une gesture de notre recherche dans les marqueurs de la video.
+ * Est appelé dans les fichiers :
+ * mosaic > fonctions onMouseUp et onMarkersReady.
+ * curvesDetector > fonction updateDists.
*/
IriSP.Widgets.Timeline.prototype.atLeastOneSearchMarker = function(gesture)
{
- if(_.include(this.gestures, gesture))
- {
- if(this.annotations && this.annotations.length > 0)
- {
- //On parcourt les annotations, pour chaque correspondant à la gesture recherchée, on trouve celle qui se trouve à la position minimum.
- for(var i = 0 ; i < this.annotations.length ; i++)
- {
- //Si le marker est reconnu, c'est bon.
- if(this.annotations[i].annotationType.contents.title == gesture)
- {
- return true;
- }
- }
-
- return false;
- }
- }
+ if(_.include(this.gestures, gesture))
+ {
+ if(this.annotations && this.annotations.length > 0)
+ {
+ //On parcourt les annotations, pour chaque correspondant à la gesture recherchée, on trouve celle qui se trouve à la position minimum.
+ for(var i = 0 ; i < this.annotations.length ; i++)
+ {
+ //Si le marker est reconnu, c'est bon.
+ if(this.annotations[i].annotationType.contents.title == gesture)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
}
\ No newline at end of file
diff -r 03ea3d7ddbe1 -r 277c94533395 front_idill/src/search/css/searchCanvas.css
--- a/front_idill/src/search/css/searchCanvas.css Mon Jul 23 10:52:41 2012 +0200
+++ b/front_idill/src/search/css/searchCanvas.css Mon Jul 23 16:59:35 2012 +0200
@@ -1,3 +1,25 @@
+/*
+* This file is part of the TraKERS\Front IDILL package.
+*
+* (c) IRI
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+/*
+ * Projet : TraKERS
+ * Module : Front IDILL
+ * Fichier : searchCanvas.css
+ *
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ *
+ * Fonctionnalités : Style du canvas pour les courbes de recherche.
+ */
+
+/*
+ * Canvas sur lequel se dessinent les courbes de recherche.
+*/
.canvas
{
position: absolute;
diff -r 03ea3d7ddbe1 -r 277c94533395 front_idill/src/search/js/curvesDetector.js
--- a/front_idill/src/search/js/curvesDetector.js Mon Jul 23 10:52:41 2012 +0200
+++ b/front_idill/src/search/js/curvesDetector.js Mon Jul 23 16:59:35 2012 +0200
@@ -1,368 +1,403 @@
-/*
-* This file is part of the TraKERS\Front IDILL package.
-*
-* (c) IRI
-*
-* For the full copyright and license information, please view the LICENSE
-* file that was distributed with this source code.
-*/
-
-/*
- * Projet : TraKERS
- * Module : Front IDILL
- * Fichier : curvesDetector.js
- *
- * Auteur : alexandre.bastien@iri.centrepompidou.fr
- *
- * Fonctionnalités : Détecteur de courbes de recherche, appelé par la classe de création du canvas de recherche.
- */
-
-/*
- * Détecteur de courbes (lignes droites, arcs de cercles et cercles).
-*/
-function curvesDetector(divisions, sizeTreshold, dictionary, mosaic)
-{
- //Précision de la détection de direction en divisions (par défaut 12, selon une modélisation horaire et non mathématique).
- this.divisions = divisions;
- //Taille limite pour un segment/courbe pour être considéré comme tel en px.
- this.sizeTreshold = sizeTreshold;
-
- this.dictionary = dictionary;
-
- this.mosaic = mosaic;
-
- //Code actuel généré. Il représente la structure de la courbe de recherche.
- this.actualCode = '';
-
- this.joints = [];
- this.jInc = 0;
-
- //Longueur totale de la courbe.
- this.MPTotalDist = 0;
- this.SPTotalDist = 0;
- //Longueur de la partie actuelle (après début ou changement de direction).
- this.MPActualDist = 0;
- this.SPActualDist = 0;
- //Angles actuels.
- this.MPActualAngle = -1;
- this.SPActualAngle = -1;
-
- //Centre du repère du pointeur principal.
- this.MPrepX;
- this.MPrepY;
- //Centre du repère du pointeur secondaire.
- this.SPrepX;
- this.SPrepY;
-
- //Coordonnées actuelles du/des pointeur/s.
- this.MPx = 0;
- this.MPy = 0;
- this.SPx = 0;
- this.SPy = 0;
- //Coordonnées précédentes du/des pointeur/s.
- this.MPpx = 0;
- this.MPpy = 0;
- this.SPpx = 0;
- this.SPpy = 0;
-
- //Si les paramètres sont incorrects, on leur donne une valeur par défaut.
- if(isNaN(divisions) || divisions < 1 || divisions > 360)
- {
- this.divisions = 12;
- }
- if(sizeTreshold < 1)
- {
- sizeTreshold = 30;
- }
-}
-
-/*
- * Reinit les paramètres du détecteur.
-*/
-curvesDetector.prototype.reinit = function()
-{
- this.MPrepX = 0;
- this.MPrepY = 0;
- this.MPpx = 0;
- this.MPpy = 0;
- this.MPActualAngle = -1;
- this.SPActualAngle = -1;
- this.actualCode = '';
-
- /*for(var i = 0 ; i < this.joints.length ; i++)
- {
- if(this.joints[i])
- {
- this.joints[i].remove();
- }
- }
-
- this.jInc = 0;*/
- this.MPActualDist = 0;
- this.MPTotalDist = 0;
-}
-
-/*
- * Met à jour les positions des pointeurs
-*/
-curvesDetector.prototype.updatePos = function(mpx, mpy, spx, spy)
-{
- //On met à jour les coordonnées récentes.
- this.MPx = mpx;
- this.MPy = mpy;
-
- //Si les coordonnées précédentes n'existent pas, alors on les met à jour.
- if(!this.MPpx)
- {
- this.MPpx = mpx;
- }
- if(!this.MPpy)
- {
- this.MPpy = mpy;
- }
- if(!this.MPrepX)
- {
- this.MPrepX = mpx;
- }
- if(!this.MPrepY)
- {
- this.MPrepY = mpy;
- }
-
- //Si on a un second pointeur.
- if(spx && spy)
- {
- //On met les coordonnées à jour.
- this.SPx = spx;
- this.SPy = spy;
-
- //Si les coordonnées précédentes n'existent pas, alors on les met à jour.
- if(!this.SPpx)
- {
- this.SPpx = spx;
- }
- if(!this.SPpy)
- {
- this.SPpy = spy;
- }
- }
-
- this.updateDists();
-}
-
-/*
- * Met à jour les distances parcourues.
-*/
-curvesDetector.prototype.updateDists = function()
-{
- var foundGestures;
-
- //Si on a de quoi calculer les distances.
- if(this.MPx && this.MPy && this.MPpx && this.MPpy && this.MPrepX && this.MPrepY)
- {
- var MPDist = Math.floor(Math.sqrt((this.MPx - this.MPpx) * (this.MPx - this.MPpx) + (this.MPy - this.MPpy) * (this.MPy - this.MPpy)));
- this.MPTotalDist += MPDist;
- this.MPActualDist += MPDist;
-
- var MPCurrentA = -1;
-
- if(MPDist > 0)
- {
- MPCurrentA = this.currentAngle(this.MPrepX, this.MPrepY, this.MPx, this.MPy, this.divisions);
- // console.log(MPCurrentA);//, this.MPActualDist);
- }
-
- if(this.MPActualDist > this.sizeTreshold && MPCurrentA != -1)
- {
- console.log(this.MPActualAngle, MPCurrentA, this.MPActualAngle != -1, this.MPActualAngle != MPCurrentA);
-
- if(this.MPActualAngle == -1 || this.MPActualAngle != MPCurrentA)
- {
- this.MPActualAngle = MPCurrentA;
- this.actualCode += 'D' + MPCurrentA;
- this.mosaic.actualCode = this.actualCode;
-
- foundGestures = this.codeToGestures(this.actualCode);
-
- console.log(+this.jInc+1, this.MPActualDist);
- console.log(this.actualCode);
- console.log(foundGestures);
-
- if(foundGestures.length == 0 || foundGestures.split(';').length != 1)
- {
- console.log('many curves');
- this.mosaic.curvesGesturesFound = true;
- this.mosaic.removeNotifications();
- this.mosaic.curvesGestures(foundGestures);
-
- if(foundGestures.length == 0 && !this.mosaic.helpDisplayed)
- {
- this.mosaic.notifyHelp();
- foundGestures = '';
- this.mosaic.curvesGesturesFound = false;
- this.mosaic.isSearchByCurvesOn = false;
- this.mosaic.leaveSearch();
- }
- else if(foundGestures.split(';').length != 1 && this.mosaic.helpDisplayed)
- {
- if(this.mosaic.helpDisplayed)
- {
- this.mosaic.removeHelp();
- }
- }
- }
- else
- {
- // console.log(this.mosaic.currentMode);
- this.mosaic.currentSearchGesture[this.mosaic.centerId] = foundGestures;
- this.mosaic.isUserInSearchZone = false;
-
- if(this.mosaic.currentMode == "SEARCH" && this.mosaic.playerIsReady)
- {
- this.mosaic.player.widgets[0].searchByGesture(foundGestures);
- this.mosaic.isCurrentlyInASearchByGesture = this.mosaic.player.widgets[0].isCurrentlyInASearchByGesture;
-
- this.mosaic.removeNotifications();
- this.mosaic.searchGesture(foundGestures, 'valid');
-
- if(this.mosaic.player && this.mosaic.player.widgets[0] && this.mosaic.timeToGoAt[this.mosaic.centerId] === 0 && this.mosaic.player.widgets[0].atLeastOneSearchMarker(this.mosaic.currentSearchGesture[this.mosaic.centerId]))
- {
- this.mosaic.player.widgets[0].goToFirstSearchedMarker(this.mosaic.currentSearchGesture[this.mosaic.centerId]);
- }
-
- this.mosaic.currentSearchGesture[this.mosaic.centerId] = foundGestures;
-
- foundGestures = '';
- this.mosaic.curvesGesturesFound = false;
-
- this.mosaic.isSearchByCurvesOn = false;
- this.mosaic.leaveSearch();
- }
- else if(this.mosaic.currentMode == "FILTER")
- {
- if(this.mosaic.isMosaicFiltered)
- {
- console.log('1 curve : ' + foundGestures);
- this.mosaic.filterSearchedType = foundGestures;
- this.mosaic.searchFilter(foundGestures);
- this.mosaic.curvesGesturesFound = false;
-
- this.mosaic.removeNotifications();
- this.mosaic.filterGesture(foundGestures, 'valid');
-
- foundGestures = '';
-
- this.mosaic.isSearchByCurvesOn = false;
- this.mosaic.leaveSearch();
- }
- }
- }
-
- this.MPActualDist = 0;
- //this.jInc++
- }
- else
- {
- this.MPrepX = this.MPpx;
- this.MPrepY = this.MPpy;
-
- /*if(this.joints[this.jInc])
- {
- this.joints[this.jInc].remove();
- }
- this.joints[this.jInc] = new paper.Path.Circle(new paper.Point(this.MPrepX, this.MPrepY), 10);
- this.joints[this.jInc].strokeColor = 'black';
- this.joints[this.jInc].fillColor = 'green';*/
- }
-
- if(this.MPActualAngle == -1)
- {
- this.MPActualAngle = MPCurrentA;
- }
- }
-
- //On met à jour les coordonnées précédentes.
- if(this.MPpx != this.MPx)
- {
- this.MPpx = this.MPx;
- }
- if(this.MPpy != this.MPy)
- {
- this.MPpy = this.MPy;
- }
- }
- //Idem au cas où on aurait un deuxième pointeur.
- if(this.SPx && this.SPy && this.SPpx && this.SPpy)
- {
- var SPDist = Math.floor(Math.sqrt((this.SPx - this.SPpx) * (this.SPx - this.SPpx) + (this.SPy - this.SPpy) * (this.SPy - this.SPpy)));
- this.SPTotalDist += SPDist;
- this.SPActualDist += SPDist;
-
- if(SPDist > 0)
- {
- this.currentAngle(this.SPpx, this.SPpy, this.SPx, this.SPy);
- }
-
- //On met à jour les coordonnées précédentes.
- if(this.SPpx != this.SPx)
- {
- this.SPpx = this.SPx;
- }
- if(this.SPpy != this.SPy)
- {
- this.SPpy = this.SPy;
- }
- }
-}
-
-/*
- * Renvoie les noms de gestures du dictionnaire qui ont un code qui commence par le code en entrée.
-*/
-curvesDetector.prototype.codeToGestures = function(code)
-{
- //Variable qui va stocker tous les noms trouvés.
- var retNames = '';
-
- //Pour tout le dictionnaire.
- for(var i = 0 ; i < this.dictionary.length ; i++)
- {
- //Pour touts les codes de chaque gesture du dictionnaire.
- for(var j = 0 ; j < this.dictionary[i].codes.length ; j++)
- {
- //Si le code en entrée est une partie début d'un des codes.
- if(this.dictionary[i].codes[j].indexOf(code) == 0)
- {
- //On ajoute le nom de la gesture et on passe à la gesture suivante.
- retNames += this.dictionary[i].name + ';';
- break;
- }
- }
- }
- //Comme on sépare chaque nom par un ;, il faut supprimer le dernier si au moins un nom a été trouvé.
- if(retNames.length > 0)
- {
- retNames = retNames.substring(0, retNames.length-1);
- }
-
- //On renvoit les noms.
- return retNames;
-}
-
-/*
- * Calcule l'angle emprunté par le morceau de segment actuel. On prend A va vers B.
-*/
-curvesDetector.prototype.currentAngle = function(xa, ya, xb, yb, divisions)
-{
- //On calcule l'angle de la droite AB et des abscisses, et on effectue une rotation de 90° vers la gauche.
- var angleRad = Math.atan2((ya - yb), (xa - xb)) - Math.PI / 2;
- //On traduit les radians en divisions en passant de [-PI/2 ; PI/2] à [0 ; divisions - 1].
- var angleDiv = Math.floor((angleRad > 0 ? angleRad : (2*Math.PI + angleRad)) * divisions / (2*Math.PI));
-
- //L'angle initial est 0.
- if(angleDiv == divisions)
- {
- angleDiv = 0;
- }
-
- return angleDiv;
+/*
+* This file is part of the TraKERS\Front IDILL package.
+*
+* (c) IRI
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+/*
+ * Projet : TraKERS
+ * Module : Front IDILL
+ * Fichier : curvesDetector.js
+ *
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ *
+ * Fonctionnalités : Détecteur de courbes de recherche, appelé par la classe de création du canvas de recherche.
+ */
+
+/*
+ * Détecteur de courbes (lignes droites, arcs de cercles et cercles).
+ * Est appelé dans le fichier :
+ * searchCanvas > fonction create.
+*/
+function CurvesDetector(divisions, sizeTreshold, dictionary, mosaic)
+{
+ //Précision de la détection de direction en divisions (par défaut 12, selon une modélisation horaire et non mathématique).
+ this.divisions = divisions;
+ //Taille limite pour un segment/courbe pour être considéré comme tel en px.
+ this.sizeTreshold = sizeTreshold;
+
+ this.dictionary = dictionary;
+
+ this.mosaic = mosaic;
+
+ //Code actuel généré. Il représente la structure de la courbe de recherche.
+ this.actualCode = '';
+
+ this.joints = [];
+ this.jInc = 0;
+
+ //Longueur totale de la courbe.
+ this.MPTotalDist = 0;
+ this.SPTotalDist = 0;
+ //Longueur de la partie actuelle (après début ou changement de direction).
+ this.MPActualDist = 0;
+ this.SPActualDist = 0;
+ //Angles actuels.
+ this.MPActualAngle = -1;
+ this.SPActualAngle = -1;
+
+ //Centre du repère du pointeur principal.
+ this.MPrepX = null;
+ this.MPrepY = null;
+ //Centre du repère du pointeur secondaire.
+ this.SPrepX = null;
+ this.SPrepY = null;
+
+ //Coordonnées actuelles du/des pointeur/s.
+ this.MPx = 0;
+ this.MPy = 0;
+ this.SPx = 0;
+ this.SPy = 0;
+ //Coordonnées précédentes du/des pointeur/s.
+ this.MPpx = 0;
+ this.MPpy = 0;
+ this.SPpx = 0;
+ this.SPpy = 0;
+
+ //Si les paramètres sont incorrects, on leur donne une valeur par défaut.
+ if(isNaN(divisions) || divisions < 1 || divisions > 360)
+ {
+ this.divisions = 12;
+ }
+ if(sizeTreshold < 1)
+ {
+ sizeTreshold = 30;
+ }
+}
+
+/*
+ * Reinitialise les paramètres du détecteur.
+ * Est appelé dans le fichier :
+ * searchCanvas > fonction onPointerOut.
+*/
+CurvesDetector.prototype.reinit = function()
+{
+ this.MPrepX = 0;
+ this.MPrepY = 0;
+ this.MPpx = 0;
+ this.MPpy = 0;
+ this.MPActualAngle = -1;
+ this.SPActualAngle = -1;
+ this.actualCode = '';
+ this.MPActualDist = 0;
+ this.MPTotalDist = 0;
+}
+
+/*
+ * Met à jour les positions des pointeurs.
+ * Est appelé dans le fichier :
+ * searchCanvas > fonction onPointerMove.
+*/
+CurvesDetector.prototype.updatePos = function(mpx, mpy, spx, spy)
+{
+ //On met à jour les coordonnées récentes.
+ this.MPx = mpx;
+ this.MPy = mpy;
+
+ //Si les coordonnées précédentes n'existent pas, alors on les met à jour.
+ if(!this.MPpx)
+ {
+ this.MPpx = mpx;
+ }
+ if(!this.MPpy)
+ {
+ this.MPpy = mpy;
+ }
+ if(!this.MPrepX)
+ {
+ this.MPrepX = mpx;
+ }
+ if(!this.MPrepY)
+ {
+ this.MPrepY = mpy;
+ }
+
+ //Si on a un second pointeur.
+ if(spx && spy)
+ {
+ //On met les coordonnées à jour.
+ this.SPx = spx;
+ this.SPy = spy;
+
+ //Si les coordonnées précédentes n'existent pas, alors on les met à jour.
+ if(!this.SPpx)
+ {
+ this.SPpx = spx;
+ }
+ if(!this.SPpy)
+ {
+ this.SPpy = spy;
+ }
+ }
+
+ //On met à jour la distance des segments courants et on regarde les correspondances dans le dictionnaire.
+ this.updateDists();
+}
+
+/*
+ * Met à jour les distances parcourues.
+ * Est appelé dans le fichier :
+ * curvesDetector > fonction updatePos.
+*/
+CurvesDetector.prototype.updateDists = function()
+{
+ //Si on n'est pas en recherche pas courbes, on part.
+ if(!this.mosaic.isSearchByCurvesOn)
+ {
+ return;
+ }
+
+ var foundGestures;
+
+ //Si on a de quoi calculer les distances.
+ if(this.MPx && this.MPy && this.MPpx && this.MPpy && this.MPrepX && this.MPrepY)
+ {
+ //Distance entre les deux derniers points.
+ var MPDist = Math.floor(Math.sqrt((this.MPx - this.MPpx) * (this.MPx - this.MPpx) + (this.MPy - this.MPpy) * (this.MPy - this.MPpy)));
+ //On met à jour la distance totale de la courbe.
+ this.MPTotalDist += MPDist;
+ //Et aussi la distance du segment en cours.
+ this.MPActualDist += MPDist;
+
+ //Angle courant initialisé à -1.
+ var MPCurrentA = -1;
+
+ //Si la distance actuelle du segment existe.
+ if(MPDist > 0)
+ {
+ //On calcule l'angle courant entre ce segment et
+ MPCurrentA = this.currentAngle(this.MPrepX, this.MPrepY, this.MPx, this.MPy, this.divisions);
+ }
+
+ //Si la distance du segment actuel excède le seuil de la config et qu'il y a un angle.
+ if(this.MPActualDist > this.sizeTreshold && MPCurrentA != -1)
+ {
+ //Si l'angle affecté n'a pas encore de valeur ou si l'angle affecté est différent de l'angle calculé.
+ if(this.MPActualAngle == -1 || this.MPActualAngle != MPCurrentA)
+ {
+ //On affecte le nouvel angle.
+ this.MPActualAngle = MPCurrentA;
+ //On construit le code correspondant à ce segment.
+ this.actualCode += 'D' + MPCurrentA;
+ //On affecte le code dans la mosaique.
+ this.mosaic.actualCode = this.actualCode;
+ //On recherche les gestures commencant par ce code.
+ foundGestures = this.codeToGestures(this.actualCode);
+
+ //S'il n'y a pas de gestures trouvées ou s'il y en a plus d'une.
+ if(foundGestures.length == 0 || foundGestures.split(';').length != 1)
+ {
+ //On a trouvé quelque chose, même si ce qu'on a trouvé est vide ('').
+ this.mosaic.curvesGesturesFound = true;
+ //On notifie ce qu'on a trouvé. Dans le cas où c'est '', on affiche geste inconnu.
+ this.mosaic.removeNotifications();
+ this.mosaic.curvesGestures(foundGestures);
+
+ //Si ce qu'on a trouvé est vide et si l'aide n'est pas affichée.
+ if(foundGestures.length == 0 && !this.mosaic.helpDisplayed)
+ {
+ //On l'affiche.
+ this.mosaic.notifyHelp();
+ foundGestures = '';
+
+ //On enlève la recherche.
+ this.mosaic.curvesGesturesFound = false;
+ this.mosaic.isSearchByCurvesOn = false;
+ this.mosaic.leaveSearch();
+
+ //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.mosaic.currentMode == "FILTER" && this.mosaic.filterSearchedType == "")
+ {
+ this.mosaic.currentMode = "MOSAIC";
+ this.mosaic.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.mosaic.currentMode == "SEARCH" && this.mosaic.currentSearchGesture[this.centerId] == "")
+ {
+ this.mosaic.currentMode = "VIDEO";
+ }
+ }
+ //Si l'aide est déjà affichée, on l'enlève.
+ else if(foundGestures.split(';').length != 1 && this.mosaic.helpDisplayed)
+ {
+ this.mosaic.removeHelp();
+ }
+ }
+ //Si on a un seul résultat.
+ else
+ {
+ //On affecte la recherche.
+ this.mosaic.currentSearchGesture[this.mosaic.centerId] = foundGestures;
+ this.mosaic.isUserInSearchZone = false;
+
+ //Si on est en mode recherche et que le player est prêt.
+ if(this.mosaic.currentMode == "SEARCH" && this.mosaic.playerIsReady)
+ {
+ //On effectue la recherche.
+ this.mosaic.player.widgets[0].searchByGesture(foundGestures);
+ this.mosaic.isCurrentlyInASearchByGesture = this.mosaic.player.widgets[0].isCurrentlyInASearchByGesture;
+
+ //On notifie.
+ this.mosaic.removeNotifications();
+ this.mosaic.searchGesture(foundGestures, 'valid');
+
+ //S'il y a un marqueur trouvé au moins, on place le curseur sur le premier résultat.
+ if(this.mosaic.player && this.mosaic.player.widgets[0] && this.mosaic.timeToGoAt[this.mosaic.centerId] === 0 && this.mosaic.player.widgets[0].atLeastOneSearchMarker(this.mosaic.currentSearchGesture[this.mosaic.centerId]))
+ {
+ this.mosaic.player.widgets[0].goToFirstSearchedMarker(this.mosaic.currentSearchGesture[this.mosaic.centerId]);
+ }
+
+ //On enlève a recherche par courbes.
+ foundGestures = '';
+ this.mosaic.curvesGesturesFound = false;
+
+ this.mosaic.isSearchByCurvesOn = false;
+ this.mosaic.leaveSearch();
+ }
+ //Si on est en filtrage.
+ else if(this.mosaic.currentMode == "FILTER")
+ {
+ if(this.mosaic.isMosaicFiltered)
+ {
+ //On met à jour la gesture de filtrage.
+ this.mosaic.filterSearchedType = foundGestures;
+ //On filtre la mosaique.
+ this.mosaic.searchFilter(foundGestures);
+ this.mosaic.curvesGesturesFound = false;
+ //On notifie.
+ this.mosaic.removeNotifications();
+ this.mosaic.filterGesture(foundGestures, 'valid');
+
+ foundGestures = '';
+ //On enlève la recherche par courbes.
+ this.mosaic.isSearchByCurvesOn = false;
+ this.mosaic.leaveSearch();
+ }
+ }
+ }
+ //On réinitialise la distance entre les deux derniers points.
+ this.MPActualDist = 0;
+ }
+ //Sinon si l'angle n'a pas changé dans le segment en cours.
+ else
+ {
+ //On met à jour les dernières coordonnées du pointeur principal.
+ this.MPrepX = this.MPpx;
+ this.MPrepY = this.MPpy;
+ }
+
+ //Si l'angle affecté n'a pas encore de valeur.
+ if(this.MPActualAngle == -1)
+ {
+ //On le met à jour.
+ this.MPActualAngle = MPCurrentA;
+ }
+ }
+
+ //On met à jour les coordonnées précédentes.
+ if(this.MPpx != this.MPx)
+ {
+ this.MPpx = this.MPx;
+ }
+ if(this.MPpy != this.MPy)
+ {
+ this.MPpy = this.MPy;
+ }
+ }
+ //Idem au cas où on aurait un deuxième pointeur.
+ if(this.SPx && this.SPy && this.SPpx && this.SPpy)
+ {
+ //Distance entre les deux derniers points.
+ var SPDist = Math.floor(Math.sqrt((this.SPx - this.SPpx) * (this.SPx - this.SPpx) + (this.SPy - this.SPpy) * (this.SPy - this.SPpy)));
+ //On met à jour la distance totale de la courbe.
+ this.SPTotalDist += SPDist;
+ //Et aussi la distance du segment en cours.
+ this.SPActualDist += SPDist;
+
+ //Si la distance actuelle du segment existe.
+ if(SPDist > 0)
+ {
+ /*En développement*/
+ this.currentAngle(this.SPpx, this.SPpy, this.SPx, this.SPy);
+ }
+
+ //On met à jour les coordonnées précédentes.
+ if(this.SPpx != this.SPx)
+ {
+ this.SPpx = this.SPx;
+ }
+ if(this.SPpy != this.SPy)
+ {
+ this.SPpy = this.SPy;
+ }
+ }
+}
+
+/*
+ * Renvoie les noms de gestures du dictionnaire qui ont un code qui commence par le code en entrée.
+ * Est appelé dans le fichier :
+ * curvesDetector > fonction updateDists.
+*/
+CurvesDetector.prototype.codeToGestures = function(code)
+{
+ //Variable qui va stocker tous les noms trouvés.
+ var retNames = '';
+
+ //Pour tout le dictionnaire.
+ for(var i = 0 ; i < this.dictionary.length ; i++)
+ {
+ //Pour touts les codes de chaque gesture du dictionnaire.
+ for(var j = 0 ; j < this.dictionary[i].codes.length ; j++)
+ {
+ //Si le code en entrée est une partie début d'un des codes.
+ if(this.dictionary[i].codes[j].indexOf(code) == 0)
+ {
+ //On ajoute le nom de la gesture et on passe à la gesture suivante.
+ retNames += this.dictionary[i].name + ';';
+ break;
+ }
+ }
+ }
+ //Comme on sépare chaque nom par un ;, il faut supprimer le dernier si au moins un nom a été trouvé.
+ if(retNames.length > 0)
+ {
+ retNames = retNames.substring(0, retNames.length-1);
+ }
+
+ //On renvoit les noms.
+ return retNames;
+}
+
+/*
+ * Calcule l'angle emprunté par le morceau de segment actuel. On prend A va vers B.
+ * Est appelé dans le fichier :
+ * curvesDetector > fonction updateDists.
+*/
+CurvesDetector.prototype.currentAngle = function(xa, ya, xb, yb, divisions)
+{
+ //On calcule l'angle de la droite AB et des abscisses, et on effectue une rotation de 90° vers la gauche.
+ var angleRad = Math.atan2((ya - yb), (xa - xb)) - Math.PI / 2;
+ //On traduit les radians en divisions en passant de [-PI/2 ; PI/2] à [0 ; divisions - 1].
+ var angleDiv = Math.floor((angleRad > 0 ? angleRad : (2*Math.PI + angleRad)) * divisions / (2*Math.PI));
+
+ //L'angle initial est 0.
+ if(angleDiv == divisions)
+ {
+ angleDiv = 0;
+ }
+
+ return angleDiv;
}
\ No newline at end of file
diff -r 03ea3d7ddbe1 -r 277c94533395 front_idill/src/search/js/searchCanvas.js
--- a/front_idill/src/search/js/searchCanvas.js Mon Jul 23 10:52:41 2012 +0200
+++ b/front_idill/src/search/js/searchCanvas.js Mon Jul 23 16:59:35 2012 +0200
@@ -1,285 +1,295 @@
+/*
+* This file is part of the TraKERS\Front IDILL package.
+*
+* (c) IRI
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+/*
+ * Projet : TraKERS
+ * Module : Front IDILL
+ * Fichier : searchCanvas.js
+ *
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ *
+ * Fonctionnalités : Définit les fonctions de recherche par courbe de haut niveau (instantiation et manipulation de la classe de recherche par courbe mais pas les courbes en elles-mêmes ni le détecteur).
+ */
/*
* Déclaration du canvas de recherche par courbes.
+ * Est appelé dans le fichier :
+ * search > fonction startSearch.
*/
-function searchCanvas(_canvasTop, _canvasLeft, _canvasWidth, _canvasHeight, _margin_top, _fadeTime, _inMosaic, _mosaic)
+function SearchCanvas(_canvasTop, _canvasLeft, _canvasWidth, _canvasHeight, _margin_top, _fadeTime, _inMosaic, _mosaic)
{
- //Coordonnées, dimensions et autres paramètres du canvas.
- this.canvasTop = _canvasTop;
- this.canvasLeft = _canvasLeft;
- this.canvasWidth = _canvasWidth;
- this.canvasHeight = _canvasHeight;
- this.fadeTime = _fadeTime;
- this.margin_top = _margin_top;
-
- this.mosaic = _mosaic;
-
- //Courbe du pointeur principal.
- this.mainPath;
- this.mainPathStroke;
-
- //Courbe du pointeur secondaire.
- this.secondPath;
- this.secondPathStroke;
-
- //Courbe indicatrice de la direction actuelle.
- this.direction;
-
- //Point précédent des pointeurs.
- this.mainLastPoint;
- this.secondLastPoint;
-
- //Coordonnées précédentes des pointeurs.
- this.mainPointerLastX;
- this.mainPointerLastY;
- this.secondPointerLastX;
- this.secondPointerLastY;
-
- this.inMosaic = _inMosaic;
-
- this.detector;
+ //Coordonnées, dimensions et autres paramètres du canvas.
+ this.canvasTop = _canvasTop;
+ this.canvasLeft = _canvasLeft;
+ this.canvasWidth = _canvasWidth;
+ this.canvasHeight = _canvasHeight;
+ this.fadeTime = _fadeTime;
+ this.margin_top = _margin_top;
+
+ this.mosaic = _mosaic;
+
+ //Courbe du pointeur principal.
+ this.mainPath;
+ this.mainPathStroke;
+
+ //Courbe du pointeur secondaire.
+ this.secondPath;
+ this.secondPathStroke;
+
+ //Courbe indicatrice de la direction actuelle.
+ this.direction;
+
+ //Point précédent des pointeurs.
+ this.mainLastPoint;
+ this.secondLastPoint;
+
+ //Coordonnées précédentes des pointeurs.
+ this.mainPointerLastX;
+ this.mainPointerLastY;
+ this.secondPointerLastX;
+ this.secondPointerLastY;
+
+ this.inMosaic = _inMosaic;
+
+ this.detector;
}
/*
* Fonction d'initialisation du canvas de recherche par courbes.
+ * Est appelé dans le fichier :
+ * search > fonction startSearch.
*/
-searchCanvas.prototype.create = function(dictionary)
+SearchCanvas.prototype.create = function(dictionary)
{
- var _this = this;
-
- //On crée le canvas.
- var canvas = '
';
- //On l'ajoute à la page.
- $('body').append(canvas);
-
- $('.canvas').css(
- {
- top: this.canvasTop,
- left: this.canvasLeft
- });
-
- //S'il est dans la mosaique, on le réhausse en fonction de la taille de la marge verticale.
- if(this.inMosaic)
- {
- console.log(this.margin_top);
- $('.canvas').css(
- {
- "margin-top": this.margin_top
- });
- }
-
- //On instancie le détecteur de courbes de recherche.
- this.detector = new curvesDetector(6, 100, dictionary, this.mosaic);
-
- //On active le canvas.
- paper.setup('paperCanvas');
+ var _this = this;
+
+ //On crée le canvas.
+ var canvas = '
';
+ //On l'ajoute à la page.
+ $('body').append(canvas);
+
+ $('.canvas').css(
+ {
+ top: this.canvasTop,
+ left: this.canvasLeft
+ });
+
+ //S'il est dans la mosaique, on le réhausse en fonction de la taille de la marge verticale.
+ if(this.inMosaic)
+ {
+ $('.canvas').css(
+ {
+ "margin-top": this.margin_top
+ });
+ }
+
+ //On instancie le détecteur de courbes de recherche.
+ this.detector = new CurvesDetector(6, 100, dictionary, this.mosaic);
+
+ //On active le canvas.
+ paper.setup('paperCanvas');
};
/*
* Fonction appelée pour quitter le mode de recherche par courbes.
+ * Est appelé dans le fichier :
+ * search > fonction leaveSearch.
*/
-searchCanvas.prototype.leaveSearch = function()
+SearchCanvas.prototype.leaveSearch = function()
{
- $('.canvas').fadeTo(this.fadeTime, 0, function()
- {
- $('.canvas').remove();
- });
+ $('.canvas').fadeTo(this.fadeTime, 0, function()
+ {
+ $('.canvas').remove();
+ });
};
/*
* Fonction de déclaration des courbes.
+ * Est appelé dans les fichiers :
+ * mosaic > fonctions onMouseDown et onMouseMove.
+ * client > fonction processMsg.
*/
-searchCanvas.prototype.onPointerIn = function(mainPointerX, mainPointerY, secondPointerX, secondPointerY)
+SearchCanvas.prototype.onPointerIn = function(mainPointerX, mainPointerY, secondPointerX, secondPointerY)
{
- if(this.mosaic.currentMode != 'MOSAIC' && this.mosaic.currentMode != 'FILTER')
- {
- mainPointerX -= 130;
- mainPointerY -= 60;
- }
-
- //On obtient les coordonnées du pointeur principal en px.
- mainPointerX = Math.floor(mainPointerX);
- mainPointerY = Math.floor(mainPointerY);
-
- //On forme le contour la courbe principale.
- this.mainPathStroke = new paper.Path();
- this.mainPathStroke.strokeColor = '#366F7A';
- this.mainPathStroke.strokeWidth = 18;
- this.mainPathStroke.strokeCap = 'round';
- this.mainPathStroke.strokeJoin = 'round';
-
- //On forme la courbe principale.
- this.mainPath = new paper.Path();
- this.mainPath.strokeColor = '#02FEFF';
- this.mainPath.strokeWidth = 10;
- this.mainPath.strokeCap = 'round';
- this.mainPath.strokeJoin = 'round';
-
- /*this.direction = new paper.Path();
- this.direction.strokeColor = '#FF0000';
- this.direction.strokeWidth = 5;
- this.direction.strokeCap = 'round';
- this.direction.strokeJoin = 'round';*/
-
- //Si on a un pointeur secondaire
- if(secondPointerX && secondPointerY)
- {
- //On obtient les coordonnées du pointeur secondaire en px.
- secondPointerX = Math.floor(secondPointerX);
- secondPointerY = Math.floor(secondPointerY);
-
- //On forme le contour de la courbe secondaire.
- this.secondPathStroke = new paper.Path();
- this.secondPathStroke.fillColor = '#366F7A';
- this.secondPathStroke.strokeWidth = 12;
- this.secondPathStroke.strokeCap = 'round';
- this.secondPathStroke.strokeJoin = 'round';
-
- //On forme la courbe secondaire.
- this.secondPath = new paper.Path();
- this.secondPath.fillColor = '#02FEFF';
- this.secondPath.strokeWidth = 10;
- this.secondPath.strokeCap = 'round';
- this.secondPath.strokeJoin = 'round';
- }
-
- // console.log('IN');
-
- //On raffraichit l'affichage.
- paper.view.draw();
+ if(this.mosaic.currentMode != 'MOSAIC' && this.mosaic.currentMode != 'FILTER')
+ {
+ mainPointerX -= 130;
+ mainPointerY -= 60;
+ }
+
+ //On obtient les coordonnées du pointeur principal en px.
+ mainPointerX = Math.floor(mainPointerX);
+ mainPointerY = Math.floor(mainPointerY);
+
+ //On forme le contour la courbe principale.
+ this.mainPathStroke = new paper.Path();
+ this.mainPathStroke.strokeColor = '#366F7A';
+ this.mainPathStroke.strokeWidth = 18;
+ this.mainPathStroke.strokeCap = 'round';
+ this.mainPathStroke.strokeJoin = 'round';
+
+ //On forme la courbe principale.
+ this.mainPath = new paper.Path();
+ this.mainPath.strokeColor = '#02FEFF';
+ this.mainPath.strokeWidth = 10;
+ this.mainPath.strokeCap = 'round';
+ this.mainPath.strokeJoin = 'round';
+
+ //Si on a un pointeur secondaire
+ if(secondPointerX && secondPointerY)
+ {
+ //On obtient les coordonnées du pointeur secondaire en px.
+ secondPointerX = Math.floor(secondPointerX);
+ secondPointerY = Math.floor(secondPointerY);
+
+ //On forme le contour de la courbe secondaire.
+ this.secondPathStroke = new paper.Path();
+ this.secondPathStroke.fillColor = '#366F7A';
+ this.secondPathStroke.strokeWidth = 12;
+ this.secondPathStroke.strokeCap = 'round';
+ this.secondPathStroke.strokeJoin = 'round';
+
+ //On forme la courbe secondaire.
+ this.secondPath = new paper.Path();
+ this.secondPath.fillColor = '#02FEFF';
+ this.secondPath.strokeWidth = 10;
+ this.secondPath.strokeCap = 'round';
+ this.secondPath.strokeJoin = 'round';
+ }
+
+ //On raffraichit l'affichage.
+ paper.view.draw();
};
/*
* Fonction appelée lorsque les pointeurs bougent pour construire la courbe.
+ * Est appelé dans les fichiers :
+ * mosaic > fonction onMouseMove.
+ * client > fonction processMsg.
*/
-searchCanvas.prototype.onPointerMove = function(mainPointerX, mainPointerY, secondPointerX, secondPointerY)
+SearchCanvas.prototype.onPointerMove = function(mainPointerX, mainPointerY, secondPointerX, secondPointerY)
{
- // console.log('MOVE');
-
- if(this.mosaic.currentMode != 'MOSAIC' && this.mosaic.currentMode != 'FILTER')
- {
- mainPointerX -= 130;
- mainPointerY -= 60;
- }
-
- if(!this.mainPointerLastX || !this.mainPointerLastY)
- {
- this.mainPointerLastX = mainPointerX;
- this.mainPointerLastY = mainPointerY;
- }
-
- //On obtient les coordonnées du pointeur principal en px.
- mainPointerX = Math.floor(mainPointerX);
- mainPointerY = Math.floor(mainPointerY);
-
- //On crée les points de la courbe principale.
- var mainPoint = new paper.Point(mainPointerX, mainPointerY);
- var mainPointStroke = new paper.Point(mainPointerX, mainPointerY);
-
- //On les ajoute à la courbe.
- this.mainPathStroke.add(mainPointStroke);
- this.mainPathStroke.smooth();
-
- this.mainPath.add(mainPoint);
- this.mainPath.smooth();
-
- //this.direction.remove();
- // console.log(this.mainPointerLastX, this.mainPointerLastY);
- /*var directionPoint = new paper.Point(this.mainPointerLastX, this.mainPointerLastY);
- var directionPointEnd = new paper.Point((mainPointerX - this.mainPointerLastX) * 2 + mainPointerX, (mainPointerY - this.mainPointerLastY) * 2 + mainPointerY);
- this.direction.add(directionPoint);
- this.direction.add(directionPointEnd);
- this.direction.smooth();*/
-
- //Variables de construction de la courbe secondaire.
- var secondPoint, secondDelta, secondStep, secondStepStroke, secondTop, secondBottom, secondTopStroke, secondBottomStroke;
-
- //Si on a un pointeur secondaire.
- if(secondPointerX && secondPointerY)
- {
- //On obtient les coordonnées du pointeur secondaire en px.
- secondPointerX = Math.floor(secondPointerX);
- secondPointerY = Math.floor(secondPointerY);
-
- //On crée les points de la courbe secondaire.
- secondPoint = new paper.Point(mainPointerX, mainPointerY);
- secondPointStroke = new paper.Point(mainPointerX, mainPointerY);
-
- //On les ajoute à la courbe.
- this.secondPathStroke.add(secondPointStroke);
- this.secondPathStroke.smooth();
-
- this.secondPath.add(secondPoint);
- this.secondPath.smooth();
- }
-
- if(this.mainPointerLastX != mainPointerX)
- {
- this.mainPointerLastX = mainPointerX;
- }
- if(this.mainPointerLastY != mainPointerY)
- {
- this.mainPointerLastY = mainPointerY;
- }
-
- //On met à jour les points dans le détecteur de courbes.
- this.detector.updatePos(mainPointerX, mainPointerY);
-
- //On met à jour l'affichage.
- paper.view.draw();
+ //Si on est dans une video, on réhausse
+ if(this.mosaic.currentMode != 'MOSAIC' && this.mosaic.currentMode != 'FILTER')
+ {
+ mainPointerX -= 130;
+ mainPointerY -= 60;
+ }
+
+ //On obtient les coordonnées du pointeur principal en px.
+ mainPointerX = Math.floor(mainPointerX);
+ mainPointerY = Math.floor(mainPointerY);
+
+ //Si les coordonnées du pointeur principal n'ont pas été affectées, on les affecte.
+ if(!this.mainPointerLastX || !this.mainPointerLastY)
+ {
+ this.mainPointerLastX = mainPointerX;
+ this.mainPointerLastY = mainPointerY;
+ }
+
+ //On crée les points de la courbe principale.
+ var mainPoint = new paper.Point(mainPointerX, mainPointerY);
+ var mainPointStroke = new paper.Point(mainPointerX, mainPointerY);
+
+ //On les ajoute à la courbe.
+ this.mainPathStroke.add(mainPointStroke);
+ this.mainPathStroke.smooth();
+
+ //On place le premier point de la courbe, qu'on lisse.
+ this.mainPath.add(mainPoint);
+ this.mainPath.smooth();
+
+ //Variables de construction de la courbe secondaire.
+ var secondPoint, secondDelta, secondStep, secondStepStroke, secondTop, secondBottom, secondTopStroke, secondBottomStroke;
+
+ //Si on a un pointeur secondaire.
+ if(secondPointerX && secondPointerY)
+ {
+ //On obtient les coordonnées du pointeur secondaire en px.
+ secondPointerX = Math.floor(secondPointerX);
+ secondPointerY = Math.floor(secondPointerY);
+
+ //Si les coordonnées du pointeur principal n'ont pas été affectées, on les affecte.
+ if(!this.secondPointerLastX || !this.secondPointerLastY)
+ {
+ this.secondPointerLastX = secondPointerX;
+ this.secondPointerLastY = secondPointerY;
+ }
+
+ //On crée les points de la courbe secondaire.
+ secondPoint = new paper.Point(mainPointerX, mainPointerY);
+ secondPointStroke = new paper.Point(mainPointerX, mainPointerY);
+
+ //On les ajoute à la courbe.
+ this.secondPathStroke.add(secondPointStroke);
+ this.secondPathStroke.smooth();
+
+ //On place le premier point de la seconde courbe, qu'on lisse.
+ this.secondPath.add(secondPoint);
+ this.secondPath.smooth();
+
+ //On met l'avant dernière position du pointeur secondaire à jour.
+ if(this.secondPointerLastX != secondPointerX)
+ {
+ this.secondPointerLastX = secondPointerX;
+ }
+ if(this.secondPointerLastY != secondPointerY)
+ {
+ this.secondPointerLastY = secondPointerY;
+ }
+ }
+
+ //On met l'avant dernière position du pointeur principal à jour.
+ if(this.mainPointerLastX != mainPointerX)
+ {
+ this.mainPointerLastX = mainPointerX;
+ }
+ if(this.mainPointerLastY != mainPointerY)
+ {
+ this.mainPointerLastY = mainPointerY;
+ }
+
+ //On met à jour les points dans le détecteur de courbes.
+ this.detector.updatePos(mainPointerX, mainPointerY);
+
+ //On met à jour l'affichage.
+ paper.view.draw();
};
/*
* Fonction appelée lorsqu'on cesse de dessiner une courbe.
+ * Est appelé dans les fichiers :
+ * mosaic > fonction onMouseUp.
+ * client > fonction processMsg.
*/
-searchCanvas.prototype.onPointerOut = function()
+SearchCanvas.prototype.onPointerOut = function()
{
- // console.log('OUT');
-
- //On réinitialise la courbe principale.
- this.mainPathStroke.remove();
- this.mainPath.remove();
-
- this.mainPointerLastX = 0;
- this.mainPointerLastY = 0;
-
- // this.direction.remove();
-
- this.detector.reinit();
-
- //Si on a un second pointeur, on réinitialise la courbe secondaire.
- if(this.secondPathStroke)
- {
- this.secondPathStroke.remove();
- }
- if(this.secondPath)
- {
- this.secondPath.remove();
- }
-
- //On met à jour l'affichage.
- paper.view.draw();
-};
-
-searchCanvas.prototype.onKeyDown = function(event)
-{
- //S'il n'y a rien a colorier, on quitte.
- if(typeof this.pathStroke === 'undefined' || typeof this.path === 'undefined')
- return;
-
- if(event.key == 'r' || event.key == 'R')
- {
- this.pathStroke.fillColor = '#49564F';
- this.path.fillColor = '#00FE00'
- }
- else if(event.key == 'x' || event.key == 'X')
- {
- this.pathStroke.fillColor = '#535F6D';
- this.path.fillColor = '#CCCCCC'
- }
- else if(event.key == 'w' || event.key == 'W')
- {
- this.pathStroke.fillColor = '#366F7A';
- this.path.fillColor = '#02FEFF'
- }
+ //On réinitialise la courbe principale.
+ this.mainPathStroke.remove();
+ this.mainPath.remove();
+
+ this.mainPointerLastX = 0;
+ this.mainPointerLastY = 0;
+
+ //On réinitialise le détecteur.
+ this.detector.reinit();
+
+ //Si on a un second pointeur, on réinitialise la courbe secondaire.
+ if(this.secondPathStroke)
+ {
+ this.secondPathStroke.remove();
+ }
+ if(this.secondPath)
+ {
+ this.secondPath.remove();
+ }
+
+ //On met à jour l'affichage.
+ paper.view.draw();
};
\ No newline at end of file
diff -r 03ea3d7ddbe1 -r 277c94533395 front_processing/doc/tutorial front processing.html
--- a/front_processing/doc/tutorial front processing.html Mon Jul 23 10:52:41 2012 +0200
+++ b/front_processing/doc/tutorial front processing.html Mon Jul 23 16:59:35 2012 +0200
@@ -12,6 +12,8 @@
Le deuxième module de ce projet est un Front en Processing doté d'un client TUIO et récupérant les messages OSC (sous forme d'objets tels que des Curseurs ou des Strings).
Ce tutoriel concerne ce second module et a pour but d'expliquer le fonctionnement général d'un sketch Processing et la récupération des notifications du Middleware. Il sera agrémenté d'exemples fonctionnels créés pour les besoins de ce tutoriel ou inspirés d'exemples réels disponibles sur le site processing.org.
+
+
Sommaire
- Installation de Processing
@@ -26,7 +28,7 @@
- - Installation de Processing
+
Avant de pouvoir modifier les sketches Processing fournis dans l'installateur, il est nécessaire d'installer Processing.
@@ -42,7 +44,7 @@
- - Structure d'un sketch
+
Un sketch est représenté par un dossier, contenant plusieurs choses :
@@ -68,7 +70,7 @@
- - Fonctions principales de Processing
+
En Processing, les variables déclarées absolues (en dehors d'une fonction ou d'une classe) sont visibles dans tous les autres fichiers .pde du sketch. Il en va de même pour les classes et fonctions (et non méthodes de classe, qui est une fonction appartenant à la classe et donc ne pouvant être appelée qu'en créant un objet de cette classe).
@@ -101,7 +103,7 @@
- - Récupérer les objets envoyés par le Middleware TraKERS via un Client TUIO
+
Les objets TUIO exploités dans le cadre de TraKERS sont de deux types :
@@ -190,7 +192,7 @@
- - Interactions entre les objets TUIO récupérés et des fonctions de dessin basiques
+
Dans les exemples de code vu précédemment, nous aurions pu remplacer la fonction text() par une fonction de votre cru, comme celle-ci :
@@ -229,7 +231,7 @@
- - Quelques exemples d'implémentation
+
Les exemples fournis dans l'installeur sont répartis dans 4 dossiers principaux :
@@ -245,7 +247,7 @@
- - Références
+
Voici quelques liens utiles où se trouvent les dépendances trop lourdes pour être incluses dans cet installeur. Ils vont permettront également d'approfondissant vos connaissances sur Processing ou TUIO.