Projet

Général

Profil

Paste
Télécharger (25,2 ko) Statistiques
| Branche: | Révision:

root / js / pano.js @ 8b0958ea

1
if (img_prefix == undefined) var img_prefix = './tiles/ttn_mediatheque/mediatheque_70';
2
if (to_cap == undefined) var to_cap = 0;
3
if (to_ele == undefined) var to_ele = 0;
4
if (to_zoom == undefined) var to_zoom = 0;
5
if (cap == undefined) var cap = 0;
6
if (cap_min == undefined) var cap_min = cap;
7
if (cap_max == undefined) var cap_max = cap_min+360;
8
if (ref_points == undefined) var ref_points = new Array();
9
if (image_loop == undefined) var image_loop = true;
10

    
11
var debug_mode = false;
12
var canvas;
13
var cntext;
14
var point_list = new Array();
15
var zoom = 0;
16
var zooms = new Array();
17
var prev_zm;
18
var zm;
19
var tile = {width:256, height:256};
20
var ntiles = {x:228, y:9};
21
var border_width = 2;
22
var imageObj = new Array();
23

    
24
var last  = {x:0,y:0};
25
var shift = {x:0,y:0};
26
var mouse = {x:0,y:0};
27
var speed = {x:0,y:0};
28
var canvas_pos = {x:0,y:0};
29
var tmt;
30
var is_located = false;
31
var point_colors = {'pano_point' : '255,128,128',
32
                    'ref_point'  : '128,128,255',
33
                    'loc_point'  : '128,255,128',
34
                    'unlocated'  : '255,255,255'};
