PageSourceSearch

https://thulhagiri.com.mv/wp-content/themes/thulhagiri/assets/js/360.js

js thulhagiri.com.mv collected 2026-10-03 22:19:06 UTC 13,335 bytes, 396 lines download raw bytes

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      scrollZoom: false
68    }
69  };
70
71  // Initialize viewer.
72  var viewer = new Marzipano.Viewer(panoElement, viewerOpts);
73
74  // Create scenes.
75  var scenes = data.scenes.map(function(data) {
76    var urlPrefix = template_url+"/assets/img/tiles";
77    var source = Marzipano.ImageUrlSource.fromString(
78      urlPrefix + "/" + data.id + "/{z}/{f}/{y}/{x}.jpg",
79      { cubeMapPreviewUrl: urlPrefix + "/" + data.id + "/preview.jpg" });
80    var geometry = new Marzipano.CubeGeometry(data.levels);
81
82    var limiter = Marzipano.RectilinearView.limit.traditional(data.faceSize, 100*Math.PI/180, 120*Math.PI/180);
83    var view = new Marzipano.RectilinearView(data.initialViewParameters, limiter);
84
85    var scene = viewer.createScene({
86      source: source,
87      geometry: geometry,
88      view: view,
89      pinFirstLevel: true
90    });
91
92    // Create link hotspots.
93    data.linkHotspots.forEach(function(hotspot) {
94      var element = createLinkHotspotElement(hotspot);
95      scene.hotspotContainer().createHotspot(element, { yaw: hotspot.yaw, pitch: hotspot.pitch });
96    });
97
98    // Create info hotspots.
99    data.infoHotspots.forEach(function(hotspot) {
100      var element = createInfoHotspotElement(hotspot);
101      scene.hotspotContainer().createHotspot(element, { yaw: hotspot.yaw, pitch: hotspot.pitch });
102    });
103
104    return {
105      data: data,
106      scene: scene,
107      view: view
108    };
109  });
110
111  // Set up autorotate, if enabled.
112  var autorotate = Marzipano.autorotate({
113    yawSpeed: 0.03,
114    // yawSpeed: 0,
115    targetPitch: 0,
116    targetFov: Math.PI/2
117  });
118
119  // data.settings.autorotateEnabled = false;
120  if (data.settings.autorotateEnabled) {
121    autorotateToggleElement.classList.add('enabled');
122  }
123
124  // Set handler for autorotate toggle.
125  autorotateToggleElement.addEventListener('click', toggleAutorotate);
126
127  // Set up fullscreen mode, if supported.
128  if (screenfull.enabled && data.settings.fullscreenButton) {
129    document.body.classList.add('fullscreen-enabled');
130    fullscreenToggleElement.addEventListener('click', function() {
131      screenfull.toggle();
132    });
133    screenfull.on('change', function() {
134      if (screenfull.isFullscreen) {
135        fullscreenToggleElement.classList.add('enabled');
136      } else {
137        fullscreenToggleElement.classList.remove('enabled');
138      }
139    });
140  } else {
141    document.body.classList.add('fullscreen-disabled');
142  }
143
144  // Set handler for scene list toggle.
145  sceneListToggleElement.addEventListener('click', toggleSceneList);
146
147  // Start with the scene list open on desktop.
148  if (!document.body.classList.contains('mobile')) {
149    showSceneList();
150  }
151
152  // Set handler for scene switch.
153  scenes.forEach(function(scene) {
154    var el = document.querySelector('#sceneList .scene[data-id="' + scene.data.id + '"]');
155    el.addEventListener('click', function() {
156      switchScene(scene);
157      // On mobile, hide scene list after selecting a scene.
158      if (document.body.classList.contains('mobile')) {
159        hideSceneList();
160      }
161    });
162  });
163
164  // DOM elements for view controls.
165  var viewUpElement = document.querySelector('#viewUp');
166  var viewDownElement = document.querySelector('#viewDown');
167  var viewLeftElement = document.querySelector('#viewLeft');
168  var viewRightElement = document.querySelector('#viewRight');
169  var viewInElement = document.querySelector('#viewIn');
170  var viewOutElement = document.querySelector('#viewOut');
171
172  // Dynamic parameters for controls.
173  var velocity = 0.7;
174  var friction = 3;
175
176  // Associate view controls with elements.
177  var controls = viewer.controls();
178  controls.registerMethod('upElement',    new Marzipano.ElementPressControlMethod(viewUpElement,     'y', -velocity, friction), true);
179  controls.registerMethod('downElement',  new Marzipano.ElementPressControlMethod(viewDownElement,   'y',  velocity, friction), true);
180  controls.registerMethod('leftElement',  new Marzipano.ElementPressControlMethod(viewLeftElement,   'x', -velocity, friction), true);
181  controls.registerMethod('rightElement', new Marzipano.ElementPressControlMethod(viewRightElement,  'x',  velocity, friction), true);
182  controls.registerMethod('inElement',    new Marzipano.ElementPressControlMethod(viewInElement,  'zoom', -velocity, friction), true);
183  controls.registerMethod('outElement',   new Marzipano.ElementPressControlMethod(viewOutElement, 'zoom',  velocity, friction), true);
184
185  function sanitize(s) {
186    return s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;');
187  }
188
189  function switchScene(scene) {
190    stopAutorotate();
191    scene.view.setParameters(scene.data.initialViewParameters);
192    scene.scene.switchTo();
193    startAutorotate();
194    updateSceneName(scene);
195    updateSceneList(scene);
196  }
197
198  function updateSceneName(scene) {
199    sceneNameElement.innerHTML = sanitize(scene.data.name);
200  }
201
202  function updateSceneList(scene) {
203    for (var i = 0; i < sceneElements.length; i++) {
204      var el = sceneElements[i];
205      if (el.getAttribute('data-id') === scene.data.id) {
206        el.classList.add('current');
207      } else {
208        el.classList.remove('current');
209      }
210    }
211  }
212
213  function showSceneList() {
214    sceneListElement.classList.add('enabled');
215    sceneListToggleElement.classList.add('enabled');
216  }
217
218  function hideSceneList() {
219    sceneListElement.classList.remove('enabled');
220    sceneListToggleElement.classList.remove('enabled');
221  }
222
223  function toggleSceneList() {
224    sceneListElement.classList.toggle('enabled');
225    sceneListToggleElement.classList.toggle('enabled');
226  }
227
228  function startAutorotate() {
229    if (!autorotateToggleElement.classList.contains('enabled')) {
230      return;
231    }
232    viewer.startMovement(autorotate);
233    viewer.setIdleMovement(3000, autorotate);
234  }
235
236  function stopAutorotate() {
237    viewer.stopMovement();
238    viewer.setIdleMovement(Infinity);
239  }
240
241  function toggleAutorotate() {
242    if (autorotateToggleElement.classList.contains('enabled')) {
243      autorotateToggleElement.classList.remove('enabled');
244      stopAutorotate();
245    } else {
246      autorotateToggleElement.classList.add('enabled');
247      startAutorotate();
248    }
249  }
250
251  function createLinkHotspotElement(hotspot) {
252
253    // Create wrapper element to hold icon and tooltip.
254    var wrapper = document.createElement('div');
255    wrapper.classList.add('hotspot');
256    wrapper.classList.add('link-hotspot');
257
258    // Create image element.
259    var icon = document.createElement('img');
260    icon.src = template_url+'/assets/img/360/link.png';
261    icon.classList.add('link-hotspot-icon');
262
263    // Set rotation transform.
264    var transformProperties = [ '-ms-transform', '-webkit-transform', 'transform' ];
265    for (var i = 0; i < transformProperties.length; i++) {
266      var property = transformProperties[i];
267      icon.style[property] = 'rotate(' + hotspot.rotation + 'rad)';
268    }
269
270    // Add click event handler.
271    wrapper.addEventListener('click', function() {
272      switchScene(findSceneById(hotspot.target));
273    });
274
275    // Prevent touch and scroll events from reaching the parent element.
276    // This prevents the view control logic from interfering with the hotspot.
277    stopTouchAndScrollEventPropagation(wrapper);
278
279    // Create tooltip element.
280    var tooltip = document.createElement('div');
281    tooltip.classList.add('hotspot-tooltip');
282    tooltip.classList.add('link-hotspot-tooltip');
283    tooltip.innerHTML = findSceneDataById(hotspot.target).name;
284
285    wrapper.appendChild(icon);
286    wrapper.appendChild(tooltip);
287
288    return wrapper;
289  }
290
291  function createInfoHotspotElement(hotspot) {
292
293    // Create wrapper element to hold icon and tooltip.
294    var wrapper = document.createElement('div');
295    wrapper.classList.add('hotspot');
296    wrapper.classList.add('info-hotspot');
297
298    // Create hotspot/tooltip header.
299    var header = document.createElement('div');
300    header.classList.add('info-hotspot-header');
301
302    // Create image element.
303    var iconWrapper = document.createElement('div');
304    iconWrapper.classList.add('info-hotspot-icon-wrapper');
305    var icon = document.createElement('img');
306    icon.src = template_url+'/assets/img/360/info.png';
307    icon.classList.add('info-hotspot-icon');
308    iconWrapper.appendChild(icon);
309
310    // Create title element.
311    var titleWrapper = document.createElement('div');
312    titleWrapper.classList.add('info-hotspot-title-wrapper');
313    var title = document.createElement('div');
314    title.classList.add('info-hotspot-title');
315    title.innerHTML = hotspot.title;
316    titleWrapper.appendChild(title);
317
318    // Create close element.
319    var closeWrapper = document.createElement('div');
320    closeWrapper.classList.add('info-hotspot-close-wrapper');
321    var closeIcon = document.createElement('img');
322    closeIcon.src = template_url+'/assets/img/360/close.png';
323    closeIcon.classList.add('info-hotspot-close-icon');
324    closeWrapper.appendChild(closeIcon);
325
326    // Construct header element.
327    header.appendChild(iconWrapper);
328    header.appendChild(titleWrapper);
329    header.appendChild(closeWrapper);
330
331    // Create text element.
332    var text = document.createElement('div');
333    text.classList.add('info-hotspot-text');
334    text.innerHTML = hotspot.text;
335
336    // Place header and text into wrapper element.
337    wrapper.appendChild(header);
338    wrapper.appendChild(text);
339
340    // Create a modal for the hotspot content to appear on mobile mode.
341    var modal = document.createElement('div');
342    modal.innerHTML = wrapper.innerHTML;
343    modal.classList.add('info-hotspot-modal');
344    document.body.appendChild(modal);
345
346    var toggle = function() {
347      wrapper.classList.toggle('visible');
348      modal.classList.toggle('visible');
349    };
350
351    // Show content when hotspot is clicked.
352    wrapper.querySelector('.info-hotspot-header').addEventListener('click', toggle);
353
354    // Hide content when close icon is clicked.
355    modal.querySelector('.info-hotspot-close-wrapper').addEventListener('click', toggle);
356
357    // Prevent touch and scroll events from reaching the parent element.
358    // This prevents the view control logic from interfering with the hotspot.
359    stopTouchAndScrollEventPropagation(wrapper);
360
361    return wrapper;
362  }
363
364  // Prevent touch and scroll events from reaching the parent element.
365  function stopTouchAndScrollEventPropagation(element, eventList) {
366    var eventList = [ 'touchstart', 'touchmove', 'touchend', 'touchcancel',
367                      'wheel', 'mousewheel' ];
368    for (var i = 0; i < eventList.length; i++) {
369      element.addEventListener(eventList[i], function(event) {
370        event.stopPropagation();
371      });
372    }
373  }
374
375  function findSceneById(id) {
376    for (var i = 0; i < scenes.length; i++) {
377      if (scenes[i].data.id === id) {
378        return scenes[i];
379      }
380    }
381    return null;
382  }
383
384  function findSceneDataById(id) {
385    for (var i = 0; i < data.scenes.length; i++) {
386      if (data.scenes[i].id === id) {
387        return data.scenes[i];
388      }
389    }
390    return null;
391  }
392
393  // Display the initial scene.
394  switchScene(scenes[0]);
395
396})();

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.