Advertisement
Guest User

Untitled

a guest
Aug 19th, 2019
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.22 KB | None | 0 0
  1. /*
  2. * Copyright 2016 Google Inc. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. 'use strict';
  17.  
  18. (function() {
  19. var Marzipano = window.Marzipano;
  20. var bowser = window.bowser;
  21. var screenfull = window.screenfull;
  22. var data = window.APP_DATA;
  23.  
  24. // Grab elements from DOM.
  25. var panoElement = document.querySelector('#pano');
  26. var sceneNameElement = document.querySelector('#titleBar .sceneName');
  27. var sceneListElement = document.querySelector('#sceneList');
  28. var sceneElements = document.querySelectorAll('#sceneList .scene');
  29. var sceneListToggleElement = document.querySelector('#sceneListToggle');
  30. var autorotateToggleElement = document.querySelector('#autorotateToggle');
  31. var fullscreenToggleElement = document.querySelector('#fullscreenToggle');
  32.  
  33. // Detect desktop or mobile mode.
  34. if (window.matchMedia) {
  35. var setMode = function() {
  36. if (mql.matches) {
  37. document.body.classList.remove('desktop');
  38. document.body.classList.add('mobile');
  39. } else {
  40. document.body.classList.remove('mobile');
  41. document.body.classList.add('desktop');
  42. }
  43. };
  44. var mql = matchMedia("(max-width: 500px), (max-height: 500px)");
  45. setMode();
  46. mql.addListener(setMode);
  47. } else {
  48. document.body.classList.add('desktop');
  49. }
  50.  
  51. // Detect whether we are on a touch device.
  52. document.body.classList.add('no-touch');
  53. window.addEventListener('touchstart', function() {
  54. document.body.classList.remove('no-touch');
  55. document.body.classList.add('touch');
  56. });
  57.  
  58. // Use tooltip fallback mode on IE < 11.
  59. if (bowser.msie && parseFloat(bowser.version) < 11) {
  60. document.body.classList.add('tooltip-fallback');
  61. }
  62.  
  63. // Viewer options.
  64. var viewerOpts = {
  65. controls: {
  66. mouseViewMode: data.settings.mouseViewMode
  67. }
  68. };
  69.  
  70. // Initialize viewer.
  71. var viewer = new Marzipano.Viewer(panoElement, viewerOpts);
  72.  
  73. // Create scenes.
  74. var scenes = data.scenes.map(function(data) {
  75. var urlPrefix = "tiles";
  76. var source = Marzipano.ImageUrlSource.fromString(
  77. urlPrefix + "/" + data.id + "/{z}/{f}/{y}/{x}.jpg",
  78. { cubeMapPreviewUrl: urlPrefix + "/" + data.id + "/preview.jpg" });
  79. var geometry = new Marzipano.CubeGeometry(data.levels);
  80.  
  81. var limiter = Marzipano.RectilinearView.limit.traditional(data.faceSize, 100*Math.PI/180, 120*Math.PI/180);
  82. var view = new Marzipano.RectilinearView(data.initialViewParameters, limiter);
  83.  
  84. var scene = viewer.createScene({
  85. source: source,
  86. geometry: geometry,
  87. view: view,
  88. pinFirstLevel: true
  89. });
  90.  
  91. // Create link hotspots.
  92. data.linkHotspots.forEach(function(hotspot) {
  93. var element = createLinkHotspotElement(hotspot);
  94. scene.hotspotContainer().createHotspot(element, { yaw: hotspot.yaw, pitch: hotspot.pitch });
  95. });
  96.  
  97. // Create info hotspots.
  98. data.infoHotspots.forEach(function(hotspot) {
  99. var element = createInfoHotspotElement(hotspot);
  100. scene.hotspotContainer().createHotspot(element, { yaw: hotspot.yaw, pitch: hotspot.pitch });
  101. });
  102.  
  103. return {
  104. data: data,
  105. scene: scene,
  106. view: view
  107. };
  108. });
  109.  
  110. // Set up autorotate, if enabled.
  111. var autorotate = Marzipano.autorotate({
  112. yawSpeed: 0.03,
  113. targetPitch: 0,
  114. targetFov: Math.PI/2
  115. });
  116. if (data.settings.autorotateEnabled) {
  117. autorotateToggleElement.classList.add('enabled');
  118. }
  119.  
  120. // Set handler for autorotate toggle.
  121. autorotateToggleElement.addEventListener('click', toggleAutorotate);
  122.  
  123. // Set up fullscreen mode, if supported.
  124. if (screenfull.enabled && data.settings.fullscreenButton) {
  125. document.body.classList.add('fullscreen-enabled');
  126. fullscreenToggleElement.addEventListener('click', function() {
  127. screenfull.toggle();
  128. });
  129. screenfull.on('change', function() {
  130. if (screenfull.isFullscreen) {
  131. fullscreenToggleElement.classList.add('enabled');
  132. } else {
  133. fullscreenToggleElement.classList.remove('enabled');
  134. }
  135. });
  136. } else {
  137. document.body.classList.add('fullscreen-disabled');
  138. }
  139.  
  140. // Set handler for scene list toggle.
  141. sceneListToggleElement.addEventListener('click', toggleSceneList);
  142.  
  143. // Start with the scene list open on desktop.
  144. if (!document.body.classList.contains('mobile')) {
  145. showSceneList();
  146. }
  147.  
  148. // Set handler for scene switch.
  149. scenes.forEach(function(scene) {
  150. var el = document.querySelector('#sceneList .scene[data-id="' + scene.data.id + '"]');
  151. el.addEventListener('click', function() {
  152. switchScene(scene);
  153. // On mobile, hide scene list after selecting a scene.
  154. if (document.body.classList.contains('mobile')) {
  155. hideSceneList();
  156. }
  157. });
  158. });
  159.  
  160. // DOM elements for view controls.
  161. var viewUpElement = document.querySelector('#viewUp');
  162. var viewDownElement = document.querySelector('#viewDown');
  163. var viewLeftElement = document.querySelector('#viewLeft');
  164. var viewRightElement = document.querySelector('#viewRight');
  165. var viewInElement = document.querySelector('#viewIn');
  166. var viewOutElement = document.querySelector('#viewOut');
  167.  
  168. // Dynamic parameters for controls.
  169. var velocity = 0.7;
  170. var friction = 3;
  171.  
  172. // Associate view controls with elements.
  173. var controls = viewer.controls();
  174. controls.registerMethod('upElement', new Marzipano.ElementPressControlMethod(viewUpElement, 'y', -velocity, friction), true);
  175. controls.registerMethod('downElement', new Marzipano.ElementPressControlMethod(viewDownElement, 'y', velocity, friction), true);
  176. controls.registerMethod('leftElement', new Marzipano.ElementPressControlMethod(viewLeftElement, 'x', -velocity, friction), true);
  177. controls.registerMethod('rightElement', new Marzipano.ElementPressControlMethod(viewRightElement, 'x', velocity, friction), true);
  178. controls.registerMethod('inElement', new Marzipano.ElementPressControlMethod(viewInElement, 'zoom', -velocity, friction), true);
  179. controls.registerMethod('outElement', new Marzipano.ElementPressControlMethod(viewOutElement, 'zoom', velocity, friction), true);
  180.  
  181. function sanitize(s) {
  182. return s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;');
  183. }
  184.  
  185. function switchScene(scene) {
  186. stopAutorotate();
  187. scene.view.setParameters(scene.data.initialViewParameters);
  188. scene.scene.switchTo();
  189. startAutorotate();
  190. updateSceneName(scene);
  191. updateSceneList(scene);
  192. }
  193.  
  194. function updateSceneName(scene) {
  195. sceneNameElement.innerHTML = sanitize(scene.data.name);
  196. }
  197.  
  198. function updateSceneList(scene) {
  199. for (var i = 0; i < sceneElements.length; i++) {
  200. var el = sceneElements[i];
  201. if (el.getAttribute('data-id') === scene.data.id) {
  202. el.classList.add('current');
  203. } else {
  204. el.classList.remove('current');
  205. }
  206. }
  207. }
  208.  
  209. function showSceneList() {
  210. sceneListElement.classList.add('enabled');
  211. sceneListToggleElement.classList.add('enabled');
  212. }
  213.  
  214. function hideSceneList() {
  215. sceneListElement.classList.remove('enabled');
  216. sceneListToggleElement.classList.remove('enabled');
  217. }
  218.  
  219. function toggleSceneList() {
  220. sceneListElement.classList.toggle('enabled');
  221. sceneListToggleElement.classList.toggle('enabled');
  222. }
  223.  
  224. function startAutorotate() {
  225. if (!autorotateToggleElement.classList.contains('enabled')) {
  226. return;
  227. }
  228. viewer.startMovement(autorotate);
  229. viewer.setIdleMovement(3000, autorotate);
  230. }
  231.  
  232. function stopAutorotate() {
  233. viewer.stopMovement();
  234. viewer.setIdleMovement(Infinity);
  235. }
  236.  
  237. function toggleAutorotate() {
  238. if (autorotateToggleElement.classList.contains('enabled')) {
  239. autorotateToggleElement.classList.remove('enabled');
  240. stopAutorotate();
  241. } else {
  242. autorotateToggleElement.classList.add('enabled');
  243. startAutorotate();
  244. }
  245. }
  246.  
  247. function createLinkHotspotElement(hotspot) {
  248.  
  249. // Create wrapper element to hold icon and tooltip.
  250. var wrapper = document.createElement('div');
  251. wrapper.classList.add('hotspot');
  252. wrapper.classList.add('link-hotspot');
  253.  
  254. // Create image element.
  255. var icon = document.createElement('img');
  256. icon.src = 'img/link.png';
  257. icon.classList.add('link-hotspot-icon');
  258.  
  259. // Set rotation transform.
  260. var transformProperties = [ '-ms-transform', '-webkit-transform', 'transform' ];
  261. for (var i = 0; i < transformProperties.length; i++) {
  262. var property = transformProperties[i];
  263. icon.style[property] = 'rotate(' + hotspot.rotation + 'rad)';
  264. }
  265.  
  266. // Add click event handler.
  267. wrapper.addEventListener('click', function() {
  268. switchScene(findSceneById(hotspot.target));
  269. });
  270.  
  271. // Prevent touch and scroll events from reaching the parent element.
  272. // This prevents the view control logic from interfering with the hotspot.
  273. stopTouchAndScrollEventPropagation(wrapper);
  274.  
  275. // Create tooltip element.
  276. var tooltip = document.createElement('div');
  277. tooltip.classList.add('hotspot-tooltip');
  278. tooltip.classList.add('link-hotspot-tooltip');
  279. tooltip.innerHTML = findSceneDataById(hotspot.target).name;
  280.  
  281. wrapper.appendChild(icon);
  282. wrapper.appendChild(tooltip);
  283.  
  284. return wrapper;
  285. }
  286.  
  287. function createInfoHotspotElement(hotspot) {
  288.  
  289. // Create wrapper element to hold icon and tooltip.
  290. var wrapper = document.createElement('div');
  291. wrapper.classList.add('hotspot');
  292. wrapper.classList.add('info-hotspot');
  293.  
  294. // Create hotspot/tooltip header.
  295. var header = document.createElement('div');
  296. header.classList.add('info-hotspot-header');
  297.  
  298. // Create image element.
  299. var iconWrapper = document.createElement('div');
  300. iconWrapper.classList.add('info-hotspot-icon-wrapper');
  301. var icon = document.createElement('img');
  302. icon.src = 'img/info.png';
  303. icon.classList.add('info-hotspot-icon');
  304. iconWrapper.appendChild(icon);
  305.  
  306. // Create title element.
  307. var titleWrapper = document.createElement('div');
  308. titleWrapper.classList.add('info-hotspot-title-wrapper');
  309. var title = document.createElement('div');
  310. title.classList.add('info-hotspot-title');
  311. title.innerHTML = hotspot.title;
  312. titleWrapper.appendChild(title);
  313.  
  314. // Create close element.
  315. var closeWrapper = document.createElement('div');
  316. closeWrapper.classList.add('info-hotspot-close-wrapper');
  317. var closeIcon = document.createElement('img');
  318. closeIcon.src = 'img/close.png';
  319. closeIcon.classList.add('info-hotspot-close-icon');
  320. closeWrapper.appendChild(closeIcon);
  321.  
  322. // Construct header element.
  323. header.appendChild(iconWrapper);
  324. header.appendChild(titleWrapper);
  325. header.appendChild(closeWrapper);
  326.  
  327. // Create text element.
  328. var text = document.createElement('div');
  329. text.classList.add('info-hotspot-text');
  330. text.innerHTML = hotspot.text;
  331.  
  332. // Place header and text into wrapper element.
  333. wrapper.appendChild(header);
  334. wrapper.appendChild(text);
  335.  
  336. // Create a modal for the hotspot content to appear on mobile mode.
  337. var modal = document.createElement('div');
  338. modal.innerHTML = wrapper.innerHTML;
  339. modal.classList.add('info-hotspot-modal');
  340. document.body.appendChild(modal);
  341.  
  342. var toggle = function() {
  343. wrapper.classList.toggle('visible');
  344. modal.classList.toggle('visible');
  345. };
  346.  
  347. // Show content when hotspot is clicked.
  348. wrapper.querySelector('.info-hotspot-header').addEventListener('click', toggle);
  349.  
  350. // Hide content when close icon is clicked.
  351. modal.querySelector('.info-hotspot-close-wrapper').addEventListener('click', toggle);
  352.  
  353. // Prevent touch and scroll events from reaching the parent element.
  354. // This prevents the view control logic from interfering with the hotspot.
  355. stopTouchAndScrollEventPropagation(wrapper);
  356.  
  357. return wrapper;
  358. }
  359.  
  360. // Prevent touch and scroll events from reaching the parent element.
  361. function stopTouchAndScrollEventPropagation(element, eventList) {
  362. var eventList = [ 'touchstart', 'touchmove', 'touchend', 'touchcancel',
  363. 'wheel', 'mousewheel' ];
  364. for (var i = 0; i < eventList.length; i++) {
  365. element.addEventListener(eventList[i], function(event) {
  366. event.stopPropagation();
  367. });
  368. }
  369. }
  370.  
  371. function findSceneById(id) {
  372. for (var i = 0; i < scenes.length; i++) {
  373. if (scenes[i].data.id === id) {
  374. return scenes[i];
  375. }
  376. }
  377. return null;
  378. }
  379.  
  380. function findSceneDataById(id) {
  381. for (var i = 0; i < data.scenes.length; i++) {
  382. if (data.scenes[i].id === id) {
  383. return data.scenes[i];
  384. }
  385. }
  386. return null;
  387. }
  388.  
  389. // Display the initial scene.
  390. switchScene(scenes[0]);
  391.  
  392. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement