diff --git a/bower.json b/bower.json index f74e2da8a..228296eb2 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "Photo-Sphere-Viewer", - "version": "3.0.0", + "version": "3.0.1", "authors": [{ "name": "Jérémy Heleine", "email": "jeremy.heleine@gmail.com", diff --git a/dist/photo-sphere-viewer.css b/dist/photo-sphere-viewer.css index bc157ad4e..9073ff9fe 100644 --- a/dist/photo-sphere-viewer.css +++ b/dist/photo-sphere-viewer.css @@ -1,5 +1,5 @@ /*! - * Photo Sphere Viewer 3.0.0 + * Photo Sphere Viewer 3.0.1 * Copyright (c) 2014-2015 Jérémy Heleine * Copyright (c) 2015 Damien "Mistic" Sorel * Licensed under MIT (http://opensource.org/licenses/MIT) @@ -212,8 +212,8 @@ .psv-fullscreen-button div:before, .psv-fullscreen-button div:after { - position: absolute; content: ''; + position: absolute; width: 6.0px; height: 4px; border-style: solid; @@ -255,3 +255,59 @@ border-left-width: 0; border-top-width: 0; } + +.psv-download-button { + width: 20px; + height: 20px; +} + +.psv-download-button:before { + content: ''; + position: absolute; + width: 20px; + height: 7px; + bottom: 10px; + border: 2px solid rgba(255, 255, 255, 0.7); + border-top-width: 0; + border-radius: 0; + transition: border-radius 0.2s ease; +} + +.psv-download-button:hover:before { + border-radius: 2px; +} + +.psv-download-button div { + position: absolute; + width: 12px; + height: 12px; + top: 50%; + left: 50%; + margin: -6px; + margin-top: -8px; + transition: margin-top 0.2s ease; +} + +.psv-download-button:hover div { + margin-top: -6px; +} + +.psv-download-button div:before, +.psv-download-button div:after { + content: ''; + display: block; + margin: 0 auto; +} + +.psv-download-button div:before { + width: 6px; + height: 6px; + background: rgba(255, 255, 255, 0.7); +} + +.psv-download-button div:after { + width: 0; + height: 0; + border: 6px solid transparent; + border-top-color: rgba(255, 255, 255, 0.7); +} diff --git a/dist/photo-sphere-viewer.js b/dist/photo-sphere-viewer.js index 8da24493f..b9b30cbe3 100644 --- a/dist/photo-sphere-viewer.js +++ b/dist/photo-sphere-viewer.js @@ -1,5 +1,5 @@ /*! - * Photo Sphere Viewer 3.0.0 + * Photo Sphere Viewer 3.0.1 * Copyright (c) 2014-2015 Jérémy Heleine * Copyright (c) 2015 Damien "Mistic" Sorel * Licensed under MIT (http://opensource.org/licenses/MIT) @@ -132,6 +132,14 @@ PhotoSphereViewer.DEFAULTS = { anim_speed: '2rpm', anim_lat: null, navbar: false, + lang: { + autorotate: 'Automatic rotation', + zoom: 'Zoom', + zoomOut: 'Zoom out', + zoomIn: 'Zoom in', + download: 'Download', + fullscreen: 'Fullscreen' + }, mousewheel: true, mousemove: true, loading_img: null, @@ -684,7 +692,6 @@ PhotoSphereViewer.prototype.setAnimSpeed = function(speed) { case 'degrees per minute': case 'dps': case 'degrees per second': - // Degrees to radians (rad = deg * pi / 180) rad_per_second = speed_value * Math.PI / 180; break; @@ -699,11 +706,12 @@ PhotoSphereViewer.prototype.setAnimSpeed = function(speed) { case 'revolutions per minute': case 'rps': case 'revolutions per second': - // Unknown unit - default: - // speed * 2pi rad_per_second = speed_value * PhotoSphereViewer.TwoPI; break; + + // Unknown unit + default: + throw 'PhotoSphereViewer: unknown speed unit "' + speed_unit + '"'; } // Theta offset @@ -744,13 +752,14 @@ PhotoSphereViewer.prototype.on = function(name, f) { /** * Triggers an action * @param name (string) Action name - * @param arg (mixed) An argument to send to the handler functions + * @param args... (mixed) Arguments to send to the handler functions * @return (void) */ -PhotoSphereViewer.prototype.trigger = function(name, arg) { +PhotoSphereViewer.prototype.trigger = function(name, args) { + args = Array.prototype.slice.call(arguments, 1); if ((name in this.actions) && this.actions[name].length > 0) { for (var i = 0, l = this.actions[name].length; i < l; ++i) { - this.actions[name][i](arg); + this.actions[name][i].apply(this, args); } } }; @@ -838,15 +847,24 @@ var PSVNavBar = function(psv) { this.autorotateBtn = null; this.zoomBar = null; this.fullscreenBtn = null; + this.downloadBtn = null; this.caption = null; - if (typeof this.config != 'object') { + if (this.config === true) { this.config = { autorotate: true, zoom: true, - fullscreen: true + fullscreen: true, + download: true }; } + else if (typeof this.config == 'string') { + var map = {}; + this.config.split(/[ ,:]/).forEach(function(button) { + map[button] = true; + }); + this.config = map; + } this.create(); }; @@ -878,6 +896,12 @@ PSVNavBar.prototype.create = function() { this.container.appendChild(this.fullscreenBtn.getButton()); } + // Download button + if (this.config.download) { + this.downloadBtn = new PSVNavBarDownloadButton(this.psv); + this.container.appendChild(this.downloadBtn.getButton()); + } + // Caption this.caption = document.createElement('div'); this.caption.className = 'psv-caption'; @@ -965,6 +989,7 @@ PSVNavBarAutorotateButton.prototype.constructor = PSVNavBarAutorotateButton; PSVNavBarAutorotateButton.prototype.create = function() { this.button = document.createElement('div'); this.button.className = 'psv-button psv-autorotate-button'; + this.button.title = this.psv.config.lang.autorotate; var autorotate_sphere = document.createElement('div'); autorotate_sphere.className = 'psv-autorotate-sphere'; @@ -997,6 +1022,7 @@ PSVNavBarFullscreenButton.prototype.constructor = PSVNavBarFullscreenButton; PSVNavBarFullscreenButton.prototype.create = function() { this.button = document.createElement('div'); this.button.className = 'psv-button psv-fullscreen-button'; + this.button.title = this.psv.config.lang.fullscreen; this.button.appendChild(document.createElement('div')); this.button.appendChild(document.createElement('div')); @@ -1032,6 +1058,7 @@ PSVNavBarZoomButton.prototype.create = function() { var zoom_minus = document.createElement('div'); zoom_minus.className = 'psv-zoom-minus'; + zoom_minus.title = this.psv.config.lang.zoomOut; this.button.appendChild(zoom_minus); var zoom_range_bg = document.createElement('div'); @@ -1040,14 +1067,17 @@ PSVNavBarZoomButton.prototype.create = function() { this.zoom_range = document.createElement('div'); this.zoom_range.className = 'psv-zoom-range-line'; + this.zoom_range.title = this.psv.config.lang.zoom; zoom_range_bg.appendChild(this.zoom_range); this.zoom_value = document.createElement('div'); this.zoom_value.className = 'psv-zoom-range-handle'; + this.zoom_value.title = this.psv.config.lang.zoom; this.zoom_range.appendChild(this.zoom_value); var zoom_plus = document.createElement('div'); zoom_plus.className = 'psv-zoom-plus'; + zoom_plus.title = this.psv.config.lang.zoomIn; this.button.appendChild(zoom_plus); PSVUtils.addEvent(this.zoom_range, 'mousedown', this._initZoomChangeWithMouse.bind(this)); @@ -1151,6 +1181,47 @@ PSVNavBarZoomButton.prototype._changeZoom = function(x) { } }; +/** + * Navigation bar download button class + * @param psv (PhotoSphereViewer) A PhotoSphereViewer object + */ +var PSVNavBarDownloadButton = function(psv) { + PSVNavBarButton.call(this, psv); + + this.create(); +}; + +PSVNavBarDownloadButton.prototype = Object.create(PSVNavBarButton.prototype); +PSVNavBarDownloadButton.prototype.constructor = PSVNavBarDownloadButton; + +/** + * Creates the button + * @return (void) + */ +PSVNavBarDownloadButton.prototype.create = function() { + this.button = document.createElement('div'); + this.button.className = 'psv-button psv-download-button'; + this.button.title = this.psv.config.lang.download; + + this.button.appendChild(document.createElement('div')); + + PSVUtils.addEvent(this.button, 'mouseenter', this.toggleActive.bind(this, true)); + PSVUtils.addEvent(this.button, 'mouseleave', this.toggleActive.bind(this, false)); + PSVUtils.addEvent(this.button, 'click', this.download.bind(this)); +}; + +/** + * Ask the browser to download the panorama source file + */ +PSVNavBarDownloadButton.prototype.download = function() { + var link = document.createElement('a'); + link.href = this.psv.config.panorama; + link.download = this.psv.config.panorama; + this.psv.config.container.appendChild(link); + link.click(); + this.psv.config.container.removeChild(link); +}; + /** * Static utilities for PSV */ diff --git a/dist/photo-sphere-viewer.min.css b/dist/photo-sphere-viewer.min.css index 0242c7a32..58f8fbe03 100644 --- a/dist/photo-sphere-viewer.min.css +++ b/dist/photo-sphere-viewer.min.css @@ -1,8 +1,8 @@ /*! - * Photo Sphere Viewer 3.0.0 + * Photo Sphere Viewer 3.0.1 * Copyright (c) 2014-2015 Jérémy Heleine * Copyright (c) 2015 Damien "Mistic" Sorel * Licensed under MIT (http://opensource.org/licenses/MIT) */ -.psv-caption,.psv-container.loading{text-align:center}.psv-container,.psv-container *{box-sizing:content-box;font-family:sans-serif;margin:0;padding:0}.psv-container{width:100%;height:100%;position:relative;background:radial-gradient(#fff,#fdfdfd 16%,#fbfbfb 33%,#f8f8f8 49%,#efefef 66%,#dfdfdf 82%,#bfbfbf 100%)}.psv-canvas-container{position:absolute;z-index:0}.psv-canvas-container canvas{display:block}.psv-loader{position:relative;color:rgba(61,61,61,.7);width:150px;height:150px;border:10px solid transparent}.psv-loader-canvas{position:absolute;top:0;left:0}.psv-container.loading:before,.psv-loader:before{content:'';display:inline-block;height:100%;vertical-align:middle}.psv-loader,.psv-loader-image,.psv-loader-text{display:inline-block;vertical-align:middle}.psv-navbar{position:absolute;z-index:10;bottom:0;width:100%;background:rgba(61,61,61,.5)}.psv-caption{color:rgba(255,255,255,.7);margin:10px;white-space:nowrap;overflow:hidden}.psv-button{float:left;padding:10px;position:relative;cursor:pointer;height:20px;background:0 0}.psv-button.active{background:rgba(255,255,255,.1)}.psv-zoom-button{cursor:default}.psv-zoom-minus,.psv-zoom-plus{float:left;position:relative;cursor:pointer;width:9px;height:9px;color:rgba(255,255,255,.7);margin:4.5px 0;border:1px solid rgba(255,255,255,.7);border-radius:30%;transition:transform .3s ease}.psv-zoom-minus:before,.psv-zoom-plus:after,.psv-zoom-plus:before{content:'';position:absolute;top:4px;left:1px;width:7px;height:1px;background:rgba(255,255,255,.7)}.psv-zoom-plus:after{transform:rotate(90deg)}.psv-zoom-button:hover .psv-zoom-minus,.psv-zoom-button:hover .psv-zoom-plus{transform:scale(1.2)}.psv-zoom-range{float:left;padding:9.5px 10px}.psv-zoom-range-line{position:relative;cursor:pointer;width:80px;height:1px;background:rgba(255,255,255,.7);transition:all .3s ease}.psv-zoom-button:hover .psv-zoom-range-line{box-shadow:0 0 2px rgba(255,255,255,.7)}.psv-zoom-range-handle{position:absolute;border-radius:50%;top:-3px;width:7px;height:7px;background:rgba(255,255,255,.7);transform:scale(1);transition:transform .3s ease}.psv-zoom-button:hover .psv-zoom-range-handle{transform:scale(1.3)}.psv-autorotate-button{width:20px}.psv-autorotate-equator,.psv-autorotate-sphere{border-radius:50%;border-width:1px;border-style:solid;border-color:rgba(255,255,255,.7)}.psv-autorotate-sphere{width:18px;height:18px;transform:rotateY(0);transition:all .3s ease}.psv-autorotate-button:hover .psv-autorotate-sphere{transform:rotateY(180deg)}.psv-autorotate-equator{position:absolute;top:50%;width:18px;height:1.8px;margin-top:-1.9px;transform:rotateY(0);transition:all .3s ease}.psv-autorotate-button:hover .psv-autorotate-equator{transform:rotateY(180deg);height:4.5px;margin-top:-3.25px}.psv-fullscreen-button{float:right;width:26.67px;height:20px}.psv-fullscreen-button div{position:absolute;width:26.67px;height:20px}.psv-fullscreen-button div:after,.psv-fullscreen-button div:before{position:absolute;content:'';width:6px;height:4px;border-style:solid;border-color:rgba(255,255,255,.7);border-width:2px;transition:all .2s ease}.psv-fullscreen-button:hover div:after,.psv-fullscreen-button:hover div:before{width:8.67px;height:6px}.psv-fullscreen-button div:first-child:before{top:0;left:0;border-right-width:0;border-bottom-width:0}.psv-fullscreen-button div:first-child:after{top:0;right:0;border-left-width:0;border-bottom-width:0}.psv-fullscreen-button div:last-child:before{bottom:0;left:0;border-right-width:0;border-top-width:0}.psv-fullscreen-button div:last-child:after{bottom:0;right:0;border-left-width:0;border-top-width:0} \ No newline at end of file +.psv-caption,.psv-container.loading{text-align:center}.psv-container,.psv-container *{box-sizing:content-box;font-family:sans-serif;margin:0;padding:0}.psv-container{width:100%;height:100%;position:relative;background:radial-gradient(#fff,#fdfdfd 16%,#fbfbfb 33%,#f8f8f8 49%,#efefef 66%,#dfdfdf 82%,#bfbfbf 100%)}.psv-canvas-container{position:absolute;z-index:0}.psv-canvas-container canvas{display:block}.psv-loader{position:relative;color:rgba(61,61,61,.7);width:150px;height:150px;border:10px solid transparent}.psv-loader-canvas{position:absolute;top:0;left:0}.psv-container.loading:before,.psv-loader:before{content:'';display:inline-block;height:100%;vertical-align:middle}.psv-loader,.psv-loader-image,.psv-loader-text{display:inline-block;vertical-align:middle}.psv-navbar{position:absolute;z-index:10;bottom:0;width:100%;background:rgba(61,61,61,.5)}.psv-caption{color:rgba(255,255,255,.7);margin:10px;white-space:nowrap;overflow:hidden}.psv-button{float:left;padding:10px;position:relative;cursor:pointer;height:20px;background:0 0}.psv-button.active{background:rgba(255,255,255,.1)}.psv-zoom-button{cursor:default}.psv-zoom-minus,.psv-zoom-plus{float:left;position:relative;cursor:pointer;width:9px;height:9px;color:rgba(255,255,255,.7);margin:4.5px 0;border:1px solid rgba(255,255,255,.7);border-radius:30%;transition:transform .3s ease}.psv-zoom-minus:before,.psv-zoom-plus:after,.psv-zoom-plus:before{content:'';position:absolute;top:4px;left:1px;width:7px;height:1px;background:rgba(255,255,255,.7)}.psv-zoom-plus:after{transform:rotate(90deg)}.psv-zoom-button:hover .psv-zoom-minus,.psv-zoom-button:hover .psv-zoom-plus{transform:scale(1.2)}.psv-zoom-range{float:left;padding:9.5px 10px}.psv-zoom-range-line{position:relative;cursor:pointer;width:80px;height:1px;background:rgba(255,255,255,.7);transition:all .3s ease}.psv-zoom-button:hover .psv-zoom-range-line{box-shadow:0 0 2px rgba(255,255,255,.7)}.psv-zoom-range-handle{position:absolute;border-radius:50%;top:-3px;width:7px;height:7px;background:rgba(255,255,255,.7);transform:scale(1);transition:transform .3s ease}.psv-zoom-button:hover .psv-zoom-range-handle{transform:scale(1.3)}.psv-autorotate-button{width:20px}.psv-autorotate-equator,.psv-autorotate-sphere{border-radius:50%;border-width:1px;border-style:solid;border-color:rgba(255,255,255,.7)}.psv-autorotate-sphere{width:18px;height:18px;transform:rotateY(0);transition:all .3s ease}.psv-autorotate-button:hover .psv-autorotate-sphere{transform:rotateY(180deg)}.psv-autorotate-equator{position:absolute;top:50%;width:18px;height:1.8px;margin-top:-1.9px;transform:rotateY(0);transition:all .3s ease}.psv-autorotate-button:hover .psv-autorotate-equator{transform:rotateY(180deg);height:4.5px;margin-top:-3.25px}.psv-fullscreen-button{float:right;width:26.67px;height:20px}.psv-fullscreen-button div{position:absolute;width:26.67px;height:20px}.psv-fullscreen-button div:after,.psv-fullscreen-button div:before{content:'';position:absolute;width:6px;height:4px;border-style:solid;border-color:rgba(255,255,255,.7);border-width:2px;transition:all .2s ease}.psv-fullscreen-button:hover div:after,.psv-fullscreen-button:hover div:before{width:8.67px;height:6px}.psv-fullscreen-button div:first-child:before{top:0;left:0;border-right-width:0;border-bottom-width:0}.psv-fullscreen-button div:first-child:after{top:0;right:0;border-left-width:0;border-bottom-width:0}.psv-fullscreen-button div:last-child:before{bottom:0;left:0;border-right-width:0;border-top-width:0}.psv-fullscreen-button div:last-child:after{bottom:0;right:0;border-left-width:0;border-top-width:0}.psv-download-button{width:20px;height:20px}.psv-download-button:before{content:'';position:absolute;width:20px;height:7px;bottom:10px;border:2px solid rgba(255,255,255,.7);border-top-width:0;border-radius:0;transition:border-radius .2s ease}.psv-download-button:hover:before{border-radius:2px}.psv-download-button div{position:absolute;width:12px;height:12px;top:50%;left:50%;margin:-8px -6px -6px;transition:margin-top .2s ease}.psv-download-button:hover div{margin-top:-6px}.psv-download-button div:after,.psv-download-button div:before{content:'';display:block;margin:0 auto}.psv-download-button div:before{width:6px;height:6px;background:rgba(255,255,255,.7)}.psv-download-button div:after{width:0;height:0;border:6px solid transparent;border-top-color:rgba(255,255,255,.7)} \ No newline at end of file diff --git a/dist/photo-sphere-viewer.min.js b/dist/photo-sphere-viewer.min.js index 5b2e921e7..c4e173024 100644 --- a/dist/photo-sphere-viewer.min.js +++ b/dist/photo-sphere-viewer.min.js @@ -1,8 +1,8 @@ /*! - * Photo Sphere Viewer 3.0.0 + * Photo Sphere Viewer 3.0.1 * Copyright (c) 2014-2015 Jérémy Heleine * Copyright (c) 2015 Damien "Mistic" Sorel * Licensed under MIT (http://opensource.org/licenses/MIT) */ -!function(a,b){"function"==typeof define&&define.amd?define(["three"],b):a.PhotoSphereViewer=b(a.THREE)}(this,function(a){"use strict";var b=function(a){if(!(this instanceof b))return new b(a);if(void 0===a||void 0===a.panorama||void 0===a.container)throw"PhotoSphereViewer: no value given for panorama or container";this.config=i.deepmerge(b.DEFAULTS,a),this.config.min_fov=i.stayBetween(this.config.min_fov,1,179),this.config.max_fov=i.stayBetween(this.config.max_fov,1,179),this.config.default_fov=null===this.config.default_fov?this.config.max_fov:i.stayBetween(this.config.default_fov,this.config.min_fov,this.config.max_fov),null===this.config.anim_lat&&(this.config.anim_lat=this.config.default_lat),this.config.anim_lat=i.stayBetween(this.config.anim_lat,-b.HalfPI,b.HalfPI),this.container=this.config.container,this.loader=null,this.navbar=null,this.canvas_container=null,this.renderer=null,this.scene=null,this.camera=null,this.actions={},this.prop={fps:60,phi:0,theta:0,theta_offset:0,zoom_lvl:0,mousedown:!1,mouse_x:0,mouse_y:0,autorotate_timeout:null,anim_timeout:null,size:{width:0,height:0,ratio:0}},this.prop.zoom_lvl=Math.round((this.config.default_fov-this.config.min_fov)/(this.config.max_fov-this.config.min_fov)*100),this.prop.zoom_lvl-=2*(this.prop.zoom_lvl-50),this.setAnimSpeed(this.config.anim_speed),this.rotate(this.config.default_long,this.config.default_lat),null!==this.config.size&&this._setViewerSize(this.config.size),this.config.autoload&&this.load()};b.TwoPI=2*Math.PI,b.HalfPI=Math.PI/2,b.DEFAULTS={panorama:null,container:null,caption:null,autoload:!0,usexmpdata:!0,min_fov:30,max_fov:90,default_fov:null,default_long:0,default_lat:0,long_offset:Math.PI/720,lat_offset:Math.PI/360,time_anim:2e3,anim_speed:"2rpm",anim_lat:null,navbar:!1,mousewheel:!0,mousemove:!0,loading_img:null,loading_txt:"Loading...",size:null},b.prototype.load=function(){if(i.addClass(this.container,"psv-container loading"),!i.isCanvasSupported())return void(this.container.textContent="Canvas is not supported, update your browser!");this.loader=new c(this),this.container.appendChild(this.loader.getLoader()),this.loader.create(),this.canvas_container=document.createElement("div"),this.canvas_container.className="psv-canvas-container",this.container.appendChild(this.canvas_container),i.addEvent(window,"resize",this._onResize.bind(this)),this.config.mousemove&&(this.canvas_container.style.cursor="move",i.addEvent(this.canvas_container,"mousedown",this._onMouseDown.bind(this)),i.addEvent(this.canvas_container,"touchstart",this._onTouchStart.bind(this)),i.addEvent(document,"mouseup",this._onMouseUp.bind(this)),i.addEvent(document,"touchend",this._onMouseUp.bind(this)),i.addEvent(document,"mousemove",this._onMouseMove.bind(this)),i.addEvent(document,"touchmove",this._onTouchMove.bind(this))),this.config.mousewheel&&i.addEvent(this.canvas_container,i.mouseWheelEvent(),this._onMouseWheel.bind(this));var a=this._fullscreenToggled.bind(this);i.addEvent(document,"fullscreenchange",a),i.addEvent(document,"mozfullscreenchange",a),i.addEvent(document,"webkitfullscreenchange",a),i.addEvent(document,"MSFullscreenChange",a),this.config.usexmpdata?this._loadXMP():this._loadTexture(!1,!1)},b.prototype._loadXMP=function(){if(!window.XMLHttpRequest)return void(this.container.textContent="XHR is not supported, update your browser!");var a=new XMLHttpRequest,b=this,c=0;a.onreadystatechange=function(){if(4==a.readyState)if(200==a.status){b.loader.setProgress(100);var c=a.responseText,d=c.indexOf(""),f=c.substring(d,e);if(-1==d||-1==e||-1==f.indexOf("GPano:"))return void b._loadTexture(!1,!0);var g={full_width:parseInt(i.getAttribute(f,"FullPanoWidthPixels")),full_height:parseInt(i.getAttribute(f,"FullPanoHeightPixels")),cropped_width:parseInt(i.getAttribute(f,"CroppedAreaImageWidthPixels")),cropped_height:parseInt(i.getAttribute(f,"CroppedAreaImageHeightPixels")),cropped_x:parseInt(i.getAttribute(f,"CroppedAreaLeftPixels")),cropped_y:parseInt(i.getAttribute(f,"CroppedAreaTopPixels"))};b._loadTexture(g,!0)}else b.container.textContent="Cannot load image"},a.onprogress=function(a){if(a.lengthComputable){var d=parseInt(a.loaded/a.total*100);d>c&&(c=d,b.loader.setProgress(c))}},a.onerror=function(){b.container.textContent="Cannot load image"},a.open("GET",this.config.panorama,!0),a.send(null)},b.prototype._loadTexture=function(b,c){var d=new a.ImageLoader,e=this,f=c?100:0;this.config.panorama.match(/^data:image\/[a-z]+;base64/)||d.setCrossOrigin("anonymous");var g=function(a){e.loader.setProgress(100),b||(b={full_width:a.width,full_height:a.height,cropped_width:a.width,cropped_height:a.height,cropped_x:0,cropped_y:0});var c=4096;i.isWebGLSupported()&&(c=i.getMaxTextureWidth());var d=Math.min(b.full_width,c),f=d/b.full_width;b.full_width*=f,b.full_height*=f,b.cropped_width*=f,b.cropped_height*=f,b.cropped_x*=f,b.cropped_y*=f,a.width=b.cropped_width,a.height=b.cropped_height;var g=document.createElement("canvas");g.width=b.full_width,g.height=b.full_height;var h=g.getContext("2d");h.drawImage(a,b.cropped_x,b.cropped_y,b.cropped_width,b.cropped_height),e._createScene(g)},h=function(a){if(a.lengthComputable){var b=parseInt(a.loaded/a.total*100);b>f&&(f=b,e.loader.setProgress(f))}},j=function(){e.container.textContent="Cannot load image"};d.load(this.config.panorama,g,h,j)},b.prototype._createScene=function(b){this._onResize(),this.renderer=i.isWebGLSupported()?new a.WebGLRenderer:new a.CanvasRenderer,this.renderer.setSize(this.prop.size.width,this.prop.size.height),this.camera=new a.PerspectiveCamera(this.config.default_fov,this.prop.size.ratio,1,300),this.camera.position.set(0,0,0),this.scene=new a.Scene,this.scene.add(this.camera);var c=new a.Texture(b);c.needsUpdate=!0;var e=new a.SphereGeometry(200,32,32),f=new a.MeshBasicMaterial({map:c,overdraw:!0}),g=new a.Mesh(e,f);g.scale.x=-1,this.scene.add(g),this.canvas_container.appendChild(this.renderer.domElement),this.container.removeChild(this.loader.getLoader()),this.loader=null,i.removeClass(this.container,"loading"),this.config.navbar&&(this.navbar=new d(this),this.container.appendChild(this.navbar.getBar())),this.config.time_anim!==!1&&(this.prop.anim_timeout=setTimeout(this.startAutorotate.bind(this),this.config.time_anim)),this.trigger("ready"),this.render()},b.prototype.render=function(){var b=new a.Vector3;b.setX(-Math.cos(this.prop.phi)*Math.sin(this.prop.theta)),b.setY(Math.sin(this.prop.phi)),b.setZ(Math.cos(this.prop.phi)*Math.cos(this.prop.theta)),this.camera.lookAt(b),this.renderer.render(this.scene,this.camera)},b.prototype._autorotate=function(){this.rotate(this.prop.theta+this.prop.theta_offset,this.prop.phi-(this.prop.phi-this.config.anim_lat)/200),this.prop.autorotate_timeout=setTimeout(this._autorotate.bind(this),1e3/this.prop.fps)},b.prototype.startAutorotate=function(){this._autorotate(),this.trigger("autorotate",!0)},b.prototype.stopAutorotate=function(){clearTimeout(this.prop.anim_timeout),this.prop.anim_timeout=null,clearTimeout(this.prop.autorotate_timeout),this.prop.autorotate_timeout=null,this.trigger("autorotate",!1)},b.prototype.toggleAutorotate=function(){clearTimeout(this.prop.anim_timeout),this.prop.autorotate_timeout?this.stopAutorotate():this.startAutorotate()},b.prototype._onResize=function(){(this.container.clientWidth!=this.prop.size.width||this.container.clientHeight!=this.prop.size.height)&&this.resize(this.container.clientWidth,this.container.clientHeight)},b.prototype.resize=function(a,b){this.prop.size.width=parseInt(a),this.prop.size.height=parseInt(b),this.prop.size.ratio=this.prop.size.width/this.prop.size.height,this.camera&&(this.camera.aspect=this.prop.size.ratio,this.camera.updateProjectionMatrix()),this.renderer&&(this.renderer.setSize(this.prop.size.width,this.prop.size.height),this.render()),this.trigger("size-updated",this.prop.size.width,this.prop.size.height)},b.prototype._onMouseDown=function(a){this._startMove(parseInt(a.clientX),parseInt(a.clientY))},b.prototype._onTouchStart=function(a){var b=a.changedTouches[0];b.target.parentNode==this.canvas_container&&this._startMove(parseInt(b.clientX),parseInt(b.clientY))},b.prototype._startMove=function(a,b){this.prop.mouse_x=a,this.prop.mouse_y=b,this.stopAutorotate(),this.prop.mousedown=!0},b.prototype._onMouseUp=function(a){this.prop.mousedown=!1},b.prototype._onMouseMove=function(a){a.preventDefault(),this._move(parseInt(a.clientX),parseInt(a.clientY))},b.prototype._onTouchMove=function(a){var b=a.changedTouches[0];b.target.parentNode==this.canvas_container&&(a.preventDefault(),this._move(parseInt(b.clientX),parseInt(b.clientY)))},b.prototype._move=function(a,b){this.prop.mousedown&&(this.rotate(this.prop.theta-(a-this.prop.mouse_x)*this.config.long_offset,this.prop.phi+(b-this.prop.mouse_y)*this.config.lat_offset),this.prop.mouse_x=a,this.prop.mouse_y=b)},b.prototype.rotate=function(a,c){this.prop.theta=a-Math.floor(a/b.TwoPI)*b.TwoPI,this.prop.phi=i.stayBetween(c,-b.HalfPI,b.HalfPI),this.renderer&&this.render(),this.trigger("position-updated",this.prop.theta,this.prop.phi)},b.prototype._onMouseWheel=function(a){a.preventDefault(),a.stopPropagation();var b=void 0!==a.deltaY?-a.deltaY:void 0!==a.wheelDelta?a.wheelDelta:-a.detail;if(0!==b){var c=parseInt(b/Math.abs(b));this.zoom(this.prop.zoom_lvl+c)}},b.prototype.zoom=function(a){this.prop.zoom_lvl=i.stayBetween(parseInt(Math.round(a)),0,100),this.camera.fov=this.config.max_fov+this.prop.zoom_lvl/100*(this.config.min_fov-this.config.max_fov),this.camera.updateProjectionMatrix(),this.render(),this.trigger("zoom-updated",this.prop.zoom_lvl)},b.prototype.zoomIn=function(){this.prop.zoom_lvl<100&&this.zoom(this.prop.zoom_lvl+1)},b.prototype.zoomOut=function(){this.prop.zoom_lvl>0&&this.zoom(this.prop.zoom_lvl-1)},b.prototype._fullscreenToggled=function(){this.trigger("fullscreen-updated",i.isFullscreenEnabled())},b.prototype.toggleFullscreen=function(){i.isFullscreenEnabled()?i.exitFullscreen():i.requestFullscreen(this.container)},b.prototype.setAnimSpeed=function(a){a=a.toString().trim();var c=parseFloat(a.replace(/^(-?[0-9]+(?:\.[0-9]*)?).*$/,"$1")),d=a.replace(/^-?[0-9]+(?:\.[0-9]*)?(.*)$/,"$1").trim();d.match(/(pm|per minute)$/)&&(c/=60);var e=0;switch(d){case"dpm":case"degrees per minute":case"dps":case"degrees per second":e=c*Math.PI/180;break;case"radians per minute":case"radians per second":e=c;break;case"rpm":case"revolutions per minute":case"rps":case"revolutions per second":default:e=c*b.TwoPI}this.prop.theta_offset=e/this.prop.fps},b.prototype._setViewerSize=function(a){for(var b in a)("width"==b||"height"==b)&&(/^[0-9.]+$/.test(a[b])&&(a[b]+="px"),this.container.style[b]=a[b])},b.prototype.on=function(a,b){a in this.actions||(this.actions[a]=[]),this.actions[a].push(b)},b.prototype.trigger=function(a,b){if(a in this.actions&&this.actions[a].length>0)for(var c=0,d=this.actions[a].length;d>c;++c)this.actions[a][c](b)};var c=function(a){this.psv=a,this.container=document.createElement("div"),this.container.className="psv-loader",this.canvas=document.createElement("canvas"),this.canvas.className="psv-loader-canvas"};c.prototype.create=function(){this.canvas.width=this.container.clientWidth,this.canvas.height=this.container.clientWidth,this.container.appendChild(this.canvas),this.tickness=(this.container.offsetWidth-this.container.clientWidth)/2;var a;if(this.psv.config.loading_img?(a=document.createElement("img"),a.className="psv-loader-image",a.src=this.psv.config.loading_img):this.psv.config.loading_txt&&(a=document.createElement("div"),a.className="psv-loader-text",a.innerHTML=this.psv.config.loading_txt),a){var b=Math.round(Math.sqrt(2*Math.pow(this.canvas.width/2-this.tickness/2,2)));a.style.maxWidth=b+"px",a.style.maxHeight=b+"px",this.container.appendChild(a)}},c.prototype.setProgress=function(a){var b=this.canvas.getContext("2d");b.clearRect(0,0,this.canvas.width,this.canvas.height),b.lineWidth=this.tickness,b.strokeStyle=i.getStyle(this.container,"color"),b.beginPath(),b.arc(this.canvas.width/2,this.canvas.height/2,this.canvas.width/2-this.tickness/2,-Math.PI/2,a/100*2*Math.PI-Math.PI/2),b.stroke()},c.prototype.getLoader=function(){return this.container};var d=function(a){this.psv=a,this.config=this.psv.config.navbar,this.container=null,this.autorotateBtn=null,this.zoomBar=null,this.fullscreenBtn=null,this.caption=null,"object"!=typeof this.config&&(this.config={autorotate:!0,zoom:!0,fullscreen:!0}),this.create()};d.prototype.create=function(){this.container=document.createElement("div"),this.container.className="psv-navbar",this.config.autorotate&&(this.autorotateBtn=new f(this.psv),this.container.appendChild(this.autorotateBtn.getButton())),this.config.zoom&&(this.zoomBar=new h(this.psv),this.container.appendChild(this.zoomBar.getButton())),this.config.fullscreen&&(this.fullscreenBtn=new g(this.psv),this.container.appendChild(this.fullscreenBtn.getButton())),this.caption=document.createElement("div"),this.caption.className="psv-caption",this.container.appendChild(this.caption),this.setCaption(this.psv.config.caption)},d.prototype.getBar=function(){return this.container},d.prototype.setCaption=function(a){a?(this.caption.style.display="block",this.caption.innerHTML=a):this.caption.style.display="none"};var e=function(a){this.psv=a,this.button=null};e.prototype.create=function(){throw"Not implemented"},e.prototype.getButton=function(){return this.button},e.prototype.toggleActive=function(a){a?i.addClass(this.button,"active"):i.removeClass(this.button,"active")};var f=function(a){e.call(this,a),this.create()};f.prototype=Object.create(e.prototype),f.prototype.constructor=f,f.prototype.create=function(){this.button=document.createElement("div"),this.button.className="psv-button psv-autorotate-button";var a=document.createElement("div");a.className="psv-autorotate-sphere",this.button.appendChild(a);var b=document.createElement("div");b.className="psv-autorotate-equator",this.button.appendChild(b),i.addEvent(this.button,"click",this.psv.toggleAutorotate.bind(this.psv)),this.psv.on("autorotate",this.toggleActive.bind(this))};var g=function(a){e.call(this,a),this.create()};g.prototype=Object.create(e.prototype),g.prototype.constructor=g,g.prototype.create=function(){this.button=document.createElement("div"),this.button.className="psv-button psv-fullscreen-button",this.button.appendChild(document.createElement("div")),this.button.appendChild(document.createElement("div")),i.addEvent(this.button,"click",this.psv.toggleFullscreen.bind(this.psv)),this.psv.on("fullscreen-updated",this.toggleActive.bind(this))};var h=function(a){e.call(this,a),this.zoom_range=null,this.zoom_value=null,this.mousedown=!1,this.create()};h.prototype=Object.create(e.prototype),h.prototype.constructor=h,h.prototype.create=function(){this.button=document.createElement("div"),this.button.className="psv-button psv-zoom-button";var a=document.createElement("div");a.className="psv-zoom-minus",this.button.appendChild(a);var b=document.createElement("div");b.className="psv-zoom-range",this.button.appendChild(b),this.zoom_range=document.createElement("div"),this.zoom_range.className="psv-zoom-range-line",b.appendChild(this.zoom_range),this.zoom_value=document.createElement("div"),this.zoom_value.className="psv-zoom-range-handle",this.zoom_range.appendChild(this.zoom_value);var c=document.createElement("div");c.className="psv-zoom-plus",this.button.appendChild(c),i.addEvent(this.zoom_range,"mousedown",this._initZoomChangeWithMouse.bind(this)),i.addEvent(this.zoom_range,"touchstart",this._initZoomChangeByTouch.bind(this)),i.addEvent(document,"mousemove",this._changeZoomWithMouse.bind(this)),i.addEvent(document,"touchmove",this._changeZoomByTouch.bind(this)),i.addEvent(document,"mouseup",this._stopZoomChange.bind(this)),i.addEvent(document,"touchend",this._stopZoomChange.bind(this)),i.addEvent(a,"click",this.psv.zoomOut.bind(this.psv)),i.addEvent(c,"click",this.psv.zoomIn.bind(this.psv)),this.psv.on("zoom-updated",this._moveZoomValue.bind(this));var d=this;setTimeout(function(){d._moveZoomValue(d.psv.prop.zoom_lvl)},0)},h.prototype._moveZoomValue=function(a){this.zoom_value.style.left=a/100*this.zoom_range.offsetWidth-this.zoom_value.offsetWidth/2+"px"},h.prototype._initZoomChangeWithMouse=function(a){this._initZoomChange(parseInt(a.clientX))},h.prototype._initZoomChangeByTouch=function(a){var b=a.changedTouches[0];(b.target==this.zoom_range||b.target==this.zoom_value)&&this._initZoomChange(parseInt(b.clientX))},h.prototype._initZoomChange=function(a){this.mousedown=!0,this._changeZoom(a)},h.prototype._stopZoomChange=function(a){this.mousedown=!1},h.prototype._changeZoomWithMouse=function(a){a.preventDefault(),this._changeZoom(parseInt(a.clientX))},h.prototype._changeZoomByTouch=function(a){var b=a.changedTouches[0];(b.target==this.zoom_range||b.target==this.zoom_value)&&(a.preventDefault(),this._changeZoom(parseInt(b.clientX)))},h.prototype._changeZoom=function(a){if(this.mousedown){var b=a-this.zoom_range.getBoundingClientRect().left,c=b/this.zoom_range.offsetWidth*100;this.psv.zoom(c)}};var i={};return i.addClass=function(a,b){a.className.length?a.className+=" "+b:a.className=b},i.removeClass=function(a,b){a.className.length&&(a.className=a.className.replace(new RegExp("\\b"+b+"\\b"),"").trim())},i.isCanvasSupported=function(){var a=document.createElement("canvas");return!(!a.getContext||!a.getContext("2d"))},i.isWebGLSupported=function(){var a=document.createElement("canvas");return!(!window.WebGLRenderingContext||!a.getContext("webgl"))},i.getMaxTextureWidth=function(){var a=document.createElement("canvas"),b=a.getContext("webgl");return b.getParameter(b.MAX_TEXTURE_SIZE)},i.addEvent=function(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent("on"+b,c)},i.mouseWheelEvent=function(){return"onwheel"in document.createElement("div")?"wheel":void 0!==document.onmousewheel?"mousewheel":"DOMMouseScroll"},i.stayBetween=function(a,b,c){return Math.max(b,Math.min(c,a))},i.getAttribute=function(a,b){var c=a.indexOf("GPano:"+b)+b.length+8,d=a.indexOf('"',c);return a.substring(c,d)},i.isFullscreenEnabled=function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement},i.requestFullscreen=function(a){(a.requestFullscreen||a.mozRequestFullScreen||a.webkitRequestFullscreen||a.msRequestFullscreen).call(a)},i.exitFullscreen=function(a){(document.exitFullscreen||document.mozCancelFullScreen||document.webkitExitFullscreen||document.msExitFullscreen).call(document)},i.getStyle=function(a,b){return window.getComputedStyle(a,null)[b]},i.deepmerge=function(a,b){var c=Array.isArray(b),d=c&&[]||{};return c?(a=a||[],d=d.concat(a),b.forEach(function(b,c){"undefined"==typeof d[c]?d[c]=b:"object"==typeof b?d[c]=i.deepmerge(a[c],b):-1===a.indexOf(b)&&d.push(b)})):(a&&"object"==typeof a&&Object.keys(a).forEach(function(b){d[b]=a[b]}),Object.keys(b).forEach(function(c){d[c]="object"==typeof b[c]&&b[c]&&a[c]?i.deepmerge(a[c],b[c]):b[c]})),d},b}); \ No newline at end of file +!function(a,b){"function"==typeof define&&define.amd?define(["three"],b):a.PhotoSphereViewer=b(a.THREE)}(this,function(a){"use strict";var b=function(a){if(!(this instanceof b))return new b(a);if(void 0===a||void 0===a.panorama||void 0===a.container)throw"PhotoSphereViewer: no value given for panorama or container";this.config=j.deepmerge(b.DEFAULTS,a),this.config.min_fov=j.stayBetween(this.config.min_fov,1,179),this.config.max_fov=j.stayBetween(this.config.max_fov,1,179),this.config.default_fov=null===this.config.default_fov?this.config.max_fov:j.stayBetween(this.config.default_fov,this.config.min_fov,this.config.max_fov),null===this.config.anim_lat&&(this.config.anim_lat=this.config.default_lat),this.config.anim_lat=j.stayBetween(this.config.anim_lat,-b.HalfPI,b.HalfPI),this.container=this.config.container,this.loader=null,this.navbar=null,this.canvas_container=null,this.renderer=null,this.scene=null,this.camera=null,this.actions={},this.prop={fps:60,phi:0,theta:0,theta_offset:0,zoom_lvl:0,mousedown:!1,mouse_x:0,mouse_y:0,autorotate_timeout:null,anim_timeout:null,size:{width:0,height:0,ratio:0}},this.prop.zoom_lvl=Math.round((this.config.default_fov-this.config.min_fov)/(this.config.max_fov-this.config.min_fov)*100),this.prop.zoom_lvl-=2*(this.prop.zoom_lvl-50),this.setAnimSpeed(this.config.anim_speed),this.rotate(this.config.default_long,this.config.default_lat),null!==this.config.size&&this._setViewerSize(this.config.size),this.config.autoload&&this.load()};b.TwoPI=2*Math.PI,b.HalfPI=Math.PI/2,b.DEFAULTS={panorama:null,container:null,caption:null,autoload:!0,usexmpdata:!0,min_fov:30,max_fov:90,default_fov:null,default_long:0,default_lat:0,long_offset:Math.PI/720,lat_offset:Math.PI/360,time_anim:2e3,anim_speed:"2rpm",anim_lat:null,navbar:!1,lang:{autorotate:"Automatic rotation",zoom:"Zoom",zoomOut:"Zoom out",zoomIn:"Zoom in",download:"Download",fullscreen:"Fullscreen"},mousewheel:!0,mousemove:!0,loading_img:null,loading_txt:"Loading...",size:null},b.prototype.load=function(){if(j.addClass(this.container,"psv-container loading"),!j.isCanvasSupported())return void(this.container.textContent="Canvas is not supported, update your browser!");this.loader=new c(this),this.container.appendChild(this.loader.getLoader()),this.loader.create(),this.canvas_container=document.createElement("div"),this.canvas_container.className="psv-canvas-container",this.container.appendChild(this.canvas_container),j.addEvent(window,"resize",this._onResize.bind(this)),this.config.mousemove&&(this.canvas_container.style.cursor="move",j.addEvent(this.canvas_container,"mousedown",this._onMouseDown.bind(this)),j.addEvent(this.canvas_container,"touchstart",this._onTouchStart.bind(this)),j.addEvent(document,"mouseup",this._onMouseUp.bind(this)),j.addEvent(document,"touchend",this._onMouseUp.bind(this)),j.addEvent(document,"mousemove",this._onMouseMove.bind(this)),j.addEvent(document,"touchmove",this._onTouchMove.bind(this))),this.config.mousewheel&&j.addEvent(this.canvas_container,j.mouseWheelEvent(),this._onMouseWheel.bind(this));var a=this._fullscreenToggled.bind(this);j.addEvent(document,"fullscreenchange",a),j.addEvent(document,"mozfullscreenchange",a),j.addEvent(document,"webkitfullscreenchange",a),j.addEvent(document,"MSFullscreenChange",a),this.config.usexmpdata?this._loadXMP():this._loadTexture(!1,!1)},b.prototype._loadXMP=function(){if(!window.XMLHttpRequest)return void(this.container.textContent="XHR is not supported, update your browser!");var a=new XMLHttpRequest,b=this,c=0;a.onreadystatechange=function(){if(4==a.readyState)if(200==a.status){b.loader.setProgress(100);var c=a.responseText,d=c.indexOf(""),f=c.substring(d,e);if(-1==d||-1==e||-1==f.indexOf("GPano:"))return void b._loadTexture(!1,!0);var g={full_width:parseInt(j.getAttribute(f,"FullPanoWidthPixels")),full_height:parseInt(j.getAttribute(f,"FullPanoHeightPixels")),cropped_width:parseInt(j.getAttribute(f,"CroppedAreaImageWidthPixels")),cropped_height:parseInt(j.getAttribute(f,"CroppedAreaImageHeightPixels")),cropped_x:parseInt(j.getAttribute(f,"CroppedAreaLeftPixels")),cropped_y:parseInt(j.getAttribute(f,"CroppedAreaTopPixels"))};b._loadTexture(g,!0)}else b.container.textContent="Cannot load image"},a.onprogress=function(a){if(a.lengthComputable){var d=parseInt(a.loaded/a.total*100);d>c&&(c=d,b.loader.setProgress(c))}},a.onerror=function(){b.container.textContent="Cannot load image"},a.open("GET",this.config.panorama,!0),a.send(null)},b.prototype._loadTexture=function(b,c){var d=new a.ImageLoader,e=this,f=c?100:0;this.config.panorama.match(/^data:image\/[a-z]+;base64/)||d.setCrossOrigin("anonymous");var g=function(a){e.loader.setProgress(100),b||(b={full_width:a.width,full_height:a.height,cropped_width:a.width,cropped_height:a.height,cropped_x:0,cropped_y:0});var c=4096;j.isWebGLSupported()&&(c=j.getMaxTextureWidth());var d=Math.min(b.full_width,c),f=d/b.full_width;b.full_width*=f,b.full_height*=f,b.cropped_width*=f,b.cropped_height*=f,b.cropped_x*=f,b.cropped_y*=f,a.width=b.cropped_width,a.height=b.cropped_height;var g=document.createElement("canvas");g.width=b.full_width,g.height=b.full_height;var h=g.getContext("2d");h.drawImage(a,b.cropped_x,b.cropped_y,b.cropped_width,b.cropped_height),e._createScene(g)},h=function(a){if(a.lengthComputable){var b=parseInt(a.loaded/a.total*100);b>f&&(f=b,e.loader.setProgress(f))}},i=function(){e.container.textContent="Cannot load image"};d.load(this.config.panorama,g,h,i)},b.prototype._createScene=function(b){this._onResize(),this.renderer=j.isWebGLSupported()?new a.WebGLRenderer:new a.CanvasRenderer,this.renderer.setSize(this.prop.size.width,this.prop.size.height),this.camera=new a.PerspectiveCamera(this.config.default_fov,this.prop.size.ratio,1,300),this.camera.position.set(0,0,0),this.scene=new a.Scene,this.scene.add(this.camera);var c=new a.Texture(b);c.needsUpdate=!0;var e=new a.SphereGeometry(200,32,32),f=new a.MeshBasicMaterial({map:c,overdraw:!0}),g=new a.Mesh(e,f);g.scale.x=-1,this.scene.add(g),this.canvas_container.appendChild(this.renderer.domElement),this.container.removeChild(this.loader.getLoader()),this.loader=null,j.removeClass(this.container,"loading"),this.config.navbar&&(this.navbar=new d(this),this.container.appendChild(this.navbar.getBar())),this.config.time_anim!==!1&&(this.prop.anim_timeout=setTimeout(this.startAutorotate.bind(this),this.config.time_anim)),this.trigger("ready"),this.render()},b.prototype.render=function(){var b=new a.Vector3;b.setX(-Math.cos(this.prop.phi)*Math.sin(this.prop.theta)),b.setY(Math.sin(this.prop.phi)),b.setZ(Math.cos(this.prop.phi)*Math.cos(this.prop.theta)),this.camera.lookAt(b),this.renderer.render(this.scene,this.camera)},b.prototype._autorotate=function(){this.rotate(this.prop.theta+this.prop.theta_offset,this.prop.phi-(this.prop.phi-this.config.anim_lat)/200),this.prop.autorotate_timeout=setTimeout(this._autorotate.bind(this),1e3/this.prop.fps)},b.prototype.startAutorotate=function(){this._autorotate(),this.trigger("autorotate",!0)},b.prototype.stopAutorotate=function(){clearTimeout(this.prop.anim_timeout),this.prop.anim_timeout=null,clearTimeout(this.prop.autorotate_timeout),this.prop.autorotate_timeout=null,this.trigger("autorotate",!1)},b.prototype.toggleAutorotate=function(){clearTimeout(this.prop.anim_timeout),this.prop.autorotate_timeout?this.stopAutorotate():this.startAutorotate()},b.prototype._onResize=function(){(this.container.clientWidth!=this.prop.size.width||this.container.clientHeight!=this.prop.size.height)&&this.resize(this.container.clientWidth,this.container.clientHeight)},b.prototype.resize=function(a,b){this.prop.size.width=parseInt(a),this.prop.size.height=parseInt(b),this.prop.size.ratio=this.prop.size.width/this.prop.size.height,this.camera&&(this.camera.aspect=this.prop.size.ratio,this.camera.updateProjectionMatrix()),this.renderer&&(this.renderer.setSize(this.prop.size.width,this.prop.size.height),this.render()),this.trigger("size-updated",this.prop.size.width,this.prop.size.height)},b.prototype._onMouseDown=function(a){this._startMove(parseInt(a.clientX),parseInt(a.clientY))},b.prototype._onTouchStart=function(a){var b=a.changedTouches[0];b.target.parentNode==this.canvas_container&&this._startMove(parseInt(b.clientX),parseInt(b.clientY))},b.prototype._startMove=function(a,b){this.prop.mouse_x=a,this.prop.mouse_y=b,this.stopAutorotate(),this.prop.mousedown=!0},b.prototype._onMouseUp=function(a){this.prop.mousedown=!1},b.prototype._onMouseMove=function(a){a.preventDefault(),this._move(parseInt(a.clientX),parseInt(a.clientY))},b.prototype._onTouchMove=function(a){var b=a.changedTouches[0];b.target.parentNode==this.canvas_container&&(a.preventDefault(),this._move(parseInt(b.clientX),parseInt(b.clientY)))},b.prototype._move=function(a,b){this.prop.mousedown&&(this.rotate(this.prop.theta-(a-this.prop.mouse_x)*this.config.long_offset,this.prop.phi+(b-this.prop.mouse_y)*this.config.lat_offset),this.prop.mouse_x=a,this.prop.mouse_y=b)},b.prototype.rotate=function(a,c){this.prop.theta=a-Math.floor(a/b.TwoPI)*b.TwoPI,this.prop.phi=j.stayBetween(c,-b.HalfPI,b.HalfPI),this.renderer&&this.render(),this.trigger("position-updated",this.prop.theta,this.prop.phi)},b.prototype._onMouseWheel=function(a){a.preventDefault(),a.stopPropagation();var b=void 0!==a.deltaY?-a.deltaY:void 0!==a.wheelDelta?a.wheelDelta:-a.detail;if(0!==b){var c=parseInt(b/Math.abs(b));this.zoom(this.prop.zoom_lvl+c)}},b.prototype.zoom=function(a){this.prop.zoom_lvl=j.stayBetween(parseInt(Math.round(a)),0,100),this.camera.fov=this.config.max_fov+this.prop.zoom_lvl/100*(this.config.min_fov-this.config.max_fov),this.camera.updateProjectionMatrix(),this.render(),this.trigger("zoom-updated",this.prop.zoom_lvl)},b.prototype.zoomIn=function(){this.prop.zoom_lvl<100&&this.zoom(this.prop.zoom_lvl+1)},b.prototype.zoomOut=function(){this.prop.zoom_lvl>0&&this.zoom(this.prop.zoom_lvl-1)},b.prototype._fullscreenToggled=function(){this.trigger("fullscreen-updated",j.isFullscreenEnabled())},b.prototype.toggleFullscreen=function(){j.isFullscreenEnabled()?j.exitFullscreen():j.requestFullscreen(this.container)},b.prototype.setAnimSpeed=function(a){a=a.toString().trim();var c=parseFloat(a.replace(/^(-?[0-9]+(?:\.[0-9]*)?).*$/,"$1")),d=a.replace(/^-?[0-9]+(?:\.[0-9]*)?(.*)$/,"$1").trim();d.match(/(pm|per minute)$/)&&(c/=60);var e=0;switch(d){case"dpm":case"degrees per minute":case"dps":case"degrees per second":e=c*Math.PI/180;break;case"radians per minute":case"radians per second":e=c;break;case"rpm":case"revolutions per minute":case"rps":case"revolutions per second":e=c*b.TwoPI;break;default:throw'PhotoSphereViewer: unknown speed unit "'+d+'"'}this.prop.theta_offset=e/this.prop.fps},b.prototype._setViewerSize=function(a){for(var b in a)("width"==b||"height"==b)&&(/^[0-9.]+$/.test(a[b])&&(a[b]+="px"),this.container.style[b]=a[b])},b.prototype.on=function(a,b){a in this.actions||(this.actions[a]=[]),this.actions[a].push(b)},b.prototype.trigger=function(a,b){if(b=Array.prototype.slice.call(arguments,1),a in this.actions&&this.actions[a].length>0)for(var c=0,d=this.actions[a].length;d>c;++c)this.actions[a][c].apply(this,b)};var c=function(a){this.psv=a,this.container=document.createElement("div"),this.container.className="psv-loader",this.canvas=document.createElement("canvas"),this.canvas.className="psv-loader-canvas"};c.prototype.create=function(){this.canvas.width=this.container.clientWidth,this.canvas.height=this.container.clientWidth,this.container.appendChild(this.canvas),this.tickness=(this.container.offsetWidth-this.container.clientWidth)/2;var a;if(this.psv.config.loading_img?(a=document.createElement("img"),a.className="psv-loader-image",a.src=this.psv.config.loading_img):this.psv.config.loading_txt&&(a=document.createElement("div"),a.className="psv-loader-text",a.innerHTML=this.psv.config.loading_txt),a){var b=Math.round(Math.sqrt(2*Math.pow(this.canvas.width/2-this.tickness/2,2)));a.style.maxWidth=b+"px",a.style.maxHeight=b+"px",this.container.appendChild(a)}},c.prototype.setProgress=function(a){var b=this.canvas.getContext("2d");b.clearRect(0,0,this.canvas.width,this.canvas.height),b.lineWidth=this.tickness,b.strokeStyle=j.getStyle(this.container,"color"),b.beginPath(),b.arc(this.canvas.width/2,this.canvas.height/2,this.canvas.width/2-this.tickness/2,-Math.PI/2,a/100*2*Math.PI-Math.PI/2),b.stroke()},c.prototype.getLoader=function(){return this.container};var d=function(a){if(this.psv=a,this.config=this.psv.config.navbar,this.container=null,this.autorotateBtn=null,this.zoomBar=null,this.fullscreenBtn=null,this.downloadBtn=null,this.caption=null,this.config===!0)this.config={autorotate:!0,zoom:!0,fullscreen:!0,download:!0};else if("string"==typeof this.config){var b={};this.config.split(/[ ,:]/).forEach(function(a){b[a]=!0}),this.config=b}this.create()};d.prototype.create=function(){this.container=document.createElement("div"),this.container.className="psv-navbar",this.config.autorotate&&(this.autorotateBtn=new f(this.psv),this.container.appendChild(this.autorotateBtn.getButton())),this.config.zoom&&(this.zoomBar=new h(this.psv),this.container.appendChild(this.zoomBar.getButton())),this.config.fullscreen&&(this.fullscreenBtn=new g(this.psv),this.container.appendChild(this.fullscreenBtn.getButton())),this.config.download&&(this.downloadBtn=new i(this.psv),this.container.appendChild(this.downloadBtn.getButton())),this.caption=document.createElement("div"),this.caption.className="psv-caption",this.container.appendChild(this.caption),this.setCaption(this.psv.config.caption)},d.prototype.getBar=function(){return this.container},d.prototype.setCaption=function(a){a?(this.caption.style.display="block",this.caption.innerHTML=a):this.caption.style.display="none"};var e=function(a){this.psv=a,this.button=null};e.prototype.create=function(){throw"Not implemented"},e.prototype.getButton=function(){return this.button},e.prototype.toggleActive=function(a){a?j.addClass(this.button,"active"):j.removeClass(this.button,"active")};var f=function(a){e.call(this,a),this.create()};f.prototype=Object.create(e.prototype),f.prototype.constructor=f,f.prototype.create=function(){this.button=document.createElement("div"),this.button.className="psv-button psv-autorotate-button",this.button.title=this.psv.config.lang.autorotate;var a=document.createElement("div");a.className="psv-autorotate-sphere",this.button.appendChild(a);var b=document.createElement("div");b.className="psv-autorotate-equator",this.button.appendChild(b),j.addEvent(this.button,"click",this.psv.toggleAutorotate.bind(this.psv)),this.psv.on("autorotate",this.toggleActive.bind(this))};var g=function(a){e.call(this,a),this.create()};g.prototype=Object.create(e.prototype),g.prototype.constructor=g,g.prototype.create=function(){this.button=document.createElement("div"),this.button.className="psv-button psv-fullscreen-button",this.button.title=this.psv.config.lang.fullscreen,this.button.appendChild(document.createElement("div")),this.button.appendChild(document.createElement("div")),j.addEvent(this.button,"click",this.psv.toggleFullscreen.bind(this.psv)),this.psv.on("fullscreen-updated",this.toggleActive.bind(this))};var h=function(a){e.call(this,a),this.zoom_range=null,this.zoom_value=null,this.mousedown=!1,this.create()};h.prototype=Object.create(e.prototype),h.prototype.constructor=h,h.prototype.create=function(){this.button=document.createElement("div"),this.button.className="psv-button psv-zoom-button";var a=document.createElement("div");a.className="psv-zoom-minus",a.title=this.psv.config.lang.zoomOut,this.button.appendChild(a);var b=document.createElement("div");b.className="psv-zoom-range",this.button.appendChild(b),this.zoom_range=document.createElement("div"),this.zoom_range.className="psv-zoom-range-line",this.zoom_range.title=this.psv.config.lang.zoom,b.appendChild(this.zoom_range),this.zoom_value=document.createElement("div"),this.zoom_value.className="psv-zoom-range-handle",this.zoom_value.title=this.psv.config.lang.zoom,this.zoom_range.appendChild(this.zoom_value);var c=document.createElement("div");c.className="psv-zoom-plus",c.title=this.psv.config.lang.zoomIn,this.button.appendChild(c),j.addEvent(this.zoom_range,"mousedown",this._initZoomChangeWithMouse.bind(this)),j.addEvent(this.zoom_range,"touchstart",this._initZoomChangeByTouch.bind(this)),j.addEvent(document,"mousemove",this._changeZoomWithMouse.bind(this)),j.addEvent(document,"touchmove",this._changeZoomByTouch.bind(this)),j.addEvent(document,"mouseup",this._stopZoomChange.bind(this)),j.addEvent(document,"touchend",this._stopZoomChange.bind(this)),j.addEvent(a,"click",this.psv.zoomOut.bind(this.psv)),j.addEvent(c,"click",this.psv.zoomIn.bind(this.psv)),this.psv.on("zoom-updated",this._moveZoomValue.bind(this));var d=this;setTimeout(function(){d._moveZoomValue(d.psv.prop.zoom_lvl)},0)},h.prototype._moveZoomValue=function(a){this.zoom_value.style.left=a/100*this.zoom_range.offsetWidth-this.zoom_value.offsetWidth/2+"px"},h.prototype._initZoomChangeWithMouse=function(a){this._initZoomChange(parseInt(a.clientX))},h.prototype._initZoomChangeByTouch=function(a){var b=a.changedTouches[0];(b.target==this.zoom_range||b.target==this.zoom_value)&&this._initZoomChange(parseInt(b.clientX))},h.prototype._initZoomChange=function(a){this.mousedown=!0,this._changeZoom(a)},h.prototype._stopZoomChange=function(a){this.mousedown=!1},h.prototype._changeZoomWithMouse=function(a){a.preventDefault(),this._changeZoom(parseInt(a.clientX))},h.prototype._changeZoomByTouch=function(a){var b=a.changedTouches[0];(b.target==this.zoom_range||b.target==this.zoom_value)&&(a.preventDefault(),this._changeZoom(parseInt(b.clientX)))},h.prototype._changeZoom=function(a){if(this.mousedown){var b=a-this.zoom_range.getBoundingClientRect().left,c=b/this.zoom_range.offsetWidth*100;this.psv.zoom(c)}};var i=function(a){e.call(this,a),this.create()};i.prototype=Object.create(e.prototype),i.prototype.constructor=i,i.prototype.create=function(){this.button=document.createElement("div"),this.button.className="psv-button psv-download-button",this.button.title=this.psv.config.lang.download,this.button.appendChild(document.createElement("div")),j.addEvent(this.button,"mouseenter",this.toggleActive.bind(this,!0)),j.addEvent(this.button,"mouseleave",this.toggleActive.bind(this,!1)),j.addEvent(this.button,"click",this.download.bind(this))},i.prototype.download=function(){var a=document.createElement("a");a.href=this.psv.config.panorama,a.download=this.psv.config.panorama,this.psv.config.container.appendChild(a),a.click(),this.psv.config.container.removeChild(a)};var j={};return j.addClass=function(a,b){a.className.length?a.className+=" "+b:a.className=b},j.removeClass=function(a,b){a.className.length&&(a.className=a.className.replace(new RegExp("\\b"+b+"\\b"),"").trim())},j.isCanvasSupported=function(){var a=document.createElement("canvas");return!(!a.getContext||!a.getContext("2d"))},j.isWebGLSupported=function(){var a=document.createElement("canvas");return!(!window.WebGLRenderingContext||!a.getContext("webgl"))},j.getMaxTextureWidth=function(){var a=document.createElement("canvas"),b=a.getContext("webgl");return b.getParameter(b.MAX_TEXTURE_SIZE)},j.addEvent=function(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent("on"+b,c)},j.mouseWheelEvent=function(){return"onwheel"in document.createElement("div")?"wheel":void 0!==document.onmousewheel?"mousewheel":"DOMMouseScroll"},j.stayBetween=function(a,b,c){return Math.max(b,Math.min(c,a))},j.getAttribute=function(a,b){var c=a.indexOf("GPano:"+b)+b.length+8,d=a.indexOf('"',c);return a.substring(c,d)},j.isFullscreenEnabled=function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement},j.requestFullscreen=function(a){(a.requestFullscreen||a.mozRequestFullScreen||a.webkitRequestFullscreen||a.msRequestFullscreen).call(a)},j.exitFullscreen=function(a){(document.exitFullscreen||document.mozCancelFullScreen||document.webkitExitFullscreen||document.msExitFullscreen).call(document)},j.getStyle=function(a,b){return window.getComputedStyle(a,null)[b]},j.deepmerge=function(a,b){var c=Array.isArray(b),d=c&&[]||{};return c?(a=a||[],d=d.concat(a),b.forEach(function(b,c){"undefined"==typeof d[c]?d[c]=b:"object"==typeof b?d[c]=j.deepmerge(a[c],b):-1===a.indexOf(b)&&d.push(b)})):(a&&"object"==typeof a&&Object.keys(a).forEach(function(b){d[b]=a[b]}),Object.keys(b).forEach(function(c){d[c]="object"==typeof b[c]&&b[c]&&a[c]?j.deepmerge(a[c],b[c]):b[c]})),d},b}); \ No newline at end of file diff --git a/package.json b/package.json index 2af1ecac9..6f97dbc42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Photo-Sphere-Viewer", - "version": "3.0.0", + "version": "3.0.1", "authors": [{ "name": "Jérémy Heleine", "email": "jeremy.heleine@gmail.com", diff --git a/src/PSVNavBar.js b/src/PSVNavBar.js index 453a731ac..25422b1e0 100644 --- a/src/PSVNavBar.js +++ b/src/PSVNavBar.js @@ -12,7 +12,7 @@ var PSVNavBar = function(psv) { this.downloadBtn = null; this.caption = null; - if (typeof this.config != 'object') { + if (this.config === true) { this.config = { autorotate: true, zoom: true, @@ -20,6 +20,13 @@ var PSVNavBar = function(psv) { download: true }; } + else if (typeof this.config == 'string') { + var map = {}; + this.config.split(/[ ,:]/).forEach(function(button) { + map[button] = true; + }); + this.config = map; + } this.create(); }; diff --git a/src/PhotoSphereViewer.js b/src/PhotoSphereViewer.js index 452baf77b..55e329868 100644 --- a/src/PhotoSphereViewer.js +++ b/src/PhotoSphereViewer.js @@ -675,7 +675,6 @@ PhotoSphereViewer.prototype.setAnimSpeed = function(speed) { case 'degrees per minute': case 'dps': case 'degrees per second': - // Degrees to radians (rad = deg * pi / 180) rad_per_second = speed_value * Math.PI / 180; break; @@ -690,11 +689,12 @@ PhotoSphereViewer.prototype.setAnimSpeed = function(speed) { case 'revolutions per minute': case 'rps': case 'revolutions per second': - // Unknown unit - default: - // speed * 2pi rad_per_second = speed_value * PhotoSphereViewer.TwoPI; break; + + // Unknown unit + default: + throw 'PhotoSphereViewer: unknown speed unit "' + speed_unit + '"'; } // Theta offset @@ -735,13 +735,14 @@ PhotoSphereViewer.prototype.on = function(name, f) { /** * Triggers an action * @param name (string) Action name - * @param arg (mixed) An argument to send to the handler functions + * @param args... (mixed) Arguments to send to the handler functions * @return (void) */ -PhotoSphereViewer.prototype.trigger = function(name, arg) { +PhotoSphereViewer.prototype.trigger = function(name, args) { + args = Array.prototype.slice.call(arguments, 1); if ((name in this.actions) && this.actions[name].length > 0) { for (var i = 0, l = this.actions[name].length; i < l; ++i) { - this.actions[name][i](arg); + this.actions[name][i].apply(this, args); } } }; \ No newline at end of file