35
var test = {x:0, y:0, i:100};
36

    
37
function nmodulo(val, div) {                // pour obtenir un modulo dans l'espace des nombres naturels N.
38
    return Math.floor((val%div+div)%div);   // il y a peut être plus simple, mais en attendant .... 
39
}
40

    
41
function fmodulo(val, div) {                // pour obtenir un modulo dans l'espace des nombres réels positifs.
42
    return (val%div+div)%div;               // il y a peut être plus simple, mais en attendant .... 
43
}
44

    
45
function distort_canvas(p, x, y) {
46
    if (p == 0) distort = 0;
47
    else {
48
        cntext.save();
49
        distort++;
50
        cntext.clearRect(0, 0, canvas.width, 2*canvas.height);
51
        var ratio = (canvas.width-2*distort)/canvas.width;
52
        var shift = canvas.height/2*(1-ratio);
53
        cntext.scale(1, ratio);
54
        if (p == 1) cntext.translate(0, 0);
55
        else if (p == -1) cntext.translate(0, 0);
56
        draw_image(x, y);
57
        cntext.restore();
58
        document.getElementById('res').innerHTML = 'distort : ' + distort + ' shift ' + shift + ' ratio : ' + ratio + '<br/>';
59
    }
60
}
61

    
62
function draw_image(ox, oy) {
63
    var ref_vals  = {x:last.x, y:last.y, zoom:zoom};
64
    ox = nmodulo(ox-canvas.width/2, zm.im.width);        // pour placer l'origine au centre du canvas 
65
    oy = Math.floor(oy-canvas.height/2);                 // pas de rebouclage vertical
66

    
67
    cntext.clearRect(0, 0, canvas.width, canvas.height);
68
    cntext.fillStyle = "rgba(128,128,128,0.8)";
69
    
70
    if (canvas.height > zm.im.height) {
71
        var fy = Math.floor((oy+canvas.height/2-zm.im.height/2)/(tile.height*zm.ntiles.y))*zm.ntiles.y;
72
        if (fy < 0) fy = 0; 
73
        var ly = fy + zm.ntiles.y;
74
    } else {
75
        var fy = Math.floor(oy/tile.height);
76
        var ly = Math.floor((oy+canvas.height+tile.height-1)/tile.height+1);
77
        if (fy < 0) fy = 0; 
78
        if (ly > zm.ntiles.y) ly = zm.ntiles.y; 
79
    }
80

    
81
    for (var j=fy; j<ly; j++) {
82
        var delta_y = (Math.floor(j/zm.ntiles.y) - Math.floor(fy/zm.ntiles.y)) * (tile.height - zm.last_tile.height);
83
        var dy = j*tile.height - oy - delta_y;
84
        var ny = j%ntiles.y;
85
        var wy = zm.tile.width;
86
        if (ny == zm.ntiles.y - 1) wy = zm.last_tile.height;
87

    
88
        var cpx = 0;
89
        var i = 0;
90
        var Nx = zm.ntiles.x;
91
        while (cpx < ox+canvas.width) {
92
            var cur_width = zm.tile.width;
93
            if (i%Nx == zm.ntiles.x-1) cur_width = zm.last_tile.width;
94
            if (cpx >= ox-cur_width) {
95
                var nx = i%Nx;
96
                var idx = nx+'-'+ny+'-'+ref_vals.zoom;
97
                if (imageObj[idx] && imageObj[idx].complete) {
98
                    draw_tile(idx, cpx-ox, dy); // l'image est déja en mémoire, on force le dessin sans attendre.
99
                } else {
100
                    var fname = get_file_name(nx, ny, ref_vals.zoom);
101
                    imageObj[idx] = new Image();
102
                    imageObj[idx].src = fname;
103
                    var ts = zm.get_tile_size(nx, ny);
104
                    cntext.fillRect(cpx-ox, dy, ts.width, ts.height);
105
                    imageObj[idx].addEventListener('load', (function(ref, idx, dx, dy, ox, oy, ts) {
106
                        return function() {        // closure nécéssaire pour gestion assynchronisme !!!
107
                            draw_tile_del(ref, idx, dx, dy, ox, oy, ts.width, ts.height);
108
                        };
109
                    })(ref_vals, idx, cpx-ox, dy, ox, oy, ts), false);
110
                }
111
//                load_image(zoom, nx, ny, shx, shy, cpx-ox, dy, ox, oy);
112
            }
113
            cpx += cur_width;
114
            i++;
115
        }
116
    }
117
    drawDecorations(ox, oy);
118
}
119

    
120
function draw_tile_del(ref, idx, tx, ty, ox, oy, twidth, theight) {
121
    if (ref.zoom == zoom && ref.x == last.x && ref.y == last.y) {
122
        draw_tile(idx, tx, ty);
123
        drawDecorations(ox, oy, tx, ty, twidth, theight);
124
    }
125
}
126

    
127
function draw_tile(idx, ox, oy) {
128
    var img = imageObj[idx];
129
    cntext.drawImage(img, ox, oy);
130
}
131

    
132
function drawDecorations(ox, oy, tx, ty, twidth, theight) {
133
    if (twidth) {
134
        cntext.save();
135
        cntext.beginPath();
136
        cntext.rect(tx, ty, twidth, theight);
137
        cntext.clip();
138
    } 
139
    var wgrd = zm.im.width/360;
140
    var od = ((ox+canvas.width/2)/wgrd)%360;
141
    var el = (zm.im.height/2 - (oy+canvas.height/2))/wgrd;
142
    cntext.fillStyle = "rgba(0,128,128,0.9)";
143
    cntext.strokeStyle = "rgb(255,255,255)";
144
    cntext.lineWidth = 1;
145
    cntext.fillRect(canvas.width/2-5, canvas.height/2-5, 10, 10);
146
    cntext.strokeRect(canvas.width/2-5, canvas.height/2-5, 10, 10);
147
    for(var i = 0; i < zm.pt_list.length; i++) {
148
        if (zm.pt_list[i]['type'] != 'unlocated') {
149
            cntext.fillStyle = 'rgba('+point_colors[zm.pt_list[i]['type']]+',0.5)';
150
            var cx = nmodulo(zm.pt_list[i]['xc'] - ox, zm.im.width);
151
            var cy = zm.pt_list[i]['yc'] - oy;
152
            cntext.beginPath();
153
            cntext.arc(cx, cy, 20, 0, 2*Math.PI, true);
154
            cntext.fill();
155
        }
156
    }
157

    
158
    //cntext.font = "20pt Arial";
159
    //cntext.fillRect(0, 0, 200, 20);
160
    //cntext.fillStyle = "rgb(255,0,0)";
161
    //cntext.fillText(od.toFixed(2), 5, 20);
162
    //for (i=0; i<canvas.width/wgrd; i++) {
163
        //cntext.strokeRect(i*wgrd, 0, wgrd, 20);
164
    //}
165
    if (twidth) {
166
        cntext.restore();
167
    }
168
}
169

    
170
function get_file_name(x, y, z) { // recherche du fichier correspondant au zoom et à la position
171
    var prm = [z, x, y];
172
    var fname = img_prefix;
173
    for (var i = 0; i < prm.length; i++) {
174
        fname += '_';
175
        if (prm[i] < 10) fname += '00';
176
        else if (prm[i] < 100) fname += '0';
177
        fname += prm[i];
178
    }
179
    fname += '.jpg';
180
    return fname;
181
}
182

    
183
function keys(key) {
184
    hide_links();
185
    evt = key || event;
186
    evt.preventDefault();
187
    evt.stopPropagation();
188
    if (!key) {
189
        key = window.event;
190
        key.which = key.keyCode;
191
    }
192
//    alert(key);
193
//    if (!evt.shiftKey) return;
194
    switch (key.which) {
195
    case 66: // b
196
        alert(key.pageX);
197
        test.x=tile.width*(ntiles.x-3);
198
        test.y=0;
199
        putImage(test.x, test.y);
200
        return;
201
    case 67: // c
202
        test.x=0;
203
        test.y=tile.height*(ntiles.y-3);
204
        putImage(test.x, test.y);
205
        return;
206
    case 36: // home
207
        putImage(0, zm.im.height/2);
208
        return;
209
    case 35: // end
210
        putImage(last.x+zm.im.width/2, last.y);
211
        return;
212
    case 39: // left
213
        putImage(last.x+40, last.y);
214
        return;
215
    case 40: // up
216
        putImage(last.x, last.y+20);
217
        return;
218
    case 37: // right
219
        putImage(last.x-40, last.y);
220
        return;
221
    case 38: // down
222
        putImage(last.x, last.y-20);
223
        return;
224
    case 33: // pageup
225
        zoom_control.value--;
226
        change_zoom()
227
        return;
228
    case 34: // pagedown
229
        zoom_control.value++;
230
        change_zoom()
231
        return;
232
    default:
233
//        alert(key.which)
234
        return;
235
    }
236
}
237

    
238
function onImageClick(e) {
239
    hide_contextmenu();
240
    shift.x = last.x;
241
    shift.y = last.y;
242
    speed.x = 0;
243
    speed.y = 0;
244
    mouse.x = e.pageX;
245
    mouse.y = e.pageY;
246
    clearTimeout(tmt);  //arrêt de l'éffet eventuel d'amorti en cours.
247
    canvas.addEventListener('mousemove', stickImage, false);
248
    canvas.addEventListener('mouseup', launchImage, false);
249
    //canvas.addEventListener('mouseout', launchImage, false);
250
    canvas.style.cursor='move';
251
    //document.onmousemove = stickImage;
252
    document.onmouseup = launchImage;
253
    hide_links();
254
}
255

    
256

    
257
function stickImage(e) {
258
    var xs = mouse.x - e.pageX + shift.x;
259
    var ys = mouse.y - e.pageY + shift.y;
260
    speed.x = xs - last.x;  //mémorisation des vitesses horizontales
261
    speed.y = ys - last.y;  //et verticales lors de ce déplacement
262
    putImage(xs, ys);
263
}
264

    
265
function launchImage(e) {
266
    distort_canvas(0);
267
    canvas.removeEventListener('mousemove', stickImage, false);
268
    //document.onmousemove = null;
269
    shift.x = e.pageX - mouse.x + shift.x;
270
    shift.y = e.pageY - mouse.y + shift.y;
271
    tmt = setTimeout(inertialImage, 100);
272
}
273

    
274
function putImage(x, y) { // est destiné à permettre l'effet d'amortissement par la mémorisation de la position courante.
275
    if (!zm.is_updated) return; 
276
    if (x >= zm.im.width) {   // rebouclage horizontal
277
        shift.x -= zm.im.width;
278
        x -= zm.im.width;
279
    } else if (x < 0) {
280
        shift.x += zm.im.width;
281
        x += zm.im.width;
282
    }
283
    if (y >= zm.im.height) {   // pas de rebouclage vertical mais blocage
284
        //distort_canvas(1, x, y);
285
        shift.y = zm.im.height-1;
286
        y = zm.im.height-1;
287
    } else if (y < 0) {
288
        //distort_canvas(-1, x, y);
289
        shift.y = 0;
290
        y = 0;
291
    }
292

    
293
    last.x = x;
294
    last.y = y;
295
    draw_image(x, y);
296
}
297

    
298
function inertialImage() {
299
    speed.x *= 0.9;
300
    speed.y *= 0.9;
301
    if (Math.abs(speed.x) > 2 || Math.abs(speed.y) > 2) {
302
        putImage(last.x+speed.x, last.y+speed.y);
303
        tmt = setTimeout(inertialImage, 100);
304
    } else {
305
        show_links();
306
    }
307
}
308

    
309
function tri_ref_points(v1, v2) {
310
    return v1['x'] - v2['x'];
311
}
312

    
313

    
314

    
315
function tzoom(zv) {
316
    this.value = zv;
317
    this.ntiles = {x:0,y:0};
318
    this.tile = {width:0,height:0};
319
    this.last_tile = {width:0,height:0};
320
    this.max_tile = {width:0,height:0};
321
    this.im = {width:0,height:0};
322
    this.is_updated = false;
323

    
324
    this.refresh = function() {
325
        this.im.visible_width = this.tile.width*(this.ntiles.x-1)+this.last_tile.width;
326
        this.is_updated = true;
327

    
328
        this.im.width = this.im.visible_width;
329
        this.im.height = this.tile.height*(this.ntiles.y-1)+this.last_tile.height;
330
        if (this.last_tile.width > this.tile.width) this.max_tile.width = this.im.last_tile.width;
331
        else this.max_tile.width = this.tile.width;
332
        if (this.last_tile.height > this.tile.height) this.max_tile.height = this.im.last_tile.height;
333
        else this.max_tile.height = this.tile.height;
334

    
335
        var ord_pts = new Array();
336
        i=0;
337
        for(var label in ref_points) {
338
            ord_pts[i++] = ref_points[label]
339
        }
340
        ord_pts = ord_pts.sort(tri_ref_points);
341
        is_located = i > 1 || image_loop && i > 0;
342

    
343
        var alpha_domain = {start:0, end:360}; 
344
        this.pixel_y_ratio = this.im.width/360;
345
        if (is_located) {
346
            this.ref_pixels = new Array;
347
            this.ref_pixels[0] = new Array();    // Attention il faut compter un intervalle de plus !
348
            for (var i=0; i < ord_pts.length; i++) { // premier parcours pour les paramètres cap/x
349
                this.ref_pixels[i+1] = new Array();
350
                this.ref_pixels[i+1].x = Math.floor(ord_pts[i].x*this.im.width);
351
                this.ref_pixels[i+1].cap = fmodulo(ord_pts[i].cap, 360);
352
                if (i != ord_pts.length-1) {
353
                    this.ref_pixels[i+1].ratio_x = (ord_pts[i+1].x - ord_pts[i].x)/fmodulo(ord_pts[i+1].cap - ord_pts[i].cap, 360)*this.im.width;
354
                }
355
            }
356
            if (image_loop == true) {
357
                var dpix = this.im.width;
358
                var dangle = 360;
359
                if (ord_pts.length > 1) {
360
                    dpix = this.im.width - this.ref_pixels[this.ref_pixels.length-1].x + this.ref_pixels[1].x;
361
                    dangle = fmodulo(this.ref_pixels[1].cap - this.ref_pixels[this.ref_pixels.length-1].cap, 360);
362
                }
363
                this.ref_pixels[0].ratio_x = dpix/dangle;
364
                this.ref_pixels[ord_pts.length].ratio_x = this.ref_pixels[0].ratio_x;
365
                dpix = this.im.width - this.ref_pixels[ord_pts.length].x;
366
                this.ref_pixels[0].cap = fmodulo(this.ref_pixels[ord_pts.length].cap + dpix / this.ref_pixels[0].ratio_x, 360);
367
            } else {
368
                this.ref_pixels[0].ratio_x = this.ref_pixels[1].ratio_x;
369
                this.ref_pixels[ord_pts.length].ratio_x = this.ref_pixels[ord_pts.length-1].ratio_x;
370
                this.ref_pixels[0].cap = fmodulo(this.ref_pixels[1].cap - this.ref_pixels[1].x / this.ref_pixels[1].ratio_x, 360);
371
                alpha_domain.start = this.ref_pixels[0].cap;
372
                alpha_domain.end = fmodulo(this.ref_pixels[ord_pts.length].cap+(this.im.width-this.ref_pixels[ord_pts.length].x)/this.ref_pixels[ord_pts.length].ratio_x, 360);
373
                this.pixel_y_ratio = this.im.width/fmodulo(alpha_domain.end-alpha_domain.start, 360);
374
            }
375
            this.ref_pixels[0].x = 0;
376

    
377
            for (var i=0; i < ord_pts.length; i++) { // second parcours pour les paramètres elevation/y
378
                this.ref_pixels[i+1].shift_y = Math.floor(this.pixel_y_ratio*ord_pts[i].ele - ord_pts[i].y*this.im.height);
379
                if (i != ord_pts.length-1) {
380
                    var next_shift = Math.floor(this.pixel_y_ratio*ord_pts[i+1].ele - ord_pts[i+1].y*this.im.height);
381
                    this.ref_pixels[i+1].dshft_y = (next_shift - this.ref_pixels[i+1].shift_y)/(this.ref_pixels[i+2].x - this.ref_pixels[i+1].x);
382
                }
383
            }
384

    
385
            if (image_loop == true) {
386
                var dpix  = this.im.width;
387
                var delt = 0;
388
                if (ord_pts.length > 1) {
389
                    dpix  = this.im.width - this.ref_pixels[this.ref_pixels.length-1].x + this.ref_pixels[1].x;
390
                    delt = this.ref_pixels[this.ref_pixels.length-1].shift_y - this.ref_pixels[1].shift_y;
391
                }
392
                this.ref_pixels[0].dshft_y = delt/dpix;
393
                this.ref_pixels[ord_pts.length].dshft_y = this.ref_pixels[0].dshft_y;
394
                dpix = this.im.width - this.ref_pixels[ord_pts.length].x;
395
                this.ref_pixels[0].shift_y = this.ref_pixels[ord_pts.length].shift_y - dpix*this.ref_pixels[0].dshft_y;
396
            } else {
397
                this.ref_pixels[0].shift_y = this.ref_pixels[1].shift_y;
398
                this.ref_pixels[ord_pts.length].shift_y = this.ref_pixels[ord_pts.length-1].shift_y;
399
                this.ref_pixels[0].dshft_y = 0;
400
                this.ref_pixels[ord_pts.length].dshft_y = 0;
401
            }
402

    
403
            if (debug_mode) {
404
                var res = document.getElementById('res');
405
                res.innerHTML = 'liste des '+this.ref_pixels.length+' valeurs de correction (image = '+this.im.width+'x'+this.im.height+') zoom = '+this.value+':<br/>';
406
                for (var i=0; i < this.ref_pixels.length; i++) { // pour le debug
407
                    res.innerHTML += '<p>point '+i+' :</p><ul>';
408
                    for (var key in this.ref_pixels[i]) { // pour le debug
409
                        res.innerHTML += '<li>'+key + '['+i+'] = '+this.ref_pixels[i][key]+'</li>';
410
                    }
411
                    if (i != this.ref_pixels.length-1) {
412
                        var tx0 = this.ref_pixels[i+1].x-1;
413
                        //var ty0 = this.ref_pixels[i+1].shift_y;
414
                        var ty0 = 0;
415
                    } else {
416
                        var tx0 = this.im.width-1;
417
                        var ty0 = 0;
418
                    }
419
                    res.innerHTML += '</ul><p>test sur : '+tx0+','+ty0+'</p>';
420
                    var tst = this.get_cap_ele(tx0, ty0);
421
                    res.innerHTML += '<p>cap:'+tst.cap+', shift:'+tst.ele+'</p>';
422
                    var tst2 = this.get_pos_xy(tst.cap, tst.ele);
423
                    res.innerHTML += '</ul><p>x:'+tst2.x+', y:'+tst2.y+'</p>';
424
                }
425
            }
426
        }
427

    
428
        this.pt_list = new Array();
429
        for (var i=0; i<point_list.length; i++) {
430
            var lbl = point_list[i][0];
431
            var dst = point_list[i][1];
432
            var cap = point_list[i][2];
433
            var ele = point_list[i][3];
434
            var lnk = point_list[i][4];
435
            var typ = 'unlocated';
436
            var rxy = this.get_pos_xy(cap, ele);
437
            var is_visible = fmodulo(cap - alpha_domain.start, 360) <= fmodulo(alpha_domain.end - alpha_domain.start -0.0001, 360)+0.0001 && is_located;
438

    
439
            this.pt_list[i] = new Array();
440
            if (ref_points[lbl] != undefined) {
441
                typ = 'ref_point';
442
                if (!is_located) rxy = {x:ref_points[lbl].x*this.im.width, y:ref_points[lbl].y*this.im.height}
443
            } else if(lnk == '' && is_visible) {
444
                typ = 'loc_point';
445
            } else if(is_visible) {
446
                typ = 'pano_point';
447
                lnk += '&to_zoom='+this.value;
448
            }
449
            this.pt_list[i]['type'] = typ;
450
            this.pt_list[i]['cap'] = cap;
451
            this.pt_list[i]['ele'] = ele;
452
            this.pt_list[i]['dist'] = dst;
453
            this.pt_list[i]['label'] = lbl;
454
            this.pt_list[i]['lnk'] = lnk;
455
            this.pt_list[i]['xc'] = rxy.x;
456
            this.pt_list[i]['yc'] = Math.floor(this.im.height/2 - rxy.y);
457
        }
458
    }
459
    
460
    this.get_tile_size = function(nx, ny) {
461
        var res = {width:0, height:0};
462
        if (nx == this.ntiles.x-1) res.width = this.last_tile.width;
463
        else res.width = this.tile.width;
464
        if (ny == this.ntiles.y-1) res.height = this.last_tile.height;
465
        else res.height = this.tile.height;
466
        return res;
467
    }
468
    
469
    this.get_cap_ele = function(px, py) {               // recherche d'un cap et d'une élévation à partir d'un pixel X,Y.
470
        if (is_located) {
471
            for (var i=0; i < this.ref_pixels.length; i++) {
472
                if (i == this.ref_pixels.length - 1 || px < this.ref_pixels[i+1].x) {
473
                    var dpix = px-this.ref_pixels[i].x;
474
                    var cp = fmodulo(this.ref_pixels[i].cap + dpix/this.ref_pixels[i].ratio_x, 360);
475
                    var el = (py+this.ref_pixels[i].shift_y+this.ref_pixels[i].dshft_y*dpix)/this.pixel_y_ratio;
476
                    return {cap:cp, ele:el};
477
                }
478
            }
479
        } else {
480
            var cp = 360*px/this.im.width;
481
            var el = 360*py/this.im.height;
482
            return {cap:cp, ele:el};
483
        }
484
    }
485
    
486
    this.get_pos_xy = function(cap, ele) {                  // recherche des coordonnées pixel à partir d'un cap et d'une élévation.
487
        if (is_located) {
488
            var dcap = fmodulo(cap-this.ref_pixels[0].cap, 360);
489
            for (var i=0; i < this.ref_pixels.length; i++) {
490
                if (i == this.ref_pixels.length - 1 || dcap < fmodulo(this.ref_pixels[i+1].cap-this.ref_pixels[0].cap, 360)) {
491
                    var px = this.ref_pixels[i].x + this.ref_pixels[i].ratio_x*fmodulo(cap - this.ref_pixels[i].cap, 360);
492
                    var dpix = px-this.ref_pixels[i].x;
493
                    var py = this.pixel_y_ratio*ele - this.ref_pixels[i].shift_y - this.ref_pixels[i].dshft_y*dpix;
494
                    return {x:px, y:py};
495
                }
496
            }
497
        } else {
498
            var px = fmodulo(cap, 360)/360*this.im.width;
499
            var py = ele/360*this.im.height;
500
            return {x:px, y:py};
501
        }
502
    }
503
}
504

    
505
function reset_zooms () {
506
    for(i=0; i<zooms.length; i++) zooms[i].is_updated = false;
507
    zm.refresh();
508
}
509

    
510
function wheel_zoom (event) {
511
    var zshift = {x:0, y:0};
512
    if (event.pageX != undefined && event.pageX != undefined) {
513
        zshift.x = event.pageX-canvas.width/2-canvas_pos.x;
514
        zshift.y = event.pageY-canvas.height/2-canvas_pos.y;
515
    }
516
    event.preventDefault();
517
    if (event.wheelDelta < 0 && zoom_control.value < zoom_control.max) {
518
        zoom_control.value++;
519
        change_zoom(zshift.x, zshift.y);
520
    } else if (event.wheelDelta > 0 && zoom_control.value > zoom_control.min) {
521
        zoom_control.value--; 
522
        change_zoom(zshift.x, zshift.y);
523
    }
524
}
525

    
526
function change_zoom(shx, shy) {
527
    var zoom_control = document.getElementById("zoom_ctrl");
528
    var v = zoom_control.value;
529

    
530
    prev_zm = zm;
531

    
532
    if (zooms[v]) {
533
        if (!zooms[v].is_updated) zooms[v].refresh();
534
    } else {
535
        zooms[v] = new tzoom(v);
536
    }
537

    
538
    if (zooms[v].is_updated) {
539
        if (shx == undefined || shy == undefined) {
540
            shx=0;
541
            shy=0;
542
        }
543
        zm = zooms[v];
544
        var px = (last.x+shx)*zm.im.width/prev_zm.im.width - shx;
545
        var py = (last.y+shy)*zm.im.height/prev_zm.im.height - shy;
546
        if (py < zm.im.height && py >= 0) {
547
            zoom = zm.value;
548
            tile = zm.tile;
549
            ntiles = zm.ntiles;
550
            putImage(px, py);
551
        } else {
552
            zm = prev_zm;
553
            zoom_control.value = zm.value;
554
        }
555
    }
556
}
557

    
558
function change_angle() {
559
    var elvtn_control = document.getElementById('elvtn_ctrl');
560
    var angle_control = document.getElementById('angle_ctrl');
561
    var resxy = zm.get_pos_xy(angle_control.value, elvtn_control.value);
562
    var pos_x = resxy.x;
563
    var pos_y = Math.floor(zm.im.height/2 - resxy.y);
564
    putImage(pos_x, pos_y);
565
}
566

    
567
function check_prox(x, y, r) {   //verification si un point de coordonnées x, y est bien dans un cercle de rayon r centré en X,Y. 
568
    return Math.sqrt(x*x + y*y) < r;
569
}
570

    
571
function check_links(e) {
572
    var mouse_x = e.pageX-canvas_pos.x;
573
    var mouse_y = e.pageY-canvas_pos.y;
574
    var pos_x = nmodulo(last.x + mouse_x - canvas.width/2, zm.im.width);
575
    var pos_y = last.y + mouse_y - canvas.height/2;
576
    for(var i = 0; i < zm.pt_list.length; i++) {
577
        if (is_located && zm.pt_list[i]['type'] == 'pano_point') {
578
            if (check_prox(zm.pt_list[i]['xc']-pos_x, zm.pt_list[i]['yc']-pos_y, 20)) {
579
                if (zm.pt_list[i]['lnk'] != '') window.location = zm.pt_list[i]['lnk'];
580
                break;
581
            }
582
        }
583
    }
584
}
585

    
586
function display_links(e) {
587
    var info = document.getElementById('info');
588
    var mouse_x = e.pageX-canvas_pos.x;
589
    var mouse_y = e.pageY-canvas_pos.y;
590
    var pos_x = nmodulo(last.x + mouse_x - canvas.width/2, zm.im.width);
591
    var pos_y = last.y + mouse_y - canvas.height/2;
592
    //var cap = ((pos_x/zm.im.width)*360).toFixed(2);
593
    var res = zm.get_cap_ele(pos_x, zm.im.height/2 - pos_y);
594
    //var ele = ((zm.im.height/2 - pos_y)/zm.im.width)*360;
595
    info.innerHTML = 'élévation : '+res.ele.toFixed(2)+'<br/>cap : '+res.cap.toFixed(2);
596
    info.style.top = e.pageY+'px';
597
    info.style.left = e.pageX+'px';
598
    info.style.backgroundColor = '#FFC';
599
    info.style.display = 'block';
600
    canvas.style.cursor='crosshair';
601
    for(var i = 0; i < zm.pt_list.length; i++) {
602
        if (is_located || zm.pt_list[i]['type'] == 'ref_point') {
603
            if (check_prox(zm.pt_list[i]['xc']-pos_x, zm.pt_list[i]['yc']-pos_y, 20)) {
604
                info.innerHTML = zm.pt_list[i]['label'];
605
                if (zm.pt_list[i]['dist'] < 10) var dst = Math.round(zm.pt_list[i]['dist']*1000)+' m';
606
                else var dst = zm.pt_list[i]['dist'].toFixed(1)+' kms';
607
                info.innerHTML += '<br/> à ' + dst;
608
                info.style.backgroundColor = 'rgb('+point_colors[zm.pt_list[i]['type']]+')';
609
                canvas.style.cursor='auto';
610
                break;
611
            }
612
        }
613
    }
614
}
615

    
616
function hide_links() {
617
    canvas.removeEventListener( "mousemove", display_links, false);
618
    var info = document.getElementById('info');
619
    info.style.display = 'none';
620
}
621

    
622
function show_links() {
623
    canvas.addEventListener( "mousemove", display_links, false);
624
//    var info = document.getElementById('info');
625
//    info.style.display = 'block';
626
}
627

    
628
function hide_contextmenu() {
629
    document.getElementById('insert').style.display = 'none';
630
}
631

    
632
function manage_ref_points(e) {
633
    //event.preventDefault();
634
    //event.stopPropagation();
635
    var insrt = document.getElementById('insert');
636
    document.getElementById('do-cancel').onclick = hide_contextmenu;
637
    insrt.style.left = e.pageX+'px';
638
    insrt.style.top = e.pageY+'px';
639
    insrt.style.display = 'block';
640
    var sel_pt = document.getElementById('sel_point');
641
    var do_insert = document.getElementById('do-insert');
642
    var do_delete = document.getElementById('do-delete');
643
    var pos_x = nmodulo(last.x + e.pageX - canvas_pos.x - canvas.width/2, zm.im.width);
644
    var pos_y = last.y + e.pageY - canvas_pos.y - canvas.height/2;
645
    for(var i = 0; i < zm.pt_list.length; i++) {
646
        if (zm.pt_list[i]['type'] == 'ref_point') {
647
            if (check_prox(zm.pt_list[i]['xc']-pos_x, zm.pt_list[i]['yc']-pos_y, 20)) {
648
                sel_pt.value = zm.pt_list[i]['label'];
649
            }
650
        }
651
    }
652
    do_delete.onclick = function() {delete_ref_point(insrt)};
653
    do_insert.onclick = function() {insert_ref_point(insrt, e.pageX-canvas_pos.x, e.pageY-canvas_pos.y)};
654
    return false;
655
}
656

    
657
function insert_ref_point(el, x, y) {
658
    var label;
659
    el.style.display = 'none';
660
    for(var i = 0; i < zm.pt_list.length; i++) {
661
        label = zm.pt_list[i]['label'];
662
        if(label == document.getElementById('sel_point').value) {
663
            var posx = nmodulo(last.x + x - canvas.width/2, zm.im.width)/zm.im.width;
664
            var posy = 0.5 - (last.y + y - canvas.height/2)/zm.im.height;
665
            var pval = {x:posx, y:posy, cap:zm.pt_list[i]['cap'], ele:zm.pt_list[i]['ele'], label:label};
666
            ref_points[label] = pval;
667
            document.getElementById('res').innerHTML = '<h4>Dernier point entré</h4>';
668
            document.getElementById('res').innerHTML += '<p>reference["'+label+'"] = '+posx.toFixed(5)+','+posy.toFixed(5)+'</p>';
669
            reset_zooms();
670
             putImage(last.x, last.y);
671
            break;
672
        }
673
    }
674
    show_result();
675
}
676

    
677
function show_result(clear_before) {
678
    var res = document.getElementById('res');
679
    var strg = '';
680
    for (var lbl in ref_points) {
681
        strg += '<li>reference["'+lbl+'"] = '+ref_points[lbl].x.toFixed(5)+','+ref_points[lbl].y.toFixed(5)+'</li>';
682
    }
683
    if (strg) strg = '<h3>Liste de tous les points de référence</h3>\n<ul>' + strg + '</ul>';
684
    if (clear_before) res.innerHTML = strg;
685
    else res.innerHTML += strg;
686
}
687

    
688
function delete_ref_point(el) {
689
    el.style.display = 'none';
690
    delete ref_points[document.getElementById('sel_point').value];
691
    reset_zooms();
692
    putImage(last.x, last.y);
693
    show_result(true);
694
}
695

    
696
function clean_canvas_events(e) {
697
    canvas.removeEventListener('mousemove', stickImage, false);
698
    document.getElementById('info').style.display = 'none';
699
    speed.x = 0;
700
    speed.y = 0;
701
}
702

    
703
canvas_set_size = function() {
704
    canvas.style.border = border_width+"px solid red";
705
    canvas.width = window.innerWidth-2*border_width;
706
    canvas.height = window.innerHeight-2*border_width;
707
    canvas_pos.x = canvas.offsetLeft+border_width;
708
    canvas_pos.y = canvas.offsetTop+border_width;
709
}
710

    
711
canvas_resize = function() {
712
    canvas_set_size();
713
    putImage(last.x, last.y);
714
}
715

    
716
window.onload = function() {
717
    canvas = document.getElementById("mon-canvas");
718
    cntext = canvas.getContext("2d");
719
    canvas_set_size();
720
    canvas.addEventListener("click", check_links, false);
721
    //canvas.addEventListener("oncontextmenu", manage_ref_points, false);
722
    canvas.oncontextmenu = manage_ref_points;
723
    canvas.addEventListener("mouseout" , clean_canvas_events, false);
724
    show_links();
725

    
726
    var max_zoom = zooms.length - 1;
727
    zoom_control = document.getElementById("zoom_ctrl");
728
    zoom_control.onchange = change_zoom;
729
    zoom_control.max = max_zoom;
730
    if (to_zoom > max_zoom) to_zoom = Math.floor(max_zoom/2);
731
    zm = zooms[to_zoom];
732
    zoom_control.value = to_zoom;
733
    zm.refresh();
734

    
735
    zoom = zm.value;
736
    tile = zm.tile;
737
    ntiles = zm.ntiles;
738

    
739
    angle_control = document.getElementById("angle_ctrl");
740
    angle_control.value = to_cap;
741
    angle_control.onchange = change_angle;
742
    angle_control.onclick = change_angle;
743
    elvtn_control = document.getElementById("elvtn_ctrl");
744
    elvtn_control.value = to_ele;
745
    elvtn_control.onchange = change_angle;
746
    elvtn_control.onclick = change_angle;
747

    
748
    change_angle();
749

    
750
    canvas.addEventListener('mousedown', onImageClick, false);
751
    addEventListener('keydown', keys, false);
752
    canvas.addEventListener('mousewheel', wheel_zoom, false);
753
    window.onresize = canvas_resize;
754
};