PageSourceSearch

https://loopdive.com/globe/home/loopdive-globe-element.js?hash=aba…0beeb4e60fbf3c1bf4316666119b915e226073f91ad

js loopdive.com collected 2026-10-06 18:56:54 UTC 3,591 bytes, 170 lines download raw bytes

1import { createGlobeScene } from './globe-scene.js';
2
3const TAG_NAME = 'loopdive-globe';
4
5const template = document.createElement('template');
6template.innerHTML = `
7  <style>
8    :host {
9      position: absolute;
10      inset: 0;
11      display: block;
12      pointer-events: none;
13      touch-action: none;
14      -webkit-touch-callout: none;
15      -webkit-user-select: none;
16      user-select: none;
17    }
18
19    .globe-host {
20      position: absolute;
21      inset: 0;
22      overflow: hidden;
23      opacity: 0;
24      pointer-events: auto;
25      overscroll-behavior: none;
26      touch-action: none;
27      -webkit-touch-callout: none;
28      -webkit-user-select: none;
29      user-select: none;
30      transition: opacity 420ms ease;
31    }
32
33    .globe-host.is-ready {
34      opacity: 1;
35    }
36
37    :host([interactive='false']) .globe-host {
38      pointer-events: none;
39    }
40
41    .globe-host canvas {
42      display: block;
43      width: 100%;
44      height: 100%;
45      touch-action: none;
46      -webkit-touch-callout: none;
47      -webkit-user-select: none;
48      user-select: none;
49    }
50
51    .globe-labels {
52      position: absolute;
53      inset: 0;
54      pointer-events: none;
55      opacity: 0;
56      transition: opacity 180ms ease;
57    }
58
59    .globe-labels.is-ready {
60      opacity: 1;
61    }
62  </style>
63  <div class="globe-host" part="host"></div>
64  <div class="globe-labels" part="labels"></div>
65`;
66
67class LoopdiveGlobeElement extends HTMLElement {
68  constructor() {
69    super();
70    this._scene = null;
71    this._revealPrepared = false;
72    this.attachShadow({ mode: 'open' });
73    this.shadowRoot.appendChild(template.content.cloneNode(true));
74    this._hostNode = this.shadowRoot.querySelector('.globe-host');
75    this._labelNode = this.shadowRoot.querySelector('.globe-labels');
76  }
77
78  disconnectedCallback() {
79    this.destroy();
80  }
81
82  mountScene(options) {
83    this.destroy();
84    this._scene = createGlobeScene({
85      ...options,
86      host: this._hostNode,
87      labelHost: this._labelNode,
88    });
89    return this;
90  }
91
92  reveal() {
93    requestAnimationFrame(() => {
94      requestAnimationFrame(() => {
95        this._hostNode.classList.add('is-ready');
96        this._labelNode.classList.add('is-ready');
97      });
98    });
99  }
100
101  prepareReveal() {
102    this.resetReveal();
103    this._revealPrepared = true;
104  }
105
106  resetReveal() {
107    this._revealPrepared = false;
108    this._hostNode.classList.remove('is-ready');
109    this._labelNode.classList.remove('is-ready');
110  }
111
112  goTo(entry) {
113    this._scene?.goTo(entry);
114  }
115
116  buildWorld(world) {
117    this._scene?.buildWorld(world);
118  }
119
120  hydrateWorldContours(world) {
121    return this._scene?.hydrateWorldContours(world) || Promise.resolve(false);
122  }
123
124  applyProps() {
125    this._scene?.applyProps();
126  }
127
128  invalidate() {
129    this._scene?.invalidate();
130  }
131
132  setAutoRotateEnabled(active) {
133    this._scene?.setAutoRotateEnabled(active);
134  }
135
136  setCapitalLookup(lookup) {
137    this._scene?.setCapitalLookup(lookup);
138  }
139
140  setStreetMapModeActive(active) {
141    this._scene?.setStreetMapModeActive(active);
142  }
143
144  setViewState(view) {
145    this._scene?.setViewState(view);
146  }
147
148  setGlobeOffsetX(offsetX) {
149    this._scene?.setGlobeOffsetX(offsetX);
150  }
151
152  locateUser(location) {
153    this._scene?.locateUser(location);
154  }
155
156  destroy() {
157    if (this._scene) {
158      this._scene.destroy();
159      this._scene = null;
160    }
161    this.resetReveal();
162  }
163}
164
165export const defineLoopdiveGlobeElement = () => {
166  if (!customElements.get(TAG_NAME)) {
167    customElements.define(TAG_NAME, LoopdiveGlobeElement);
168  }
169  return customElements.get(TAG_NAME);
170};

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.