20 /* |
20 /* |
21 * Classe définissant la mosaïque. |
21 * Classe définissant la mosaïque. |
22 * Elle contient sa longueur, le nombre d'images total, une liste d'urls pour les vidéos, leurs snapshots principaux et leur position. |
22 * Elle contient sa longueur, le nombre d'images total, une liste d'urls pour les vidéos, leurs snapshots principaux et leur position. |
23 * Contient également les dimensions en px de la mosaïque. |
23 * Contient également les dimensions en px de la mosaïque. |
24 */ |
24 */ |
25 function mosaic(len, imgToShow, imgTotal, zoomPercentage, prezoomPercentage, zoomedMargin) |
25 function mosaic(config, default_conf) |
26 { |
26 { |
27 //S'il s'agit d'un rectangle. |
27 //Chemin du fichier de configuration. |
28 if(imgToShow % len == 0) |
28 this.config_path = config; |
29 { |
29 //Configuration par défaut en cas de valeur erronnée. |
30 //Longueur horizontale. |
30 this.default_config = default_conf; |
31 this.length = len; |
31 this.config = new Object(); |
32 //Nombre d'images dans la mosaïque. |
32 //Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque. |
33 this.imagesToShow = imgToShow; |
33 this.videos = []; |
34 this.imagesTotal = imgTotal; |
34 this.urls = []; |
35 //Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque. |
35 this.imgs = []; |
36 this.videos = []; |
36 this.ids = []; |
37 this.urls = []; |
37 this.fillingIds = []; |
38 this.imgs = []; |
38 this.currentRandomVideoIdx = 0; |
39 this.ids = []; |
39 |
40 //On remplit le tableau d'ids. |
40 //Dimensions de la mosaïque en pixels. |
41 for(var i = 0 ; i < this.imagesTotal ; i++) |
41 this.width; |
42 this.ids.push(i); |
42 this.height; |
43 //On les mélange. |
43 //Dimensions d'un snapshot en pixels. |
44 this.ids.sort(function() |
44 this.snapshotWidth; |
45 { |
45 this.snapshotHeight; |
46 return 0.5 - Math.random() |
46 //Espacement entre les snapshots en pixels. |
47 }); |
47 this.marginWidth; |
48 |
48 |
49 console.log(this.ids); |
49 //Booléens permettant ou non certaines intéractions selon le contexte. |
50 |
50 this.zoomed; |
51 //Dimensions de la mosaïque en pixels. |
51 this.fullscreen; |
52 this.width; |
52 this.canMoveToNeighbour; |
53 this.height; |
53 this.helpDisplayed; |
54 //Dimensions d'un snapshot en pixels. |
54 |
55 this.snapshotWidth; |
55 //Type de marqueur recherché dans la mosaïque (en mode filter). |
56 this.snapshotHeight; |
56 this.filterSearchedType = ""; |
57 //Espacement entre les snapshots en pixels. |
57 |
58 this.marginWidth; |
58 //Mode actuel. |
59 |
59 this.currentMode = "MOSAIC"; |
60 //Temps d'intéractions/d'animations. |
60 //Snapshot sur lequel on a zoomé. |
61 this.preZoomTime; |
61 this.previousZoomedSN; |
62 this.preUnzoomTime; |
62 //Son ID. |
63 this.zoomTime; |
63 this.previousId; |
64 this.unzoomTime; |
64 //Largeur de la marge pour le centrage vertical de la mosaïque. |
65 this.timeNeighbourGlowing; |
65 this.MPTop_margin; |
66 this.timeNeighbourUnglowing; |
66 this.top_margin; |
67 this.timeMovingToNeighbour; |
67 |
68 this.timeSearchFade; |
68 //Mosaïque locale. |
69 this.timeNotifyFade; |
69 this.localMos; |
70 |
70 //Position des voisins lors d'un zoom. |
71 //Booléens permettant ou non certaines intéractions selon le contexte. |
71 this.neighboursIds = []; |
72 this.zoomed; |
72 //ID du snapshot du milieu lors d'un zoom. |
73 this.fullscreen; |
73 this.centerId; |
74 this.canMoveToNeighbour; |
74 |
75 this.helpDisplayed; |
75 //Snapshots a afficher. |
76 |
76 this.snapshotsToShow = 1; |
77 //Mode actuel. |
77 |
78 this.currentMode; |
78 //Lecteur. |
79 //Snapshot sur lequel on a zoomé. |
79 this.player; |
80 this.previousZoomedSN; |
80 //Annotations (pour les marqueurs los d'un filtrage). |
81 //Son ID. |
81 this.annotations = []; |
82 this.previousId; |
82 |
83 //Largeur de la marge pour le centrage vertical de la mosaïque. |
83 //Coordonnées et dimensions d'un snapshot zoomé. |
84 this.MPTop_margin; |
84 this.snTop = 0; |
85 this.top_margin; |
85 this.snLeft = 0; |
86 //Pourcentage d'agrandissement lors d'un prézoom et d'un zoom. |
86 this.snWidth = 0; |
87 this.prezoomPercentage = prezoomPercentage; |
87 this.snHeight = 0; |
88 this.zoomPercentage = zoomPercentage; |
88 |
89 //Espacement des snapshots après un zoom. |
89 this.searchCanvas; |
90 this.zoomedMargin = zoomedMargin; |
90 //Position actuelle de la vidéo zoomée. |
91 //Mosaïque locale. |
91 this.notifyTopVideo; |
92 this.localMos; |
92 this.notifyLeftVideo; |
93 //Position des voisins lors d'un zoom. |
93 this.loadParameters(this.config_path); |
94 this.neighboursIds = []; |
|
95 //ID du snapshot du milieu lors d'un zoom. |
|
96 this.centerId; |
|
97 |
|
98 //Lecteur. |
|
99 this.player; |
|
100 |
|
101 //Coordonnées et dimensions d'un snapshot zoomé. |
|
102 this.snTop = 0; |
|
103 this.snLeft = 0; |
|
104 this.snWidth = 0; |
|
105 this.snHeight = 0; |
|
106 |
|
107 this.searchCanvas; |
|
108 |
|
109 this.loadFromJson('./player/json/videos.json'); |
|
110 } |
|
111 else |
|
112 { |
|
113 //Affiche un message d'erreur. |
|
114 } |
|
115 } |
94 } |
116 |
95 |
117 /* |
96 /* |
118 * Méthode d'affichage de la mosaïque. |
97 * Méthode d'affichage de la mosaïque. |
119 * Génère une matrice de imgs. |
98 * Génère une matrice de imgs. |
120 */ |
99 */ |
121 mosaic.prototype.createMosaic = function() |
100 mosaic.prototype.createMosaic = function() |
122 { |
101 { |
123 this.previousZoomedSN = ''; |
102 console.log('CREATE'); |
124 this.previousPrezoomDiv = ''; |
103 this.currentMode = "NO-USER"; |
125 this.fullscreen = false; |
104 var initPanel = '<div id="initPanel"></div>'; |
126 this.canMoveToNeighbour = false; |
105 var mp = $('#mainPanel'); |
127 this.helpDisplayed = false; |
106 mp.append(initPanel); |
128 var str = ''; |
107 $('#initPanel').css( |
129 |
108 { |
130 if(this.imgs.length >= this.imagesToShow) |
109 background: 'transparent', |
|
110 width: mp.width(), |
|
111 height: mp.height(), |
|
112 top: mp.position().top, |
|
113 left: mp.position().left, |
|
114 'margin-top': this.MPTop_margin |
|
115 }); |
|
116 |
|
117 var len = this.config['length'], imgs = this.config['imagesToShow'], imgsTotal = this.config['imagesTotal']; |
|
118 |
|
119 //S'il s'agit d'un rectangle. |
|
120 if(imgs % len == 0) |
131 { |
121 { |
132 for(var i = 0 ; i < this.imagesToShow ; i++) |
122 this.previousZoomedSN = ''; |
133 { |
123 this.previousPrezoomDiv = ''; |
134 //On charge les images de petite taille pour ne pas surcharger la mosaïque lors de l'affichage global. |
124 this.fullscreen = false; |
135 str += '<div id="snapshotDiv-' + i + '" class="snapshotDivs"><img id="snapshot-' + i + '" class="snapshots" src="snapshots-little/' + this.imgs[i] + '" /></div>'; |
125 this.canMoveToNeighbour = false; |
136 } |
126 this.helpDisplayed = false; |
137 } |
127 var str = ''; |
138 |
128 |
139 console.log(this.imagesToShow); |
129 if(this.imgs.length >= imgs) |
140 |
130 { |
141 return str; |
131 for(var i = 0 ; i < imgs ; i++) |
|
132 { |
|
133 //On charge les images de petite taille pour ne pas surcharger la mosaïque lors de l'affichage global. |
|
134 str += '<div id="snapshotDiv-' + i + '" class="snapshotDivs" style="opacity: 0;"><img id="snapshot-' + i + '" class="snapshots" src="snapshots-little/' + this.imgs[i] + '" /></div>'; |
|
135 } |
|
136 } |
|
137 |
|
138 return str; |
|
139 } |
|
140 else |
|
141 { |
|
142 alert("Le nombre d'images a afficher doit être divisible par la longueur de la mosaïque !"); |
|
143 } |
142 } |
144 } |
143 |
145 |
144 /* |
146 /* |
145 * Permet de raffraichir la mosaïque. |
147 * Permet de raffraichir la mosaïque. |
146 */ |
148 */ |
147 mosaic.prototype.loadMosaic = function() |
149 mosaic.prototype.loadMosaic = function() |
148 { |
150 { |
|
151 console.log('LOAD'); |
149 var createMosaic = this.createMosaic(); |
152 var createMosaic = this.createMosaic(); |
150 |
153 |
151 if(createMosaic == '') |
154 if(createMosaic == '') |
152 { |
155 { |
153 return; |
156 return; |
181 $('.snapshotDivs').mouseenter(function () |
184 $('.snapshotDivs').mouseenter(function () |
182 { |
185 { |
183 //On effectue un prézoom dès qu'on va sur une image. |
186 //On effectue un prézoom dès qu'on va sur une image. |
184 _this.preZoom($(this)); |
187 _this.preZoom($(this)); |
185 }); |
188 }); |
186 $('body').keypress(function (event) |
189 |
187 { |
190 this.addPointers(); |
188 //Si on a appuié sur la touche 'q' ou 'Q'; |
191 |
189 if(event.which == 113 || event.which == 81) |
192 //Si dans le metadata player _ n'est pas déclaré, on le déclare. |
190 { |
193 if(typeof _ !== "undefined" && typeof IriSP._ === "undefined") |
191 _this.unzoom(); |
194 { |
192 } |
195 IriSP._ = _; |
193 }); |
196 } |
|
197 |
|
198 if(typeof $ !== "undefined" && typeof IriSP.jQuery === "undefined") |
|
199 { |
|
200 IriSP.jQuery = $; |
|
201 } |
|
202 |
|
203 //On charge les marqueurs. |
|
204 var sourceManager = new IriSP.Model.Directory(), |
|
205 globalAnnotations = new IriSP.Model.List(sourceManager), |
|
206 nbFichiers = _this.urls.length, |
|
207 fichiersCharges = 0; |
|
208 |
|
209 for (var i = 0; i < nbFichiers; i++) |
|
210 { |
|
211 console.log('url : ' + _this.urls[i]); |
|
212 var source = sourceManager.remoteSource({url: _this.urls[i], serializer: IriSP.serializers.ldt}); |
|
213 source.onLoad(function() |
|
214 { |
|
215 globalAnnotations.addElements(source.getAnnotations()); |
|
216 fichiersCharges++; |
|
217 if (fichiersCharges == nbFichiers) |
|
218 { |
|
219 // instructions à exécuter quand tout est chargé |
|
220 _this.annotations = globalAnnotations; |
|
221 console.log('annotations loaded'); |
|
222 _this.init(); |
|
223 } |
|
224 }); |
|
225 } |
|
226 } |
|
227 |
|
228 /* |
|
229 * Charge les paramètres du Front. Local (true/false) est le mode de chargement des données. |
|
230 */ |
|
231 mosaic.prototype.loadParameters = function(file_path) |
|
232 { |
|
233 var _this = this; |
|
234 |
|
235 var supposedToBeInt = ['length', 'imagesToShow', 'totalImages', 'timePrezoom', 'timePreUnzoom', 'timeZoom', 'timeUnzoom', 'timeNeighbourGlowing', 'timeNeighbourUnglowing', 'timeMovingToNeighbour', 'timeSearchFade', 'timeNotifyFade', 'timeFilterFade', 'timeFilling', 'zoomedMargin']; |
|
236 var supposedToBeFloat = ['zoomPercentage', 'prezoomPercentage']; |
|
237 |
|
238 $.getJSON(file_path, function(data) |
|
239 { |
|
240 for(key in data) |
|
241 { |
|
242 var val = data[key]; |
|
243 |
|
244 if(_.include(supposedToBeInt, key)) |
|
245 { |
|
246 var intVal = parseInt(val); |
|
247 if(isNaN(intVal)) |
|
248 { |
|
249 console.log(_this.default_config); |
|
250 _this.config[key] = _this.default_config[key]; |
|
251 console.log("param[" + key + "] : Valeur " + val + " incorrecte (non Int). Valeur par défaut " + _this.default_config[key] + " chargée à la place."); |
|
252 } |
|
253 else |
|
254 { |
|
255 _this.config[key] = intVal; |
|
256 } |
|
257 } |
|
258 else if(_.include(supposedToBeFloat, key)) |
|
259 { |
|
260 var floatVal = parseFloat(val); |
|
261 if(isNaN(floatVal)) |
|
262 { |
|
263 _this.config[key] = _this.default_config[key]; |
|
264 console.log("param[" + key + "] : Valeur " + val + " incorrecte (non Float). Valeur par défaut " + _this.default_config[key] + " chargée à la place."); |
|
265 } |
|
266 else |
|
267 { |
|
268 _this.config[key] = floatVal; |
|
269 } |
|
270 } |
|
271 else |
|
272 { |
|
273 _this.config[key] = val; |
|
274 } |
|
275 } |
|
276 |
|
277 //On remplit le tableau d'ids. |
|
278 for(var i = 0 ; i < _this.config['totalImages'] ; i++) |
|
279 _this.ids.push(i); |
|
280 //On les mélange. |
|
281 _this.ids.sort(function() |
|
282 { |
|
283 return 0.5 - Math.random() |
|
284 }); |
|
285 |
|
286 //On remplit le tableau d'ids destiné à afficher les snapshots au fur et à mesure. |
|
287 for(var i = 0 ; i < _this.config['imagesToShow'] ; i++) |
|
288 _this.fillingIds.push(i); |
|
289 //On les mélange. |
|
290 _this.fillingIds.sort(function() |
|
291 { |
|
292 return 0.5 - Math.random() |
|
293 }); |
|
294 |
|
295 if(_this.config['local'] == 'true') |
|
296 { |
|
297 console.log("Loading local metadata."); |
|
298 _this.loadFromJson('./player/json/local_videos.json'); |
|
299 } |
|
300 else |
|
301 { |
|
302 console.log("Loading online metadata."); |
|
303 _this.loadFromJson('./player/json/online_videos.json'); |
|
304 } |
|
305 }); |
|
306 } |
|
307 |
|
308 /* |
|
309 * Phase principale (utilisateur non détecté). Une vidéo se lance aléatoirement. |
|
310 * L'interface est identique à celle du zoom, mais sans interaction possible avec les voisins, ni les controles timeline. |
|
311 * Lors de la fin d'une lecture, on dézoome vers la mosaïque, puis on rezoome vers un autre snapshot (aléatoire). |
|
312 */ |
|
313 mosaic.prototype.init = function() |
|
314 { |
|
315 var _this = this; |
|
316 |
|
317 if(this.currentRandomVideoIdx > this.config['imagesToShow']) |
|
318 { |
|
319 this.currentRandomVideoIdx = 0; |
|
320 } |
|
321 |
|
322 this.previousZoomedSN = $('#snapshotDiv-' + this.fillingIds[this.currentRandomVideoIdx]); |
|
323 this.previousId = $('img', this.previousZoomedSN).attr('id'); |
|
324 |
|
325 console.log('ids', this.fillingIds[this.currentRandomVideoIdx]); |
|
326 |
|
327 this.previousZoomedSN.fadeTo(this.config['timePrezoom'], 1, function() |
|
328 { |
|
329 _this.zoom(); |
|
330 _this.currentRandomVideoIdx++; |
|
331 }); |
|
332 } |
|
333 |
|
334 /* |
|
335 * Remplissage de la mosaïque en fonction du nombre d'images à afficher. |
|
336 */ |
|
337 mosaic.prototype.showNImages = function(n) |
|
338 { |
|
339 if(n > 1) |
|
340 { |
|
341 this.currentMode = "INCOMING-" + n; |
|
342 this.unzoom(); |
|
343 } |
|
344 |
|
345 for(var i = 0 ; i < n ; i++) |
|
346 { |
|
347 if($('#snapshotDiv-' + i).css('opacity') < 1) |
|
348 { |
|
349 $('#snapshotDiv-' + i).fadeTo(this.config['timeFilling'], 1); |
|
350 } |
|
351 } |
|
352 } |
|
353 |
|
354 /* |
|
355 * Affiche les pointeurs. |
|
356 */ |
|
357 mosaic.prototype.addPointers = function() |
|
358 { |
|
359 var _this = this; |
|
360 |
|
361 var mainPointer = '<div id="mainPointer" class="pointers"></div>'; |
|
362 $('body').append(mainPointer); |
|
363 $('body').mousemove(function(evt) |
|
364 { |
|
365 $('#mainPointer').css( |
|
366 { |
|
367 top: evt.pageY - $('#mainPointer').height()/2, |
|
368 left: evt.pageX - $('#mainPointer').width()/2 |
|
369 }); |
|
370 }); |
|
371 } |
|
372 |
|
373 /* |
|
374 * Gère les événements de contrôle dans la mosaïque. |
|
375 */ |
|
376 mosaic.prototype.manageControlEvents = function(event) |
|
377 { |
|
378 console.log('manage'); |
|
379 //Sinon si on a appuyé sur 'g' ou 'G'. |
|
380 if(event.which == 103 || event.which == 71) |
|
381 { |
|
382 //Si on est déjà en recherche par courbes. |
|
383 if(this.currentMode == "SEARCH" || this.currentMode == "FILTER") |
|
384 { |
|
385 //On quitte cette recherche. |
|
386 this.leaveSearch(); |
|
387 //Si on était en mode recherche. |
|
388 if(this.currentMode == "SEARCH") |
|
389 { |
|
390 //On revient dans la vidéo. |
|
391 this.currentMode = "VIDEO"; |
|
392 } |
|
393 else |
|
394 { |
|
395 //Sinon c'est qu'on était dans la mosaïque. |
|
396 this.currentMode = "MOSAIC"; |
|
397 } |
|
398 } |
|
399 else |
|
400 { |
|
401 //Si on est en plein écran. |
|
402 if(this.fullscreen) |
|
403 { |
|
404 //On entre en mode recherche. |
|
405 this.currentMode = "SEARCH"; |
|
406 } |
|
407 //Sinon. |
|
408 else |
|
409 { |
|
410 //On entre en mode filtrage. |
|
411 this.currentMode = "FILTER"; |
|
412 } |
|
413 |
|
414 this.startSearch(); |
|
415 } |
|
416 } |
|
417 //Si c'est a ou A. |
|
418 else if(event.which == 65 || event.which == 97) |
|
419 { |
|
420 if(!this.helpDisplayed) |
|
421 { |
|
422 this.notifyHelp(); |
|
423 } |
|
424 else |
|
425 { |
|
426 this.removeHelp(); |
|
427 } |
|
428 } |
|
429 //Si c'est v ou V. |
|
430 else if(event.which == 86 || event.which == 118) |
|
431 { |
|
432 this.notifySearchMarkers('run;jump;fall'); |
|
433 } |
|
434 //Si c'est b ou B. |
|
435 else if(event.which == 66 || event.which == 98) |
|
436 { |
|
437 this.removeSearchMarkers(); |
|
438 } |
|
439 //Si c'est k ou K. |
|
440 else if(event.which == 75 || event.which == 107) |
|
441 { |
|
442 this.searchFilter('circle'); |
|
443 } |
|
444 //Si c'est l ou L. |
|
445 else if(event.which == 76 || event.which == 108) |
|
446 { |
|
447 this.removeFilter(); |
|
448 } |
|
449 //Si on a appuié sur la touche 'q' ou 'Q'; |
|
450 else if(event.which == 113 || event.which == 81) |
|
451 { |
|
452 this.unzoom(); |
|
453 } |
|
454 else if(event.which == 111 || event.which == 79) |
|
455 { |
|
456 if(this.snapshotsToShow > this.imagesToShow) |
|
457 { |
|
458 this.snapshotsToShow = this.imagesToShow; |
|
459 } |
|
460 else |
|
461 { |
|
462 this.snapshotsToShow += 5; |
|
463 } |
|
464 |
|
465 this.showNImages(this.snapshotsToShow); |
|
466 } |
194 } |
467 } |
195 |
468 |
196 /* |
469 /* |
197 * Zoom sur la position d'une image, 1ère partie. Durant le laps de temps de time ms, l'utilisateur a le choix de zoomer sur une autre image. |
470 * Zoom sur la position d'une image, 1ère partie. Durant le laps de temps de time ms, l'utilisateur a le choix de zoomer sur une autre image. |
198 * Après ce laps de temps, l'image zoom complétement et il n'est plus possible de sélectionner une autre image par pointage. |
471 * Après ce laps de temps, l'image zoom complétement et il n'est plus possible de sélectionner une autre image par pointage. |
344 { |
617 { |
345 width: this.snapshotWidth, |
618 width: this.snapshotWidth, |
346 height: this.snapshotHeight, |
619 height: this.snapshotHeight, |
347 top: this.previousZoomedSN.position().top, |
620 top: this.previousZoomedSN.position().top, |
348 left: this.previousZoomedSN.position().left |
621 left: this.previousZoomedSN.position().left |
349 }, this.preUnzoomTime); |
622 }, this.config['preUnzoomTime']); |
350 $('#prezoomContainer-' + id).animate( |
623 $('#prezoomContainer-' + id).animate( |
351 { |
624 { |
352 width: this.snapshotWidth + margin, |
625 width: this.snapshotWidth + margin, |
353 height: this.snapshotHeight + margin, |
626 height: this.snapshotHeight + margin, |
354 top: this.previousZoomedSN.position().top, |
627 top: this.previousZoomedSN.position().top, |
355 left: this.previousZoomedSN.position().left |
628 left: this.previousZoomedSN.position().left |
356 }, this.preUnzoomTime, function(){ $(this).remove(); this.zoomed = false; }); |
629 }, this.config['preUnzoomTime'], function(){ $(this).remove(); this.zoomed = false; }); |
357 } |
630 } |
358 |
631 |
359 |
632 |
360 /* |
633 /* |
361 * Zoom d'un snapshot en plein écran. |
634 * Zoom d'un snapshot en plein écran. |
362 */ |
635 */ |
363 mosaic.prototype.zoom = function() |
636 mosaic.prototype.zoom = function() |
364 { |
637 { |
365 var mos = this; |
638 var _this = this; |
366 |
639 |
367 //Si la mosaïque est en pleine écran, pas la peine de zoomer. |
640 //Si la mosaïque est en pleine écran, pas la peine de zoomer. |
368 if(this.fullscreen) |
641 if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH") |
369 { |
642 { |
370 return; |
643 return; |
371 } |
644 } |
372 |
645 |
373 this.removePointMosaicPrezoom(); |
646 this.removePointMosaicPrezoom(); |
374 |
647 |
375 //On prend les attributs nécessaires au calculs. |
648 //On prend les attributs nécessaires au calculs. |
376 var margin = this.marginWidth, len = this.length, imgs = this.imagesToShow; |
649 var margin = this.marginWidth, len = this.config['length'], imgs = this.config['imagesToShow'], zoomedMargin = this.config['zoomedMargin']; |
|
650 var zoomPercentage = this.config['zoomPercentage']; |
377 var initMPWidth = this.previousZoomedSN.width() * len + margin*len, initMPHeight = this.previousZoomedSN.height() * (imgs / len) + margin*(imgs / len); |
651 var initMPWidth = this.previousZoomedSN.width() * len + margin*len, initMPHeight = this.previousZoomedSN.height() * (imgs / len) + margin*(imgs / len); |
378 var newMPWidth = initMPWidth * len + this.zoomedMargin * (len), newMPHeight = initMPHeight * (imgs / len) + this.zoomedMargin * ((imgs / len)); |
652 var newMPWidth = initMPWidth * len + zoomedMargin * (len), newMPHeight = initMPHeight * (imgs / len) + zoomedMargin * ((imgs / len)); |
379 var newPreMPWidth = initMPWidth * len * this.zoomPercentage + this.zoomedMargin * (len), newPreMPHeight = initMPHeight * (imgs / len) * this.zoomPercentage + this.zoomedMargin * ((imgs / len)); |
653 var newPreMPWidth = initMPWidth * len * zoomPercentage + zoomedMargin * (len), newPreMPHeight = initMPHeight * (imgs / len) * zoomPercentage + zoomedMargin * ((imgs / len)); |
380 |
654 |
381 //Dimensions et coordonnées initiales du div sur lequel on zoom. |
655 //Dimensions et coordonnées initiales du div sur lequel on zoom. |
382 var initialDivWidth = this.previousZoomedSN.width(), initialDivHeight = this.previousZoomedSN.height(); |
656 var initialDivWidth = this.previousZoomedSN.width(), initialDivHeight = this.previousZoomedSN.height(); |
383 var initialDivTop = this.previousZoomedSN.position().top, initialDivLeft = this.previousZoomedSN.position().left; |
657 var initialDivTop = this.previousZoomedSN.position().top, initialDivLeft = this.previousZoomedSN.position().left; |
384 //Dimensions et coordonnées finales du div. |
658 //Dimensions et coordonnées finales du div. |
385 var finalDivWidth = initialDivWidth * (this.zoomPercentage+1), finalDivHeight = initialDivHeight * (this.zoomPercentage+1); |
659 var finalDivWidth = initialDivWidth * (zoomPercentage+1), finalDivHeight = initialDivHeight * (zoomPercentage+1); |
386 var newZoomTop = -this.previousZoomedSN.position().top*(newPreMPHeight/initMPHeight) - this.zoomedMargin/2 + (initMPHeight - initMPHeight * this.zoomPercentage)/2, newZoomLeft = -this.previousZoomedSN.position().left*(newPreMPWidth/initMPWidth) - this.zoomedMargin/2 + (initMPWidth - initMPWidth * this.zoomPercentage)/2; |
660 var newZoomTop = -this.previousZoomedSN.position().top*(newPreMPHeight/initMPHeight) - zoomedMargin/2 + (initMPHeight - initMPHeight * zoomPercentage)/2, newZoomLeft = -this.previousZoomedSN.position().left*(newPreMPWidth/initMPWidth) - zoomedMargin/2 + (initMPWidth - initMPWidth * zoomPercentage)/2; |
387 var newSnWidth = initMPWidth * this.zoomPercentage, newSnHeight = initMPHeight * this.zoomPercentage; |
661 var newSnWidth = initMPWidth * zoomPercentage, newSnHeight = initMPHeight * zoomPercentage; |
388 |
662 |
389 this.preUnzoom(this); |
663 this.preUnzoom(this); |
390 /*SINGULARITE*/ |
664 /*SINGULARITE*/ |
391 this.fullscreen = true; |
665 this.fullscreen = true; |
392 |
666 |
395 var src = zoomedImg.attr('src'); |
669 var src = zoomedImg.attr('src'); |
396 zoomedImg.attr('src', src.replace('-little/', '/')); |
670 zoomedImg.attr('src', src.replace('-little/', '/')); |
397 |
671 |
398 //On récupère son ID. |
672 //On récupère son ID. |
399 var tab, zoomedImgId; |
673 var tab, zoomedImgId; |
400 tab = mos.previousId.split('-'); |
674 tab = _this.previousId.split('-'); |
401 zoomedImgId = tab[1]; |
675 zoomedImgId = tab[1]; |
402 |
676 |
403 //Les snapshots baissent alors en opacité, donnant l'impression qu'ils sont grisés. |
677 //On donne les dimensions des snapshots. |
404 $('.snapshotDivs').animate( |
678 $('.snapshotDivs').animate( |
405 { |
679 { |
406 width: newSnWidth, |
680 width: newSnWidth, |
407 height: newSnHeight, |
681 height: newSnHeight, |
408 margin: this.zoomedMargin/2 + 'px', |
682 margin: zoomedMargin/2 + 'px', |
409 opacity: '0.4' |
683 }, this.config['zoomTime']); |
410 }, this.zoomTime); |
684 |
411 //Le snapshot du milieu revient à une opacité optimale, ce qui attire l'attention de l'utilisateur. |
685 if(this.currentMode != 'NO-USER') |
412 $(this.previousZoomedSN).animate( |
686 { |
413 { |
687 //Les snapshots baissent alors en opacité, donnant l'impression qu'ils sont grisés. |
414 opacity: '1' |
688 $('.snapshotDivs').animate( |
415 }, this.zoomTime); |
689 { |
|
690 opacity: '0.4' |
|
691 }, this.config['zoomTime']); |
|
692 //Le snapshot du milieu revient à une opacité optimale, ce qui attire l'attention de l'utilisateur. |
|
693 $(this.previousZoomedSN).animate( |
|
694 { |
|
695 opacity: '1' |
|
696 }, this.config['zoomTime']); |
|
697 } |
|
698 |
416 //On zoome sur la mosaïque. |
699 //On zoome sur la mosaïque. |
417 $('#mainPanel').animate( |
700 $('#mainPanel').animate( |
418 { |
701 { |
419 width: newPreMPWidth, |
702 width: newPreMPWidth, |
420 height: newPreMPHeight, |
703 height: newPreMPHeight, |
421 top: newZoomTop, |
704 top: newZoomTop, |
422 left: newZoomLeft |
705 left: newZoomLeft |
423 }, this.zoomTime, function() |
706 }, this.config['zoomTime'], function() |
424 { |
707 { |
425 //On charge les interactions avec les voisins. |
708 //On charge les interactions avec les voisins. |
426 mos.centerId = zoomedImgId; |
709 _this.centerId = zoomedImgId; |
427 mos.listenToNeighbours(); |
710 |
428 mos.currentMode = 'VIDEO'; |
711 if(_this.currentMode != "NO-USER") |
429 |
712 { |
430 console.log('h : ' + -newZoomLeft + " " + zoomedImg.position().left); |
713 _this.currentMode = 'VIDEO'; |
431 |
714 _this.listenToNeighbours(); |
432 mos.snTop = (zoomedImg.position().top + newZoomTop + mos.MPTop_margin), mos.snLeft = (zoomedImg.position().left + newZoomLeft); |
715 } |
433 mos.snWidth = newSnWidth + 1, mos.snHeight = newSnHeight + 1; |
716 |
434 |
717 _this.snTop = (zoomedImg.position().top + newZoomTop + _this.MPTop_margin), _this.snLeft = (zoomedImg.position().left + newZoomLeft); |
435 mos.loadPlayer(mos.snTop, mos.snLeft, mos.snWidth, mos.snHeight, newZoomTop, newZoomLeft); |
718 _this.snWidth = newSnWidth + 1, _this.snHeight = newSnHeight + 1; |
436 |
719 |
437 /*mos.unload(); |
720 _this.notifyTopVideo = newZoomTop; |
438 mos.localMos.loadLocalMosaic(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, mos.imgs, tab[1]);*/ |
721 _this.notifyLeftVideo = newZoomLeft; |
|
722 |
|
723 _this.loadPlayer(_this.snTop, _this.snLeft, _this.snWidth, _this.snHeight, newZoomTop, newZoomLeft); |
439 }); |
724 }); |
440 } |
725 } |
441 |
726 |
442 /* |
727 /* |
443 * Chargement du player basé sur le metadataplayer. |
728 * Chargement du player basé sur le metadataplayer. |
444 */ |
729 */ |
445 mosaic.prototype.loadPlayer = function(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, zoomTop, zoomLeft) |
730 mosaic.prototype.loadPlayer = function(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, zoomTop, zoomLeft) |
446 { |
731 { |
|
732 var _this = this; |
|
733 |
447 //On configure les options de lancement. |
734 //On configure les options de lancement. |
448 IriSP.libFiles.defaultDir = "../lib/"; |
735 IriSP.libFiles.defaultDir = "../lib/"; |
449 IriSP.widgetsDir = "./player/metadataplayer/" |
736 IriSP.widgetsDir = "./player/metadataplayer/" |
450 |
737 |
451 var videoToPlay = this.videos[this.centerId]; |
738 var videoToPlay = this.videos[this.centerId]; |
452 var currentMetadata = this.urls[this.centerId]; |
739 var currentMetadata = this.urls[this.centerId]; |
453 console.log('VIDEO[' + this.centerId + '] : ' + videoToPlay); |
|
454 console.log('MD[' + this.centerId + '] : ' + currentMetadata); |
|
455 |
740 |
456 var _metadata = { |
741 var _metadata = { |
457 url: currentMetadata, |
742 url: currentMetadata, |
458 format: 'ldt' |
743 format: 'ldt' |
459 }; |
744 }; |
460 console.log(zoomTop + " m" + this.marginWidth); |
745 |
461 var _config = { |
746 var _config = { |
462 gui: { |
747 gui: { |
463 zoomTop: zoomTop - this.marginWidth*2, |
748 zoomTop: zoomTop - this.marginWidth*2, |
464 zoomLeft: zoomLeft, |
749 zoomLeft: zoomLeft, |
465 width: newSnWidth, |
750 width: newSnWidth, |
517 this.snHeight = 0; |
820 this.snHeight = 0; |
518 |
821 |
519 //On charge les attributs nécessaires aux calculs. |
822 //On charge les attributs nécessaires aux calculs. |
520 var sWidth = this.snapshotWidth, sHeight = this.snapshotHeight; |
823 var sWidth = this.snapshotWidth, sHeight = this.snapshotHeight; |
521 var mpWidth = this.width, mpHeight = this.height; |
824 var mpWidth = this.width, mpHeight = this.height; |
522 var mos = this; |
825 var _this = this; |
523 |
826 |
524 //On passe le snapshot sur lequel on a zoomé en SD. |
827 //On passe le snapshot sur lequel on a zoomé en SD. |
525 var zoomedImg = $('img', this.previousZoomedSN); |
828 var zoomedImg = $('img', this.previousZoomedSN); |
526 var src = zoomedImg.attr('src'); |
829 var src = zoomedImg.attr('src'); |
527 zoomedImg.attr('src', src.replace('snapshots/', 'snapshots-little/')); |
830 zoomedImg.attr('src', src.replace('snapshots/', 'snapshots-little/')); |
528 |
831 |
529 mos.player.widgets[0].freePlayer(); |
832 _this.player.widgets[0].freePlayer(); |
530 $('.LdtPlayer').remove(); |
833 $('.LdtPlayer').remove(); |
531 $('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>'); |
834 $('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>'); |
|
835 _this.reaffectKeyPress(); |
532 |
836 |
533 //On rend leur opacité aux snapshots. Qui ne sont alors plus grisés. |
837 //On rend leur opacité aux snapshots. Qui ne sont alors plus grisés. |
534 $('.snapshotDivs').animate( |
838 $('.snapshotDivs').animate( |
535 { |
839 { |
536 width: sWidth, |
840 width: sWidth, |
537 height: sHeight, |
841 height: sHeight, |
538 margin: this.marginWidth/2 + 'px', |
842 margin: this.marginWidth/2 + 'px' |
539 opacity: '1' |
843 }, this.config['unzoomTime']); |
540 }, this.unzoomTime); |
844 |
|
845 if(this.currentMode != 'NO-USER') |
|
846 { |
|
847 if(this.currentMode.indexOf("INCOMING") == -1) |
|
848 { |
|
849 $('.snapshotDivs').animate( |
|
850 { |
|
851 opacity: '1' |
|
852 }, this.config['unzoomTime']); |
|
853 } |
|
854 } |
|
855 else |
|
856 { |
|
857 console.log('init'); |
|
858 this.previousZoomedSN.fadeTo(this.config['unzoomTime'], 0, function() |
|
859 { |
|
860 _this.init(); |
|
861 }); |
|
862 } |
|
863 |
541 //On dézoom sur la mosaïque. |
864 //On dézoom sur la mosaïque. |
542 $('#mainPanel').animate( |
865 $('#mainPanel').animate( |
543 { |
866 { |
544 width: mpWidth, |
867 width: mpWidth, |
545 height: mpHeight, |
868 height: mpHeight, |
546 top: '0px', |
869 top: '0px', |
547 left: '0px' |
870 left: '0px' |
548 }, this.unzoomTime, function() |
871 }, this.config['unzoomTime'], function() |
549 { |
872 { |
550 //On n'est plus en plein écran, et on ne peut plus se déplacer vers le prochain voisin. |
873 //On n'est plus en plein écran, et on ne peut plus se déplacer vers le prochain voisin. |
551 mos.fullscreen = false; |
874 _this.fullscreen = false; |
552 mos.canMoveToNeighbour = false; |
875 _this.canMoveToNeighbour = false; |
553 //On revient en mode MOSAIC. |
876 |
554 mos.currentMode = 'MOSAIC'; |
877 if(_this.currentMode != 'NO-USER') |
555 //On ne permet plus le déplacement vers les voisins. |
878 { |
556 $('.snapshotDivs').unbind('mouseenter', mos.selectNeighbour); |
879 //On revient en mode MOSAIC. |
557 //On remet les notifications initiales. |
880 _this.currentMode = 'MOSAIC'; |
558 mos.notifySelectionSearchMosaicFull(); |
881 //On ne permet plus le déplacement vers les voisins. |
|
882 $('.snapshotDivs').unbind('mouseover', function() |
|
883 { |
|
884 _this.selectNeighbour(); |
|
885 }); |
|
886 //On remet les notifications initiales. |
|
887 _this.notifySelectionSearchMosaicFull(); |
|
888 } |
559 }); |
889 }); |
560 } |
890 } |
561 |
891 |
562 /* |
892 /* |
563 * Affecte les listeners mouseenter aux voisins lors d'une vue en plein écran. |
893 * Affecte les listeners mouseenter aux voisins lors d'une vue en plein écran. |
564 */ |
894 */ |
565 mosaic.prototype.listenToNeighbours = function() |
895 mosaic.prototype.listenToNeighbours = function() |
566 { |
896 { |
567 ////TEST |
897 ////TEST |
568 //$('.test').empty(); |
898 //$('.test').empty(); |
569 this.canMoveToNeighbour = false; |
899 var _this = this; |
570 var currentLine = Math.floor(this.centerId / this.length), currentColumn = this.centerId % this.length; |
900 |
|
901 this.canMoveToNeighbour = false; |
|
902 var currentLine = Math.floor(this.centerId / this.config['length']), currentColumn = this.centerId % this.config['length']; |
571 var zoomedImg = $('img', this.previousZoomedSN); |
903 var zoomedImg = $('img', this.previousZoomedSN); |
572 var mos = this; |
|
573 |
904 |
574 //On cherche l'ID des voisins. |
905 //On cherche l'ID des voisins. |
575 //Si le voisin de gauche est sur la même ligne, on n'est pas sur la bordure de gauche. |
906 //Si le voisin de gauche est sur la même ligne, on n'est pas sur la bordure de gauche. |
576 this.neighboursIds[0] = (currentColumn > 0) ? (this.centerId - 1) : -1; |
907 this.neighboursIds[0] = (currentColumn > 0) ? (this.centerId - 1) : -1; |
577 //Si le voisin de droite est sur la même ligne, on n'est pas sur la bordure de droite. |
908 //Si le voisin de droite est sur la même ligne, on n'est pas sur la bordure de droite. |
578 this.neighboursIds[1] = (currentColumn < this.length) ? (+this.centerId + 1) : -1; |
909 this.neighboursIds[1] = (currentColumn < this.config['length']) ? (+this.centerId + 1) : -1; |
579 //Si le voisin du haut est sur la même colonne, on n'est pas sur la bordure du haut. |
910 //Si le voisin du haut est sur la même colonne, on n'est pas sur la bordure du haut. |
580 this.neighboursIds[2] = (currentLine > 0) ? (this.centerId - this.length) : -1; |
911 this.neighboursIds[2] = (currentLine > 0) ? (this.centerId - this.config['length']) : -1; |
581 //Si le voisin du bas est sur la même colonne, on n'est pas sur la bordure du bas. |
912 //Si le voisin du bas est sur la même colonne, on n'est pas sur la bordure du bas. |
582 this.neighboursIds[3] = (currentLine < (this.imagesToShow / this.length)) ? (+this.centerId + this.length) : -1; |
913 this.neighboursIds[3] = (currentLine < (this.config['imagesToShow'] / this.config['length'])) ? (+this.centerId + this.config['length']) : -1; |
583 |
914 |
584 //ID du cadre voisin. |
915 //ID du cadre voisin. |
585 var preId; |
916 var preId; |
586 |
917 |
587 for(var i = 0 ; i < this.neighboursIds.length ; i++) |
918 for(var i = 0 ; i < this.neighboursIds.length ; i++) |
589 if(this.neighboursIds[i] != -1) |
920 if(this.neighboursIds[i] != -1) |
590 { |
921 { |
591 preId = '#neighbourFrameBorder-' + this.neighboursIds[i]; |
922 preId = '#neighbourFrameBorder-' + this.neighboursIds[i]; |
592 //On permet le déplacement vers les voisins. |
923 //On permet le déplacement vers les voisins. |
593 // $('#snapshotDiv-' + this.neighboursIds[i] + ', ' + preId + '-left,' + preId + '-right,' + preId + '-up,' + preId + '-down').mouseenter(mos.selectNeighbour); |
924 // $('#snapshotDiv-' + this.neighboursIds[i] + ', ' + preId + '-left,' + preId + '-right,' + preId + '-up,' + preId + '-down').mouseenter(mos.selectNeighbour); |
594 $('#snapshotDiv-' + this.neighboursIds[i]).mouseenter(mos.selectNeighbour); |
925 |
|
926 $('#snapshotDiv-' + this.neighboursIds[i]).mouseover(function() |
|
927 { |
|
928 _this.selectNeighbour($(this)); |
|
929 }); |
595 } |
930 } |
596 } |
931 } |
597 } |
932 } |
598 |
933 |
599 /* |
934 /* |
600 * Change la coloration d'une bordure où on se positionne lors d'une vue en plein écran. |
935 * Change la coloration d'une bordure où on se positionne lors d'une vue en plein écran. |
601 */ |
936 */ |
602 mosaic.prototype.selectNeighbour = function() |
937 mosaic.prototype.selectNeighbour = function(neighbour) |
603 { |
938 { |
604 ////TEST |
939 ////TEST |
605 //$('.test').append(mos.currentMode + " " + $(this).attr('id') + " " + 'snapshotDiv-' + mos.centerId + ','); |
940 //$('.test').append(mos.currentMode + " " + $(this).attr('id') + " " + 'snapshotDiv-' + mos.centerId + ','); |
606 |
941 var _this = this; |
|
942 |
607 //Si on est en mode VIDEO (plein écran) ET si le snapshot pointé est un voisin. |
943 //Si on est en mode VIDEO (plein écran) ET si le snapshot pointé est un voisin. |
608 if((mos.currentMode == 'VIDEO') && ($(this).attr('id') != 'snapshotDiv-' + mos.centerId)) |
944 |
|
945 if((this.currentMode == 'VIDEO') && (neighbour.attr('id') != 'snapshotDiv-' + this.centerId)) |
609 { |
946 { |
610 //On crée le cadre qui va être superposé au voisin. |
947 //On crée le cadre qui va être superposé au voisin. |
611 //On le colle au voisin. |
948 //On le colle au voisin. |
612 var tab = $(this).attr('id').split('-'); |
949 var tab = neighbour.attr('id').split('-'); |
613 var snapshotId = tab[1]; |
950 var snapshotId = tab[1]; |
614 var neighbourFrame = ''; |
951 var neighbourFrame = ''; |
615 var marginValue = parseFloat($(this).css('margin')); |
952 var marginValue = parseFloat(neighbour.css('margin')); |
616 |
953 |
617 neighbourFrame += '<div class="neighbourFrame" id="neighbourFrame-' + snapshotId + '"><div class="neighbourImgBg" id="neighbourImgBg-' + snapshotId + '"><div class="neighbourImg" id="neighbourImg-' + snapshotId + '"></div></div></div>'; |
954 neighbourFrame += '<div class="neighbourFrame" id="neighbourFrame-' + snapshotId + '"><div class="neighbourImgBg" id="neighbourImgBg-' + snapshotId + '"><div class="neighbourImg" id="neighbourImg-' + snapshotId + '"></div></div></div>'; |
618 |
955 |
619 $('#mainPanel').append(neighbourFrame); |
956 $('#mainPanel').append(neighbourFrame); |
620 |
957 |
621 //On positionne le div de background juste au niveau du voisin. |
958 //On positionne le div de background juste au niveau du voisin. |
622 $('#neighbourFrame-' + snapshotId).css( |
959 $('#neighbourFrame-' + snapshotId).css( |
623 { |
960 { |
624 'top': (+$(this).position().top + marginValue), |
961 'top': (+neighbour.position().top + marginValue), |
625 'left': (+$(this).position().left + marginValue), |
962 'left': (+neighbour.position().left + marginValue), |
626 'width': $(this).width(), |
963 'width': neighbour.width(), |
627 'height': $(this).height() |
964 'height': neighbour.height() |
628 }); |
965 }); |
629 //On positionne le div de background noir juste au niveau de l'image du voisin. |
966 //On positionne le div de background noir juste au niveau de l'image du voisin. |
630 $('#neighbourImgBg-' + snapshotId).css( |
967 $('#neighbourImgBg-' + snapshotId).css( |
631 { |
968 { |
632 'top': marginValue, |
969 'top': marginValue, |
633 'left': marginValue, |
970 'left': marginValue, |
634 'width': $(this).width() - marginValue*2, |
971 'width': neighbour.width() - marginValue*2, |
635 'height': $(this).height() - marginValue*2, |
972 'height': neighbour.height() - marginValue*2, |
636 }); |
973 }); |
637 //On met par dessus le div de l'image clonée du voisin. |
974 //On met par dessus le div de l'image clonée du voisin. |
638 $('#neighbourImg-' + snapshotId).css( |
975 $('#neighbourImg-' + snapshotId).css( |
639 { |
976 { |
640 'top': 0, |
977 'top': 0, |
641 'left': 0, |
978 'left': 0, |
642 'width': $(this).width() - marginValue*2, |
979 'width': neighbour.width() - marginValue*2, |
643 'height': $(this).height() - marginValue*2, |
980 'height': neighbour.height() - marginValue*2, |
644 'background-image': 'url("' + $('img', $(this)).attr('src') + '")', |
981 'background-image': 'url("' + $('img', neighbour).attr('src') + '")', |
645 'background-size': $(this).width() + 'px ' + $(this).height() + 'px', |
982 'background-size': neighbour.width() + 'px ' + neighbour.height() + 'px', |
646 'background-position': -marginValue + 'px ' + -marginValue + 'px', |
983 'background-position': -marginValue + 'px ' + -marginValue + 'px', |
647 'opacity': '0.4' |
984 'opacity': '0.4' |
648 }); |
985 }); |
649 |
986 |
650 var fId = '#neighbourFrame-' + snapshotId; |
987 var fId = '#neighbourFrame-' + snapshotId; |
651 |
988 |
652 $(fId).animate( |
989 $(fId).animate( |
653 { |
990 { |
654 //On le fait apparaître. |
991 //On le fait apparaître. |
655 opacity: '1' |
992 opacity: '1' |
656 }, timeNeighbourGlowing, function() |
993 }, _this.config['timeNeighbourGlowing'], function() |
657 { |
994 { |
658 //On peut désormais se déplacer vers ce voisin. |
995 //On peut désormais se déplacer vers ce voisin. |
659 mos.canMoveToNeighbour = true; |
996 _this.canMoveToNeighbour = true; |
660 }); |
997 }); |
661 //Lorsqu'on quitte un des snapshots (bien entendu le voisin en question), on retire le cadre. |
998 //Lorsqu'on quitte un des snapshots (bien entendu le voisin en question), on retire le cadre. |
662 $(fId).mouseleave(mos.deselectNeighbour) |
|
663 //Si on clique sur le voisin ou son cadre, on passe au voisin suivant. |
999 //Si on clique sur le voisin ou son cadre, on passe au voisin suivant. |
664 $(fId).click(mos.moveToNeighbour); |
1000 $(fId).mouseout(function() |
|
1001 { |
|
1002 _this.deselectNeighbour($(this)) |
|
1003 }).click(function() |
|
1004 { |
|
1005 _this.moveToNeighbour($(this)) |
|
1006 }); |
665 } |
1007 } |
666 } |
1008 } |
667 |
1009 |
668 /* |
1010 /* |
669 * Change la coloration d'une bordure quittée lors d'une vue en plein écran. |
1011 * Change la coloration d'une bordure quittée lors d'une vue en plein écran. |
670 */ |
1012 */ |
671 mosaic.prototype.deselectNeighbour = function() |
1013 mosaic.prototype.deselectNeighbour = function(neighbour) |
672 { |
1014 { |
673 ////TEST |
1015 ////TEST |
674 //$('.test').append('un,'); |
1016 //$('.test').append('un,'); |
675 |
1017 |
676 //On ne peut plus se déplacer vers les voisins. |
1018 //On ne peut plus se déplacer vers les voisins. |
677 mos.canMoveToNeighbour = false; |
1019 this.canMoveToNeighbour = false; |
678 |
1020 |
679 //On récupère le voisin. |
1021 //On récupère le voisin. |
680 var neighbourFrame = $(this); |
1022 var neighbourFrame = neighbour; |
681 |
1023 |
682 //Si on est en mode VIDEO. |
1024 //Si on est en mode VIDEO. |
683 if(mos.currentMode == 'VIDEO') |
1025 if(this.currentMode == 'VIDEO') |
684 { |
1026 { |
685 //On le fait disparaître progressivement. |
1027 //On le fait disparaître progressivement. |
686 neighbourFrame.animate( |
1028 neighbourFrame.animate( |
687 { |
1029 { |
688 opacity: '0' |
1030 opacity: '0' |
689 }, timeNeighbourUnglowing, function() |
1031 }, this.config['timeNeighbourUnglowing'], function() |
690 { |
1032 { |
691 //Une fois invisible, on le supprime. |
1033 //Une fois invisible, on le supprime. |
692 neighbourFrame.remove(); |
1034 neighbourFrame.remove(); |
693 }); |
1035 }); |
694 } |
1036 } |
695 } |
1037 } |
696 |
1038 |
697 /* |
1039 /* |
698 * Lors d'une vue en plein écran, on se déplace vers le voisin dont l'id a été spécifié dans la fonction appelante. |
1040 * Lors d'une vue en plein écran, on se déplace vers le voisin dont l'id a été spécifié dans la fonction appelante. |
699 */ |
1041 */ |
700 mosaic.prototype.moveToNeighbour = function() |
1042 mosaic.prototype.moveToNeighbour = function(neighbour) |
701 { |
1043 { |
|
1044 var _this = this; |
702 //Si on ne peut pas se déplacer vers les voisins, on quitte. |
1045 //Si on ne peut pas se déplacer vers les voisins, on quitte. |
703 if(!mos.canMoveToNeighbour) |
1046 if(!_this.canMoveToNeighbour) |
704 { |
1047 { |
705 return; |
1048 return; |
706 } |
1049 } |
707 |
1050 |
708 //On obtient l'ID de destination. |
1051 //On obtient l'ID de destination. |
709 var tab = $(this).attr('id').split('-'); |
1052 var tab = neighbour.attr('id').split('-'); |
710 var destinationId = tab[1]; |
1053 var destinationId = tab[1]; |
711 |
1054 |
712 //On charge les attributs nécessaires aux calculs. |
1055 //On charge les attributs nécessaires aux calculs. |
|
1056 var length = _this.config['length']; |
713 var MPCurrentTop = $('#mainPanel').position().top, MPCurrentLeft = $('#mainPanel').position().left; |
1057 var MPCurrentTop = $('#mainPanel').position().top, MPCurrentLeft = $('#mainPanel').position().left; |
714 var divideCoeffTop = Math.floor(destinationId / mos.length) == 0 ? 1 : Math.floor(destinationId / mos.length); |
1058 var divideCoeffTop = Math.floor(destinationId / length) == 0 ? 1 : Math.floor(destinationId / length); |
715 var divideCoeffLeft = destinationId % mos.length == 0 ? 1 : destinationId % mos.length; |
1059 var divideCoeffLeft = destinationId % length == 0 ? 1 : destinationId % length; |
716 var neighbourFrameTop = $('#snapshotDiv-' + destinationId).position().top, neighbourFrameLeft = $('#snapshotDiv-' + destinationId).position().left; |
1060 var neighbourFrameTop = $('#snapshotDiv-' + destinationId).position().top, neighbourFrameLeft = $('#snapshotDiv-' + destinationId).position().left; |
717 |
1061 |
718 //On définit pour le déplacement vertical s'il est nécessaire de se déplacer en haut ou en bas. |
1062 //On définit pour le déplacement vertical s'il est nécessaire de se déplacer en haut ou en bas. |
719 if(mos.previousZoomedSN.position().top > neighbourFrameTop) |
1063 if(_this.previousZoomedSN.position().top > neighbourFrameTop) |
720 MPCurrentTop += Math.abs(neighbourFrameTop - mos.previousZoomedSN.position().top); |
1064 MPCurrentTop += Math.abs(neighbourFrameTop - _this.previousZoomedSN.position().top); |
721 else if(mos.previousZoomedSN.position().top < neighbourFrameTop) |
1065 else if(_this.previousZoomedSN.position().top < neighbourFrameTop) |
722 MPCurrentTop -= Math.abs(neighbourFrameTop - mos.previousZoomedSN.position().top); |
1066 MPCurrentTop -= Math.abs(neighbourFrameTop - _this.previousZoomedSN.position().top); |
723 //On définit pour le déplacement horizontal s'il est nécessaire de se déplacer à gauche ou à droite. |
1067 //On définit pour le déplacement horizontal s'il est nécessaire de se déplacer à gauche ou à droite. |
724 if(mos.previousZoomedSN.position().left > neighbourFrameLeft) |
1068 if(_this.previousZoomedSN.position().left > neighbourFrameLeft) |
725 MPCurrentLeft += Math.abs(neighbourFrameLeft - mos.previousZoomedSN.position().left); |
1069 MPCurrentLeft += Math.abs(neighbourFrameLeft - _this.previousZoomedSN.position().left); |
726 else if(mos.previousZoomedSN.position().left < neighbourFrameLeft) |
1070 else if(_this.previousZoomedSN.position().left < neighbourFrameLeft) |
727 MPCurrentLeft -= Math.abs(neighbourFrameLeft - mos.previousZoomedSN.position().left); |
1071 MPCurrentLeft -= Math.abs(neighbourFrameLeft - _this.previousZoomedSN.position().left); |
728 |
1072 |
729 //On passe le snapshot de destination en HD. |
1073 //On passe le snapshot de destination en HD. |
730 var destinationImg = $('#snapshot-' + destinationId); |
1074 var destinationImg = $('#snapshot-' + destinationId); |
731 var destinationImgSrc = destinationImg.attr('src'); |
1075 var destinationImgSrc = destinationImg.attr('src'); |
732 destinationImg.attr('src', destinationImgSrc.replace('snapshots-little/', 'snapshots/')); |
1076 destinationImg.attr('src', destinationImgSrc.replace('snapshots-little/', 'snapshots/')); |
733 |
1077 |
734 //On passe l'ancien snapshot en SD. |
1078 //On passe l'ancien snapshot en SD. |
735 var currentImgSrc = $('img', mos.previousZoomedSN).attr('src'); |
1079 var currentImgSrc = $('img', _this.previousZoomedSN).attr('src'); |
736 $('img', mos.previousZoomedSN).attr('src', currentImgSrc.replace('snapshots/', 'snapshots-little/')); |
1080 $('img', _this.previousZoomedSN).attr('src', currentImgSrc.replace('snapshots/', 'snapshots-little/')); |
737 |
1081 |
738 //On obtient l'ID du div de coloration du snapshot vers lequel on se déplace afin de le supprimer. |
1082 //On obtient l'ID du div de coloration du snapshot vers lequel on se déplace afin de le supprimer. |
739 var neighbourFrame = $(this); |
1083 var neighbourFrame = neighbour; |
740 var tab = neighbourFrame.attr('id').split('-'); |
1084 var tab = neighbourFrame.attr('id').split('-'); |
741 mos.centerId = tab[1]; |
1085 _this.centerId = tab[1]; |
742 $(this).css('opacity', '0'); |
1086 $(this).css('opacity', '0'); |
743 neighbourFrame.remove(); |
1087 neighbourFrame.remove(); |
744 |
1088 |
745 mos.player.widgets[0].freePlayer(); |
1089 _this.player.widgets[0].freePlayer(); |
746 $('.LdtPlayer').remove(); |
1090 $('.LdtPlayer').remove(); |
747 $('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>'); |
1091 $('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>'); |
|
1092 _this.reaffectKeyPress(); |
748 |
1093 |
749 //On grise le snapshot qu'on vient de quitter. |
1094 //On grise le snapshot qu'on vient de quitter. |
750 mos.previousZoomedSN.animate( |
1095 _this.previousZoomedSN.animate( |
751 { |
1096 { |
752 opacity: '0.4' |
1097 opacity: '0.4' |
753 }); |
1098 }); |
754 |
1099 |
755 //On se déplace. |
1100 //On se déplace. |
756 $('#mainPanel').animate( |
1101 $('#mainPanel').animate( |
757 { |
1102 { |
758 top: MPCurrentTop, |
1103 top: MPCurrentTop, |
759 left: MPCurrentLeft |
1104 left: MPCurrentLeft |
760 }, timeMovingToNeighbour, function() |
1105 }, _this.config['timeMovingToNeighbour'], function() |
761 { |
1106 { |
762 //On fait apparaître le snapshot vers lequel on s'est déplacé. |
1107 //On fait apparaître le snapshot vers lequel on s'est déplacé. |
763 $('#snapshotDiv-' + destinationId).animate( |
1108 $('#snapshotDiv-' + destinationId).animate( |
764 { |
1109 { |
765 opacity: '1' |
1110 opacity: '1' |
766 }, mos.zoomTime, function() |
1111 }, _this.config['zoomTime'], function() |
767 { |
1112 { |
768 //On recharge les voisins. |
1113 //On recharge les voisins. |
769 $('.snapshotDivs').unbind('mouseenter', mos.selectNeighbour); |
1114 $('.snapshotDivs').unbind('mouseenter', _this.selectNeighbour); |
770 mos.previousZoomedSN = $('#snapshotDiv-' + mos.centerId); |
1115 _this.previousZoomedSN = $('#snapshotDiv-' + _this.centerId); |
771 mos.listenToNeighbours(); |
1116 _this.listenToNeighbours(); |
772 |
1117 |
773 mos.loadPlayer((destinationImg.position().top + MPCurrentTop + mos.MPTop_margin), (destinationImg.position().left + MPCurrentLeft), destinationImg.width(), destinationImg.height(), MPCurrentTop, MPCurrentLeft); |
1118 _this.notifyTopVideo = MPCurrentTop; |
|
1119 _this.notifyLeftVideo = MPCurrentLeft; |
|
1120 |
|
1121 _this.loadPlayer((destinationImg.position().top + MPCurrentTop + _this.MPTop_margin), (destinationImg.position().left + MPCurrentLeft), destinationImg.width(), destinationImg.height(), MPCurrentTop, MPCurrentLeft); |
774 }); |
1122 }); |
775 }); |
1123 }); |
776 } |
1124 } |
777 |
1125 |
778 /* |
1126 /* |
1130 { |
1487 { |
1131 _this.helpDisplayed = false; |
1488 _this.helpDisplayed = false; |
1132 $('#notify_help').remove(); |
1489 $('#notify_help').remove(); |
1133 }); |
1490 }); |
1134 } |
1491 } |
|
1492 |
|
1493 /* |
|
1494 * Affiche les types de marqueurs correspondants à ce qu'on a commencé à tracer lors d'une recherche. |
|
1495 */ |
|
1496 mosaic.prototype.notifySearchMarkers = function(markersStr) |
|
1497 { |
|
1498 if($('.notifications_inSearch_container').length > 0) |
|
1499 { |
|
1500 return; |
|
1501 } |
|
1502 |
|
1503 console.log(markersStr); |
|
1504 |
|
1505 var markersList = markersStr.split(new RegExp(';')); |
|
1506 |
|
1507 var notification_search_markers = "<div class='notifications_inSearch_container'>"; |
|
1508 |
|
1509 //On spécifie les notifications en div. |
|
1510 for(var i = 0 ; i < markersList.length ; i++) |
|
1511 { |
|
1512 notification_search_markers += "<div class='notifications_inSearch' style='background-image: url(./pictos/big/normal/" + markersList[i] + ".png);'></div>"; |
|
1513 } |
|
1514 |
|
1515 notification_search_markers += "</div>"; |
|
1516 |
|
1517 //On les ajoute à la mosaïque. |
|
1518 $('#mainPanel').append(notification_search_markers); |
|
1519 |
|
1520 //On calcule leurs coordonnées et dimensions. |
|
1521 var notify_width = $('.notifications_inSearch_container').width(), notify_height = $('.notifications_inSearch_container').height(); |
|
1522 var notify_margin = parseInt($('.notifications_inSearch').css('margin')); |
|
1523 var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin; |
|
1524 var point_top = 0; |
|
1525 |
|
1526 if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH") |
|
1527 { |
|
1528 point_top = -this.notifyTopVideo, |
|
1529 point_left = -this.notifyLeftVideo + ($(window).width() - notify_width) / 2 |
|
1530 } |
|
1531 |
|
1532 //On les positionne. |
|
1533 $('.notifications_inSearch_container').css( |
|
1534 { |
|
1535 left: point_left, |
|
1536 top: point_top |
|
1537 }); |
|
1538 |
|
1539 //On les fait apparaître. |
|
1540 $('.notifications_inSearch').css( |
|
1541 { |
|
1542 opacity: "0.9" |
|
1543 }); |
|
1544 } |
|
1545 |
|
1546 /* |
|
1547 * Supprime la notification de maintient du pointage. |
|
1548 */ |
|
1549 mosaic.prototype.removeSearchMarkers = function() |
|
1550 { |
|
1551 $('.notifications_inSearch_container').remove(); |
|
1552 } |
|
1553 |
|
1554 /* |
|
1555 * Effectuer un filtrage de la mosaïque par rapport à un type de marqueurs. |
|
1556 */ |
|
1557 mosaic.prototype.searchFilter = function(type) |
|
1558 { |
|
1559 var _this = this; |
|
1560 |
|
1561 if(this.currentMode == "MOSAIC") |
|
1562 { |
|
1563 this.currentMode = "FILTER"; |
|
1564 |
|
1565 if(this.annotations.length > 0) |
|
1566 { |
|
1567 var gestureNumberByVideo = new Object(); |
|
1568 var maxAnnotationNumber = 0; |
|
1569 // for(var i = 0 ; i < this.config['imagesToShow'] ; i++) |
|
1570 for(var i = 0 ; i < this.annotations.length ; i++) |
|
1571 { |
|
1572 var current = this.annotations[i]; |
|
1573 if(current.annotationType.contents.title == type) |
|
1574 { |
|
1575 if(gestureNumberByVideo[current.source.url] == undefined || gestureNumberByVideo[current.source.url] == '') |
|
1576 { |
|
1577 gestureNumberByVideo[current.source.url] = 0; |
|
1578 } |
|
1579 |
|
1580 gestureNumberByVideo[current.source.url]++; |
|
1581 } |
|
1582 } |
|
1583 |
|
1584 for(var i = 0 ; i < this.urls.length ; i++) |
|
1585 { |
|
1586 if(gestureNumberByVideo[this.urls[i]] == undefined || gestureNumberByVideo[this.urls[i]] == '') |
|
1587 { |
|
1588 gestureNumberByVideo[this.urls[i]] = 0; |
|
1589 } |
|
1590 } |
|
1591 |
|
1592 //On récupère la vidéo qui score le nombre d'occurences de la gesture le plus haut. |
|
1593 for(i in gestureNumberByVideo) |
|
1594 { |
|
1595 // console.log(i + " " + gestureNumberByVideo[i]); |
|
1596 if(maxAnnotationNumber < gestureNumberByVideo[i]) |
|
1597 { |
|
1598 maxAnnotationNumber = gestureNumberByVideo[i]; |
|
1599 } |
|
1600 } |
|
1601 |
|
1602 var snMargin = parseInt($('.snapshotDivs').css('margin')); |
|
1603 |
|
1604 //On affiche l'opacité résultante pour chaque vidéo. |
|
1605 for(i in gestureNumberByVideo) |
|
1606 { |
|
1607 //Opacité conventionelle. |
|
1608 var opacity = gestureNumberByVideo[i] / maxAnnotationNumber; |
|
1609 // console.log('opacity b : ' + opacity + ' for ' + gestureNumberByVideo[i]); |
|
1610 //Ce qui est à zéro le restera (par conséquent le snapshot associé sera invisible). |
|
1611 if(opacity > 0) |
|
1612 { |
|
1613 //On réhausse l'opacité de 50%. |
|
1614 opacity = this.scaleIntervals(0., 1., 0.5, 1., opacity); |
|
1615 } |
|
1616 |
|
1617 var filterIndex = this.getIdxFromMetadata(i); |
|
1618 |
|
1619 if(filterIndex >= 0) |
|
1620 { |
|
1621 console.log('#snapshotDiv-' + filterIndex + " " + _this.config['timeFilterFade'] + " " + opacity); |
|
1622 $('#snapshotDiv-' + filterIndex).fadeTo(_this.config['timeFilterFade'], opacity); |
|
1623 |
|
1624 if(opacity == 0) |
|
1625 { |
|
1626 var filteredSnapshot = $('#snapshotDiv-' + filterIndex); |
|
1627 |
|
1628 if(filteredSnapshot.length > 0) |
|
1629 { |
|
1630 var hider = '<div id="filterHider-' + filterIndex + '" class="filterHiders"></div>'; |
|
1631 $('#mainPanel').append(hider); |
|
1632 |
|
1633 $('#filterHider-' + filterIndex).css( |
|
1634 { |
|
1635 width: +filteredSnapshot.width() + 4 * snMargin, |
|
1636 height: +filteredSnapshot.height() + 4 * snMargin, |
|
1637 top: filteredSnapshot.position().top - snMargin, |
|
1638 left: filteredSnapshot.position().left - snMargin |
|
1639 }); |
|
1640 } |
|
1641 } |
|
1642 } |
|
1643 } |
|
1644 } |
|
1645 } |
|
1646 } |
|
1647 |
|
1648 /* |
|
1649 * Passe une valeur de l'intervalle [A, B] à l'intervalle [C, D]. |
|
1650 */ |
|
1651 mosaic.prototype.scaleIntervals = function(A, B, C, D, val) |
|
1652 { |
|
1653 return (D - C + A) * val + (C - A); |
|
1654 } |
|
1655 |
|
1656 /* |
|
1657 * Retourne l'index d'un snapshot en fonction de ses metadonnées. |
|
1658 */ |
|
1659 mosaic.prototype.getIdxFromMetadata = function(metadata) |
|
1660 { |
|
1661 var _this = this; |
|
1662 |
|
1663 for(idx in this.urls) |
|
1664 { |
|
1665 if(this.urls[idx] == metadata) |
|
1666 { |
|
1667 for(id in this.ids) |
|
1668 { |
|
1669 if(this.ids[id] == idx) |
|
1670 { |
|
1671 return id; |
|
1672 } |
|
1673 } |
|
1674 } |
|
1675 } |
|
1676 |
|
1677 return -1; |
|
1678 } |
|
1679 |
|
1680 /* |
|
1681 * Enlève une recherche par filtre. |
|
1682 */ |
|
1683 mosaic.prototype.removeFilter = function() |
|
1684 { |
|
1685 if(this.currentMode == "FILTER") |
|
1686 { |
|
1687 this.currentMode = "MOSAIC"; |
|
1688 |
|
1689 var _this = this; |
|
1690 |
|
1691 $('.filterHiders').remove(); |
|
1692 $('.snapshotDivs').fadeTo(_this.config['timeFilterFade'], 1); |
|
1693 } |
|
1694 } |
|
1695 |
|
1696 /* |
|
1697 * Rebind keypress pour body. |
|
1698 */ |
|
1699 mosaic.prototype.reaffectKeyPress = function() |
|
1700 { |
|
1701 var _this = this; |
|
1702 |
|
1703 $('body').keypress(function (event) |
|
1704 { |
|
1705 _this.manageControlEvents(event); |
|
1706 }); |
|
1707 } |