1// wppa-spheric.js 2// 3// contains wppa functions for simple zoomable photos 4// 5var wppaJsSphericVersion = '8.5.03.007'; 6 7// The main proccedure 8function wppaDoSphericPan(mocc, xdata) { 9 10 if ( xdata ) wppaSphericData[mocc] = xdata; 11 var data = update(mocc, data); 12 13 // Been here before with same parms? 14 if ( data.initialized ) return; 15 if ( data.abort ) return; 16 17 // If in lightbox but lightbox not open, quitImage 18 if ( data.isLightbox && ! wppaOvlOpen ) { 19 return; 20 } 21 22 // Clear previous instance 23 if ( data.wppaRenderer ) { 24 data.wppaRenderer.state.reset(); 25 data.wppaSphere.dispose(); 26 data.wppaSphereMaterial.dispose(); 27 data.texture.dispose(); 28 } 29 30 // If lightbox, show spinner 31 if ( data.isLightbox && wppaOvlOpen ) { 32 jQuery("#wppa-ovl-spin").show(); 33 34 // Clear normal image 35 jQuery("#wppa-overlay-ic").html(""); 36 } 37 38 // Find additional data 39 data.manCtrl = false; 40 data.butDown = false; 41 data.lon = 180; 42 data.lat = 0; 43 data.dFov = 0; 44 data.abort = false; 45 data.aspect = 2; 46 data.div = jQuery("#wppa-pan-div-"+mocc ); 47 data.left = jQuery("#wppa-pctl-left-"+mocc ); 48 data.right = jQuery("#wppa-pctl-right-"+mocc ); 49 data.up = jQuery("#wppa-pctl-up-"+mocc ); 50 data.down = jQuery("#wppa-pctl-down-"+mocc ); 51 data.zoomin = jQuery("#wppa-pctl-zoomin-"+mocc ); 52 data.zoomout = jQuery("#wppa-pctl-zoomout-"+mocc ); 53 data.prev = jQuery("#wppa-pctl-prev-"+mocc ); 54 data.next = jQuery("#wppa-pctl-next-"+mocc ); 55 data.pause = false; 56 data.mFakt = ( wppaIsMobile ? '2' : '1' ); 57 data.time = 0; 58 59 if ( data.isLightbox ) { 60 wppaGlobalOvlPanoramaId++; 61 data.uId = wppaGlobalOvlPanoramaId; 62 } 63 64 jQuery(data.div).html(""); 65 66 if ( ! data.wppaRenderer ) data.wppaRenderer = new THREE.WebGLRenderer(); 67 data.wppaRenderer.setSize(data.width, data.height); 68 jQuery(data.div).append(data.wppaRenderer.domElement); 69 70 data.wppaScene = new THREE.Scene(); 71 72 data.wppaSphere = new THREE.SphereGeometry(100, 100, 40); 73 data.wppaSphere.applyMatrix4(new THREE.Matrix4().makeScale(-1, 1, 1)); 74 75 data.texture = new THREE.TextureLoader().load(data.url); 76 data.wppaSphereMaterial = new THREE.MeshBasicMaterial({map:data.texture}); 77 78 data.wppaSphereMesh = new THREE.Mesh(data.wppaSphere, data.wppaSphereMaterial); 79 data.wppaScene.add(data.wppaSphereMesh); 80 81 data.right.on("touchstart", function(e){rDown(mocc,e)}); 82 data.right.on("touchend", function(e){bUp(mocc,e)}); 83 data.left.on("touchstart", function(e){lDown(mocc,e)}); 84 data.left.on("touchend", function(e){bUp(mocc,e)}); 85 data.up.on("touchstart", function(e){uDown(mocc,e)}); 86 data.up.on("touchend", function(e){bUp(mocc,e)}); 87 data.down.on("touchstart", function(e){dDown(mocc,e)}); 88 data.down.on("touchend", function(e){bUp(mocc,e)}); 89 data.zoomin.on("touchstart", function(e){zInDown(mocc,e)}); 90 data.zoomin.on("touchend", function(e){bUp(mocc,e)}); 91 data.zoomout.on("touchstart", function(e){zOutDown(mocc,e)}); 92 data.zoomout.on("touchend", function(e){bUp(mocc,e)}); 93 94 if ( data.enableManual && jQuery("#wppa-pan-div-"+mocc+" canvas").length > 0 ) { 95 96 jQuery("#wppa-pan-div-"+mocc+" canvas")[0].addEventListener("touchstart", function(e){onMs(mocc,e)}); 97 jQuery("#wppa-pan-div-"+mocc+" canvas")[0].addEventListener("touchmove", function(e){e.stopPropagation();onMm(mocc,e)}); 98 jQuery("#wppa-pan-div-"+mocc+" canvas")[0].addEventListener("touchend", function(e){onMe(mocc,e)}); 99 } 100 101 data.right.on("mousedown", function(e){rDown(mocc,e)}); 102 data.right.on("mouseup", function(e){bUp(mocc,e)}); 103 data.left.on("mousedown", function(e){lDown(mocc,e)}); 104 data.left.on("mouseup", function(e){bUp(mocc,e)}); 105 data.up.on("mousedown", function(e){uDown(mocc,e)}); 106 data.up.on("mouseup", function(e){bUp(mocc,e)}); 107 data.down.on("mousedown", function(e){dDown(mocc,e)}); 108 data.down.on("mouseup", function(e){bUp(mocc,e)}); 109 data.zoomin.off("mousedown"); 110 data.zoomin.on("mousedown", function(e){zInDown(mocc,e)}); 111 data.zoomin.off("mouseup"); 112 data.zoomin.on("mouseup", function(e){bUp(mocc,e)}); 113 data.zoomout.on("mousedown", function(e){zOutDown(mocc,e)}); 114 data.zoomout.on("mouseup", function(e){bUp(mocc,e)}); 115 116 if ( data.enableManual && jQuery("#wppa-pan-div-"+mocc+" canvas").length > 0 ) { 117 118 jQuery("#wppa-pan-div-"+mocc+" canvas").on("mousedown", function(e){onMs(mocc,e)}); 119 jQuery("#wppa-pan-div-"+mocc+" canvas").on("mousemove", function(e){onMm(mocc,e)}); 120 jQuery("#wppa-pan-div-"+mocc+" canvas").on("mouseup", function(e){onMe(mocc,e)}); 121 jQuery("#wppa-pan-div-"+mocc+" canvas")[0].addEventListener("wheel", function(e){onDivWheel(mocc,e)}); 122 } 123 124 // Common event handlers 125 jQuery("body").on("quitimage", function(e,arg){ 126 if ( typeof(arg) == 'undefined' || arg == mocc ) quitImage(mocc,e); 127 }); 128 129 if ( data.isLightbox ) { 130 jQuery("#wppa-pctl-div-"+mocc).on("click", function(e){wppaKillEvent(e)}); 131 } 132 133 update(mocc,data); 134 135 // Install Resize handler 136 jQuery(window).on("wpparesizeend",function(e){resize(mocc,e)}); 137 138 // Optionally disable rightclick 139 wppaProtect(); 140 141 // Redo when visible again due to tabby change tab 142 jQuery(document).on("tabbychange",function(e){tabbyChange(mocc,e)}); 143 144 resize(mocc,'force'); 145 146 function render(mocc){ 147 148 var data = update(mocc); 149 150 // To prevent multiple invocations - caused by e.g. resize events - see if we were here less than the repeat time ago 151 if ( ! data.manCtrl && timnow() < data.time + 25 ) { 152 return; 153 } 154 155 update(mocc,{time:timnow()}); 156 157 if ( data.isLightbox ) { 158 if ( ! wppaOvlOpen || wppaOvlActivePanorama != data.id || wppaGlobalOvlPanoramaId > data.uId ) abort=true; 159 } 160 161 if ( data.abort ) return; 162 if ( ( data.butDown || data.manCtrl ) && data.autorun ) { 163 data.autorun = false; 164 data.dX = 0; 165 } 166 if ( data.dX == 0 && data.dY == 0 && data.dFov == 0 ) data.pause = true; 167 if ( data.butDown ) data.pause = false; 168 169 data.fov += data.dFov; 170 data.fov = Math.max(20, Math.min(120, data.fov)); 171 data.wppaCamera = new THREE.PerspectiveCamera(data.fov, data.aspect, 1, 1000); 172 data.wppaCamera.target = new THREE.Vector3(0, 0, 0); 173 data.lon += data.dX; 174 data.lat += data.dY; 175 data.lat = Math.max(-85, Math.min(85, data.lat)); 176 data.wppaCamera.target.x = 500 * Math.sin(THREE.Math.degToRad(90 - data.lat)) * Math.cos(THREE.Math.degToRad(data.lon)); 177 data.wppaCamera.target.y = 500 * Math.cos(THREE.Math.degToRad(90 - data.lat)); 178 data.wppaCamera.target.z = 500 * Math.sin(THREE.Math.degToRad(90 - data.lat)) * Math.sin(THREE.Math.degToRad(data.lon)); 179 data.wppaCamera.lookAt(data.wppaCamera.target); 180 if ( data.wppaRenderer ) { 181 data.wppaRenderer.render(data.wppaScene, data.wppaCamera); 182 } 183 184 wppaHasControlbar = true; 185 wppaAdjustControlbar(mocc); 186 jQuery("#wppa-ovl-spin").hide(); 187 188 var t = 25; 189 if ( data.manCtrl ) t = 5; 190 191 if ( data.autorun || ( ! data.pause && ( data.manCtrl || data.butDown ) ) ) { 192 if ( data.wppaRenderer ) { 193 data.timer = setTimeout(function(){render(mocc)},25); 194 } 195 } 196 update(mocc,data); 197 } 198 199 function resize(mocc,e) { 200 201 var modeIsNormal = ! wppaIsFs(); 202 var newWidth; 203 var newHeight; 204 205 data = update(mocc); 206 if ( ! data ) return; 207 208 if ( data.isLightbox ) { 209 210 if ( ! wppaOvlOpen ) return; 211 212 jQuery("#wppa-overlay-pc").show(); 213 jQuery("#wppa-overlay-pc").css("width", ""); 214 215 var widthIsLim, modeIsNormal = ! wppaIsFs(); 216 217 var contWidth, contHeight; 218 219 if ( modeIsNormal ) { 220 contWidth = window.innerWidth ? window.innerWidth : screen.width; 221 contHeight = window.innerHeight ? window.innerHeight : screen.height; 222 } 223 else { 224 contWidth = screen.width; 225 contHeight = screen.height; 226 } 227 228 // Initialize new display sizes 229 var 230 topMarg, 231 leftMarg, 232 extraX = 8, 233 extraY = 8 + ( data.controls ? data.icsize + 10 : 0 ) + 30; 234 235 // Add borderwidth in case of mode == normal 236 if ( modeIsNormal ) { 237 extraX += 2 * data.borderWidth; 238 extraY += 2 * data.borderWidth; 239 } 240 241 // Find out if the width is the limitng dimension 242 widthIsLim = ( contHeight > ( ( ( contWidth - extraX ) / 2 ) + extraY ) ); 243 244 // Compute new sizes and margins 245 if ( modeIsNormal ) { 246 if ( widthIsLim ) { 247 newWidth = contWidth - extraX; 248 newHeight = newWidth / 2; 249 topMarg = ( contHeight - newHeight - extraY ) / 2 + 20; 250 } 251 else { 252 newHeight = contHeight - extraY; 253 newWidth = newHeight * 2; 254 topMarg = 20; 255 } 256 } 257 else { 258 newWidth = screen.width; 259 newHeight = screen.height; 260 topMarg = 0; 261 } 262 data.aspect = newWidth / newHeight; 263 264 // Set css common for all 4 situations 265 jQuery("#wppa-ovl-sphericpan-container").css({top:topMarg}); 266 jQuery("#wppa-overlay-pc").css({top:0}); 267 268 // Now set css for all 4 situations: Mode is normal 269 if ( modeIsNormal ) { 270 271 // Common for mode normal 272 jQuery("#wppa-ovl-sphericpan-container").css({ 273 backgroundColor:data.backgroundColor, 274 padding:data.padding+"px", 275 borderRadius:data.borderRadius+"px", 276 width:newWidth 277 }); 278 279 // Limit specific 280 if ( widthIsLim ) { 281 jQuery("#wppa-overlay-pc").css({left:4});
282 } 283 else { 284 jQuery("#wppa-overlay-pc").css({left:(contWidth-newWidth)/2}); 285 } 286 } 287 288 // Mode is fullscreen 289 else { 290 291 // Common for mode fullscreen 292 jQuery("#wppa-ovl-sphericpan-container").css({ 293 backgroundColor:"transparent", 294 padding:0, 295 borderRadius:"0px", 296 width:newWidth, 297 left:(contWidth-newWidth)/2 298 }); 299 } 300 301 data.wppaRenderer.setSize(newWidth, newHeight); 302 } 303 304 // Not lightbox 305 else { 306 var cw = wppaGetContainerWidth(mocc); 307 var pch = data.pancontrolheight; 308 newWidth = cw; 309 newHeight = parseInt( newWidth / 2 ); 310 if (e != 'force') { 311 if (data.width > 0 && data.width == newWidth && data.height == newHeight) { 312 return; 313 } 314 } 315 316 // Slideshow 317 if ( data.slide ) { 318 var pch = data.pancontrolheight; 319 if ( pch > 0 ) pch += 5; 320 var frameRatio = wppaAspectRatio[mocc]; // aspect ratio of slideframe h / w 321 newHeight = newWidth * frameRatio - pch; 322 jQuery('#wppa-pctl-div-'+mocc).css({width:cw}); 323 jQuery('#slide_frame-'+mocc).css({height:(newHeight + pch)}); 324// console.log('sp heigt = '+newHeight); 325 } 326 327 if ( ! data.wppaRenderer ) return; // vanished ( by pla ) 328 data.wppaRenderer.setSize(newWidth, newHeight); 329 } 330 331 // Store new sizes and render 332 data.width = newWidth; 333 data.height = newHeight; 334 update(mocc,data); 335 336 data.timer = setTimeout(function(){render(mocc)},250); 337 } 338 339 // Start event handlers 340 341 // Mouse wheel 342 function onDivWheel(mocc,e) { 343 e.preventDefault(); 344 e.stopPropagation(); 345 data = update(mocc); 346 update(mocc, { 347 manCtrl :false, 348 butDown :false, 349 autorun :false, 350 dX :0, 351 dFov :-e.deltaY * data.zoomsensitivity / 60 352 }); 353 render(mocc); 354 setTimeout(function(){update(mocc,{dFov:0})}, 25); 355 } 356 357 // Manual movement on the canvas: (s(tart), m(ove), e(nd)) 358 function onMs(mocc,e) { 359 e.preventDefault(); 360 e.stopPropagation(); 361 data = update(mocc,{ 362 manCtrl :true, 363 butDown :false, 364 autorun :false, 365 dX :0 366 }); 367 if ( e.touches ) { 368 update(mocc,{ 369 sX :e.touches[0].clientX, 370 sY :e.touches[0].clientY 371 }); 372 } 373 else { 374 update(mocc,{ 375 sX :e.clientX, 376 sY :e.clientY 377 }); 378 } 379 update(mocc, { 380 sLon :data.lon, 381 sLat :data.lat 382 }); 383 render(mocc); 384 } 385 function onMm(mocc,e) { 386 e.preventDefault(); 387 e.stopPropagation(); 388 data = update(mocc); 389 if ( data.manCtrl ) { 390 if ( e.touches ) { 391 update(mocc,{ 392 lon :(data.sX - e.touches[0].clientX) * 0.1 + data.sLon, 393 lat :(e.touches[0].clientY - data.sY) * 0.1 + data.sLat, 394 pause :false 395 }); 396 } 397 else { 398 update(mocc,{ 399 lon :(data.sX - e.clientX) * 0.1 + data.sLon, 400 lat :(e.clientY - data.sY) * 0.1 + data.sLat, 401 pause :false 402 }); 403 } 404 render(mocc); 405 } 406 } 407 function onMe(mocc,e) { 408 update(mocc,{manCtrl:false}); 409 } 410 411 // Movement by buttons 412 function zInDown(mocc,e) { 413 data = update(mocc); 414 update(mocc,{ 415 dFov :-0.4*data.mFakt, 416 butDown :true 417 }); 418 render(mocc); 419 } 420 function zOutDown(mocc,e) { 421 data = update(mocc); 422 update(mocc,{ 423 dFov :0.4*data.mFakt, 424 butDown :true 425 }); 426 render(mocc); 427 } 428 function rDown(mocc,e) { 429 data = update(mocc); 430 update(mocc,{ 431 dX :0.2*data.mFakt, 432 butDown :true 433 }); 434 render(mocc); 435 } 436 function lDown(mocc,e) { 437 data = update(mocc); 438 update(mocc,{ 439 dX :-0.2*data.mFakt, 440 butDown :true 441 }); 442 render(mocc); 443 } 444 function uDown(mocc,e) { 445 data = update(mocc); 446 update(mocc,{ 447 dY :0.2*data.mFakt, 448 butDown :true 449 }); 450 render(mocc); 451 } 452 function dDown(mocc,e) { 453 data = update(mocc); 454 update(mocc,{ 455 dY :-0.2*data.mFakt, 456 butDown :true 457 }); 458 render(mocc); 459 } 460 function bUp(mocc,e) { 461 data = update(mocc); 462 update(mocc,{ 463 dX :0, 464 dY :0, 465 dFov :0, 466 butDown :false, 467 manCtrl :false 468 }); 469 } 470 471 // Update data 472 function update(mocc, data) { 473 474 if ( ! wppaSphericData[mocc] ) return false; 475 476 if (data) { 477 for (var property in data) { 478 wppaSphericData[mocc][property] = data[property]; 479 } 480 } 481 482 return wppaSphericData[mocc]; 483 } 484 485 // Re-initialize this 486 function tabbyChange(mocc,e) { 487 488 data.wppaRenderer.state.reset(); 489 data = update(mocc,{ 490 initialized:false, 491 abort:true, 492 }); 493 494 setTimeout(function(){ 495 update(mocc,{abort:false}); 496 wppaDoSphericPan(mocc); 497 },200);
498 } 499 500 // Get current time in ms 501 function timnow() { 502 d = new Date(); 503 return d.getTime(); 504 } 505 506 // Clean up 507 function quitImage(mocc,e) { 508 509 // console.log('Quit spheric '+mocc); 510 511 // Kill timer 512 clearTimeout(data.timer); 513 514 // Clear data 515 wppaSphericData[mocc] = []; 516 517 // Make sure procs do not run 518 data = update(mocc, { 519 abort :true, 520 autorun :false 521 }); 522 523 // Clear html 524 jQuery("#wppa-pan-div-"+mocc+" canvas").html(''); 525 jQuery("#wppa-pctl-div-"+mocc).html(''); 526 jQuery("#wppa-overlay-pc").html(''); 527 } 528}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.