storysplat-viewer 0.1.21 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +807 -61
- package/dist/esm/index.js.map +1 -1
- package/dist/types/core/cameraManager.d.ts +1 -0
- package/dist/types/features/customScriptManager.d.ts +34 -0
- package/dist/types/features/htmlMeshManager.d.ts +23 -0
- package/dist/types/features/navigationManager.d.ts +4 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/types/dataTypes.d.ts +1 -0
- package/dist/types/ui/templateManager.d.ts +121 -0
- package/dist/types/viewer.d.ts +8 -0
- package/package.json +5 -2
package/dist/esm/index.js
CHANGED
|
@@ -75012,7 +75012,7 @@ class CameraManager {
|
|
|
75012
75012
|
}
|
|
75013
75013
|
}
|
|
75014
75014
|
setCameraMode(mode, immediate = false) {
|
|
75015
|
-
var _a, _b, _c, _d, _e, _f;
|
|
75015
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
75016
75016
|
if (!this._camera)
|
|
75017
75017
|
return;
|
|
75018
75018
|
const allowedModes = (_b = (_a = this._viewerOptions) === null || _a === void 0 ? void 0 : _a.allowedCameraModes) !== null && _b !== void 0 ? _b : ['explore', 'walk', 'tour', 'hybrid'];
|
|
@@ -75062,7 +75062,8 @@ class CameraManager {
|
|
|
75062
75062
|
// Trigger callback and update UI
|
|
75063
75063
|
if (oldMode !== mode) {
|
|
75064
75064
|
(_e = (_d = this._viewerOptions) === null || _d === void 0 ? void 0 : _d.onCameraModeChanged) === null || _e === void 0 ? void 0 : _e.call(_d, mode);
|
|
75065
|
-
(_f = this.
|
|
75065
|
+
(_f = this.onCameraModeChange) === null || _f === void 0 ? void 0 : _f.call(this, mode); // Call the new callback
|
|
75066
|
+
(_g = this._analyticsManager) === null || _g === void 0 ? void 0 : _g.trackCameraModeChange(oldMode, mode); // Track event
|
|
75066
75067
|
this._updateUIManager(); // Notify UI Manager of the change
|
|
75067
75068
|
}
|
|
75068
75069
|
}
|
|
@@ -108343,7 +108344,7 @@ class NavigationManager {
|
|
|
108343
108344
|
this.onProgressUpdate(scrollPercentage / 100, currentWaypointIndex);
|
|
108344
108345
|
}
|
|
108345
108346
|
// --- Tour/Hybrid Mode Logic ---
|
|
108346
|
-
if ((this.currentMode === 'hybrid'
|
|
108347
|
+
if ((this.currentMode === 'hybrid') || (this.currentMode === 'tour' && !this.userControl)) {
|
|
108347
108348
|
this.updateCameraPositionFromPath();
|
|
108348
108349
|
}
|
|
108349
108350
|
// Update UI for tour/hybrid modes
|
|
@@ -108353,8 +108354,8 @@ class NavigationManager {
|
|
|
108353
108354
|
}
|
|
108354
108355
|
// Check waypoint triggers
|
|
108355
108356
|
this.updateActiveWaypoint();
|
|
108356
|
-
// --- Explore/Walk Mode Logic ---
|
|
108357
|
-
if (this.currentMode === 'explore' || this.currentMode === 'walk') {
|
|
108357
|
+
// --- Explore/Walk/Hybrid Mode Logic ---
|
|
108358
|
+
if (this.currentMode === 'explore' || this.currentMode === 'walk' || (this.currentMode === 'hybrid' && this.userControl)) {
|
|
108358
108359
|
const deltaTime = this.scene.getEngine().getDeltaTime() / 1000.0;
|
|
108359
108360
|
this.updateExploreWalkMovement(deltaTime);
|
|
108360
108361
|
}
|
|
@@ -161032,6 +161033,13 @@ class SplatSwapManager {
|
|
|
161032
161033
|
}
|
|
161033
161034
|
}
|
|
161034
161035
|
|
|
161036
|
+
var UIType;
|
|
161037
|
+
(function (UIType) {
|
|
161038
|
+
UIType["Standard"] = "standard";
|
|
161039
|
+
UIType["Minimal"] = "minimal";
|
|
161040
|
+
UIType["Pro"] = "pro";
|
|
161041
|
+
})(UIType || (UIType = {}));
|
|
161042
|
+
|
|
161035
161043
|
/**
|
|
161036
161044
|
* Manages the preloader UI element.
|
|
161037
161045
|
*/
|
|
@@ -161600,6 +161608,775 @@ class MuteButtonUI {
|
|
|
161600
161608
|
}
|
|
161601
161609
|
}
|
|
161602
161610
|
|
|
161611
|
+
/**
|
|
161612
|
+
* Manages UI layout templates for the StorySplat viewer
|
|
161613
|
+
* Renders different UI layouts based on the uiType from scene JSON
|
|
161614
|
+
*/
|
|
161615
|
+
class TemplateManager {
|
|
161616
|
+
constructor(targetElement, options) {
|
|
161617
|
+
var _a;
|
|
161618
|
+
// UI Components
|
|
161619
|
+
this.preloaderUI = null;
|
|
161620
|
+
this.startButtonUI = null;
|
|
161621
|
+
this.watermarkUI = null;
|
|
161622
|
+
this.helpPanelUI = null;
|
|
161623
|
+
this.muteButtonUI = null;
|
|
161624
|
+
// UI Elements for templates
|
|
161625
|
+
this.controlsContainer = null;
|
|
161626
|
+
this.modeToggleContainer = null;
|
|
161627
|
+
this.progressContainer = null;
|
|
161628
|
+
this.navigationContainer = null;
|
|
161629
|
+
this.targetElement = targetElement;
|
|
161630
|
+
this.options = options;
|
|
161631
|
+
this.uiType = ((_a = options.uiOptions) === null || _a === void 0 ? void 0 : _a.uiType) || 'standard';
|
|
161632
|
+
console.log(`TemplateManager: Initializing with uiType: ${this.uiType}`);
|
|
161633
|
+
}
|
|
161634
|
+
/**
|
|
161635
|
+
* Initialize UI components based on template type
|
|
161636
|
+
*/
|
|
161637
|
+
async initializeUI(audioManager, navigationManager, cameraManager, onStartExperience) {
|
|
161638
|
+
// Create base UI components that are common to all templates
|
|
161639
|
+
this.createBaseComponents(audioManager, onStartExperience);
|
|
161640
|
+
// Apply template-specific layout
|
|
161641
|
+
switch (this.uiType) {
|
|
161642
|
+
case UIType.Minimal:
|
|
161643
|
+
case 'minimal':
|
|
161644
|
+
await this.applyMinimalTemplate(navigationManager, cameraManager);
|
|
161645
|
+
break;
|
|
161646
|
+
case UIType.Pro:
|
|
161647
|
+
case 'pro':
|
|
161648
|
+
await this.applyProTemplate(navigationManager, cameraManager);
|
|
161649
|
+
break;
|
|
161650
|
+
case UIType.Standard:
|
|
161651
|
+
case 'standard':
|
|
161652
|
+
default:
|
|
161653
|
+
await this.applyStandardTemplate(navigationManager, cameraManager);
|
|
161654
|
+
break;
|
|
161655
|
+
}
|
|
161656
|
+
}
|
|
161657
|
+
/**
|
|
161658
|
+
* Create base UI components common to all templates
|
|
161659
|
+
*/
|
|
161660
|
+
createBaseComponents(audioManager, onStartExperience) {
|
|
161661
|
+
var _a, _b, _c, _d, _e, _f;
|
|
161662
|
+
// Preloader (always created)
|
|
161663
|
+
const defaultPreloaderConfig = {
|
|
161664
|
+
enabled: true,
|
|
161665
|
+
imageUrl: 'https://firebasestorage.googleapis.com/v0/b/story-splat.firebasestorage.app/o/public%2Fimages%2FStorySplat.webp?alt=media&token=953e8ab3-1865-4ac1-a98d-b548b7066bda',
|
|
161666
|
+
lottieUrl: 'https://firebasestorage.googleapis.com/v0/b/story-splat.firebasestorage.app/o/public%2Flotties%2FstorySplatLottie.json?alt=media&token=d7edc19d-9cb8-4c20-96f3-d23b6d1272b4',
|
|
161667
|
+
uiColor: ((_a = this.options) === null || _a === void 0 ? void 0 : _a.uiColor) || '#4CAF50'
|
|
161668
|
+
};
|
|
161669
|
+
const preloaderConfig = Object.assign(Object.assign({}, defaultPreloaderConfig), (_b = this.options) === null || _b === void 0 ? void 0 : _b.preloaderConfig);
|
|
161670
|
+
this.preloaderUI = new PreloaderUI(this.targetElement, preloaderConfig);
|
|
161671
|
+
this.preloaderUI.create();
|
|
161672
|
+
// Start Button (conditional)
|
|
161673
|
+
if ((_c = this.options) === null || _c === void 0 ? void 0 : _c.showStartExperience) {
|
|
161674
|
+
this.startButtonUI = new StartButtonUI(this.targetElement, this.options, onStartExperience || (() => { }));
|
|
161675
|
+
this.startButtonUI.create();
|
|
161676
|
+
}
|
|
161677
|
+
// Watermark (conditional)
|
|
161678
|
+
this.watermarkUI = new WatermarkUI(this.targetElement, this.options);
|
|
161679
|
+
this.watermarkUI.create();
|
|
161680
|
+
// Help Panel (conditional)
|
|
161681
|
+
if ((_d = this.options) === null || _d === void 0 ? void 0 : _d.showHelpButton) {
|
|
161682
|
+
this.helpPanelUI = new HelpPanelUI(this.targetElement, this.options);
|
|
161683
|
+
this.helpPanelUI.create();
|
|
161684
|
+
}
|
|
161685
|
+
// Mute Button (conditional)
|
|
161686
|
+
if (((_f = (_e = this.options) === null || _e === void 0 ? void 0 : _e.audio) === null || _f === void 0 ? void 0 : _f.showMuteButton) && audioManager) {
|
|
161687
|
+
this.muteButtonUI = new MuteButtonUI(this.targetElement, this.options, audioManager);
|
|
161688
|
+
this.muteButtonUI.create();
|
|
161689
|
+
}
|
|
161690
|
+
}
|
|
161691
|
+
/**
|
|
161692
|
+
* Apply Minimal template layout (overlay controls)
|
|
161693
|
+
*/
|
|
161694
|
+
async applyMinimalTemplate(navigationManager, cameraManager) {
|
|
161695
|
+
console.log('TemplateManager: Applying Minimal template');
|
|
161696
|
+
// Add minimal template class
|
|
161697
|
+
this.targetElement.classList.add('template-minimal');
|
|
161698
|
+
// Create minimal controls container (overlay style)
|
|
161699
|
+
if (this.options.showProgressBar && navigationManager) {
|
|
161700
|
+
this.createMinimalControls(navigationManager);
|
|
161701
|
+
}
|
|
161702
|
+
// Create mode toggle if multiple modes allowed
|
|
161703
|
+
if (this.shouldShowModeToggle() && cameraManager) {
|
|
161704
|
+
this.createMinimalModeToggle(cameraManager);
|
|
161705
|
+
}
|
|
161706
|
+
// Apply minimal template styles
|
|
161707
|
+
this.applyMinimalStyles();
|
|
161708
|
+
}
|
|
161709
|
+
/**
|
|
161710
|
+
* Apply Standard template layout (bottom navigation)
|
|
161711
|
+
*/
|
|
161712
|
+
async applyStandardTemplate(navigationManager, cameraManager) {
|
|
161713
|
+
console.log('TemplateManager: Applying Standard template');
|
|
161714
|
+
// Add standard template class
|
|
161715
|
+
this.targetElement.classList.add('template-standard');
|
|
161716
|
+
// Create bottom navigation container
|
|
161717
|
+
if ((this.options.showProgressBar || this.options.showNavButtons) && navigationManager) {
|
|
161718
|
+
this.createStandardControls(navigationManager);
|
|
161719
|
+
}
|
|
161720
|
+
// Create mode toggle if multiple modes allowed
|
|
161721
|
+
if (this.shouldShowModeToggle() && cameraManager) {
|
|
161722
|
+
this.createStandardModeToggle(cameraManager);
|
|
161723
|
+
}
|
|
161724
|
+
// Apply standard template styles
|
|
161725
|
+
this.applyStandardStyles();
|
|
161726
|
+
}
|
|
161727
|
+
/**
|
|
161728
|
+
* Apply Pro template layout (enhanced bottom navigation)
|
|
161729
|
+
*/
|
|
161730
|
+
async applyProTemplate(navigationManager, cameraManager) {
|
|
161731
|
+
console.log('TemplateManager: Applying Pro template');
|
|
161732
|
+
// Add pro template class
|
|
161733
|
+
this.targetElement.classList.add('template-pro');
|
|
161734
|
+
// Create waypoint info display at top
|
|
161735
|
+
if (navigationManager) {
|
|
161736
|
+
this.createProWaypointInfo();
|
|
161737
|
+
}
|
|
161738
|
+
// Create enhanced bottom navigation
|
|
161739
|
+
if ((this.options.showProgressBar || this.options.showNavButtons) && navigationManager) {
|
|
161740
|
+
this.createProControls(navigationManager);
|
|
161741
|
+
}
|
|
161742
|
+
// Create mode toggle on left side
|
|
161743
|
+
if (this.shouldShowModeToggle() && cameraManager) {
|
|
161744
|
+
this.createProModeToggle(cameraManager);
|
|
161745
|
+
}
|
|
161746
|
+
// Apply pro template styles
|
|
161747
|
+
this.applyProStyles();
|
|
161748
|
+
}
|
|
161749
|
+
/**
|
|
161750
|
+
* Helper to determine if mode toggle should be shown
|
|
161751
|
+
*/
|
|
161752
|
+
shouldShowModeToggle() {
|
|
161753
|
+
const allowedModes = this.options.allowedCameraModes || [];
|
|
161754
|
+
return this.options.showCameraModeToggle !== false && allowedModes.length > 1;
|
|
161755
|
+
}
|
|
161756
|
+
/**
|
|
161757
|
+
* Create minimal overlay controls
|
|
161758
|
+
*/
|
|
161759
|
+
createMinimalControls(navigationManager) {
|
|
161760
|
+
// Create overlay container
|
|
161761
|
+
this.controlsContainer = document.createElement('div');
|
|
161762
|
+
this.controlsContainer.id = 'scrollControls';
|
|
161763
|
+
this.controlsContainer.className = 'minimal-controls';
|
|
161764
|
+
// Progress bar
|
|
161765
|
+
if (this.options.showProgressBar) {
|
|
161766
|
+
const progressContainer = document.createElement('div');
|
|
161767
|
+
progressContainer.className = 'minimal-progress-container';
|
|
161768
|
+
const progressBar = document.createElement('div');
|
|
161769
|
+
progressBar.className = 'minimal-progress-bar';
|
|
161770
|
+
const progressFill = document.createElement('div');
|
|
161771
|
+
progressFill.className = 'minimal-progress-fill';
|
|
161772
|
+
progressFill.id = 'progressBar';
|
|
161773
|
+
progressBar.appendChild(progressFill);
|
|
161774
|
+
progressContainer.appendChild(progressBar);
|
|
161775
|
+
// Add percentage display
|
|
161776
|
+
const percentageDisplay = document.createElement('div');
|
|
161777
|
+
percentageDisplay.className = 'minimal-percentage';
|
|
161778
|
+
percentageDisplay.id = 'scrollPercentage';
|
|
161779
|
+
percentageDisplay.textContent = '0%';
|
|
161780
|
+
progressContainer.appendChild(percentageDisplay);
|
|
161781
|
+
this.controlsContainer.appendChild(progressContainer);
|
|
161782
|
+
}
|
|
161783
|
+
// Navigation buttons (inline with progress)
|
|
161784
|
+
if (this.options.showNavButtons) {
|
|
161785
|
+
const navContainer = document.createElement('div');
|
|
161786
|
+
navContainer.className = 'minimal-nav-buttons';
|
|
161787
|
+
const prevButton = this.createNavButton('prev', 'minimal');
|
|
161788
|
+
const nextButton = this.createNavButton('next', 'minimal');
|
|
161789
|
+
navContainer.appendChild(prevButton);
|
|
161790
|
+
navContainer.appendChild(nextButton);
|
|
161791
|
+
this.controlsContainer.appendChild(navContainer);
|
|
161792
|
+
}
|
|
161793
|
+
this.targetElement.appendChild(this.controlsContainer);
|
|
161794
|
+
// Connect to navigation manager
|
|
161795
|
+
this.connectNavigationControls(navigationManager);
|
|
161796
|
+
}
|
|
161797
|
+
/**
|
|
161798
|
+
* Create standard bottom controls
|
|
161799
|
+
*/
|
|
161800
|
+
createStandardControls(navigationManager) {
|
|
161801
|
+
// Create bottom controls container
|
|
161802
|
+
this.controlsContainer = document.createElement('div');
|
|
161803
|
+
this.controlsContainer.id = 'scrollControls';
|
|
161804
|
+
this.controlsContainer.className = 'standard-controls';
|
|
161805
|
+
// Create controls content container
|
|
161806
|
+
const controlsContent = document.createElement('div');
|
|
161807
|
+
controlsContent.className = 'standard-controls-content';
|
|
161808
|
+
// Progress section
|
|
161809
|
+
const progressSection = document.createElement('div');
|
|
161810
|
+
progressSection.className = 'standard-progress-section';
|
|
161811
|
+
// Percentage display
|
|
161812
|
+
const percentageDisplay = document.createElement('div');
|
|
161813
|
+
percentageDisplay.id = 'scrollPercentage';
|
|
161814
|
+
percentageDisplay.className = 'standard-percentage';
|
|
161815
|
+
percentageDisplay.textContent = '0%';
|
|
161816
|
+
progressSection.appendChild(percentageDisplay);
|
|
161817
|
+
// Progress bar container
|
|
161818
|
+
const progressContainer = document.createElement('div');
|
|
161819
|
+
progressContainer.className = 'standard-progress-container';
|
|
161820
|
+
progressContainer.id = 'progressBarContainer';
|
|
161821
|
+
const progressBar = document.createElement('div');
|
|
161822
|
+
progressBar.className = 'standard-progress-bar';
|
|
161823
|
+
progressBar.id = 'progressBar';
|
|
161824
|
+
progressContainer.appendChild(progressBar);
|
|
161825
|
+
progressSection.appendChild(progressContainer);
|
|
161826
|
+
controlsContent.appendChild(progressSection);
|
|
161827
|
+
// Navigation buttons
|
|
161828
|
+
if (this.options.showNavButtons) {
|
|
161829
|
+
const buttonsContainer = document.createElement('div');
|
|
161830
|
+
buttonsContainer.className = 'standard-buttons-container';
|
|
161831
|
+
buttonsContainer.id = 'scrollButtons';
|
|
161832
|
+
const prevButton = this.createNavButton('prev', 'standard');
|
|
161833
|
+
const nextButton = this.createNavButton('next', 'standard');
|
|
161834
|
+
// Add autoplay button if enabled
|
|
161835
|
+
if (this.options.autoPlayEnabled) {
|
|
161836
|
+
const autoplayControls = document.createElement('div');
|
|
161837
|
+
autoplayControls.id = 'autoplayControls';
|
|
161838
|
+
autoplayControls.className = 'standard-autoplay';
|
|
161839
|
+
const playPauseButton = document.createElement('button');
|
|
161840
|
+
playPauseButton.id = 'playPauseButton';
|
|
161841
|
+
playPauseButton.className = 'standard-play-pause';
|
|
161842
|
+
playPauseButton.innerHTML = '<svg viewBox="0 0 24 24"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>';
|
|
161843
|
+
autoplayControls.appendChild(playPauseButton);
|
|
161844
|
+
buttonsContainer.appendChild(prevButton);
|
|
161845
|
+
buttonsContainer.appendChild(autoplayControls);
|
|
161846
|
+
buttonsContainer.appendChild(nextButton);
|
|
161847
|
+
}
|
|
161848
|
+
else {
|
|
161849
|
+
buttonsContainer.appendChild(prevButton);
|
|
161850
|
+
buttonsContainer.appendChild(nextButton);
|
|
161851
|
+
}
|
|
161852
|
+
controlsContent.appendChild(buttonsContainer);
|
|
161853
|
+
}
|
|
161854
|
+
this.controlsContainer.appendChild(controlsContent);
|
|
161855
|
+
this.targetElement.appendChild(this.controlsContainer);
|
|
161856
|
+
// Connect to navigation manager
|
|
161857
|
+
this.connectNavigationControls(navigationManager);
|
|
161858
|
+
}
|
|
161859
|
+
/**
|
|
161860
|
+
* Create pro enhanced controls
|
|
161861
|
+
*/
|
|
161862
|
+
createProControls(navigationManager) {
|
|
161863
|
+
// Implementation based on pro template HTML
|
|
161864
|
+
// TODO: Implement based on pro template HTML
|
|
161865
|
+
}
|
|
161866
|
+
/**
|
|
161867
|
+
* Create minimal mode toggle
|
|
161868
|
+
*/
|
|
161869
|
+
createMinimalModeToggle(cameraManager) {
|
|
161870
|
+
const allowedModes = this.options.allowedCameraModes || [];
|
|
161871
|
+
if (allowedModes.length <= 1)
|
|
161872
|
+
return;
|
|
161873
|
+
this.modeToggleContainer = document.createElement('div');
|
|
161874
|
+
this.modeToggleContainer.id = 'modeToggleContainer';
|
|
161875
|
+
this.modeToggleContainer.className = 'minimal-mode-toggle';
|
|
161876
|
+
// Create mode buttons
|
|
161877
|
+
if (allowedModes.includes('explore')) {
|
|
161878
|
+
const exploreButton = document.createElement('button');
|
|
161879
|
+
exploreButton.id = 'modeExplore';
|
|
161880
|
+
exploreButton.className = 'mode-button';
|
|
161881
|
+
exploreButton.textContent = 'Explore';
|
|
161882
|
+
exploreButton.addEventListener('click', () => cameraManager.setCameraMode('explore'));
|
|
161883
|
+
this.modeToggleContainer.appendChild(exploreButton);
|
|
161884
|
+
}
|
|
161885
|
+
if (allowedModes.includes('tour')) {
|
|
161886
|
+
const tourButton = document.createElement('button');
|
|
161887
|
+
tourButton.id = 'modeTour';
|
|
161888
|
+
tourButton.className = 'mode-button';
|
|
161889
|
+
tourButton.textContent = 'Tour';
|
|
161890
|
+
tourButton.addEventListener('click', () => cameraManager.setCameraMode('tour'));
|
|
161891
|
+
this.modeToggleContainer.appendChild(tourButton);
|
|
161892
|
+
}
|
|
161893
|
+
if (allowedModes.includes('hybrid')) {
|
|
161894
|
+
const hybridButton = document.createElement('button');
|
|
161895
|
+
hybridButton.id = 'modeHybrid';
|
|
161896
|
+
hybridButton.className = 'mode-button';
|
|
161897
|
+
hybridButton.textContent = 'Hybrid';
|
|
161898
|
+
hybridButton.addEventListener('click', () => cameraManager.setCameraMode('hybrid'));
|
|
161899
|
+
this.modeToggleContainer.appendChild(hybridButton);
|
|
161900
|
+
}
|
|
161901
|
+
if (allowedModes.includes('walk')) {
|
|
161902
|
+
const walkButton = document.createElement('button');
|
|
161903
|
+
walkButton.id = 'modeWalk';
|
|
161904
|
+
walkButton.className = 'mode-button';
|
|
161905
|
+
walkButton.textContent = 'Walk';
|
|
161906
|
+
walkButton.addEventListener('click', () => cameraManager.setCameraMode('walk'));
|
|
161907
|
+
this.modeToggleContainer.appendChild(walkButton);
|
|
161908
|
+
}
|
|
161909
|
+
this.targetElement.appendChild(this.modeToggleContainer);
|
|
161910
|
+
// Update button states based on current mode
|
|
161911
|
+
this.updateModeToggleState(cameraManager.currentMode);
|
|
161912
|
+
// Listen for mode changes
|
|
161913
|
+
cameraManager.onCameraModeChange = (mode) => {
|
|
161914
|
+
this.updateModeToggleState(mode);
|
|
161915
|
+
};
|
|
161916
|
+
}
|
|
161917
|
+
/**
|
|
161918
|
+
* Create standard mode toggle
|
|
161919
|
+
*/
|
|
161920
|
+
createStandardModeToggle(cameraManager) {
|
|
161921
|
+
const allowedModes = this.options.allowedCameraModes || [];
|
|
161922
|
+
if (allowedModes.length <= 1)
|
|
161923
|
+
return;
|
|
161924
|
+
this.modeToggleContainer = document.createElement('div');
|
|
161925
|
+
this.modeToggleContainer.id = 'modeToggleContainer';
|
|
161926
|
+
this.modeToggleContainer.className = 'standard-mode-toggle';
|
|
161927
|
+
const toggleRow = document.createElement('div');
|
|
161928
|
+
toggleRow.className = 'standard-mode-toggle-row';
|
|
161929
|
+
// Create mode buttons
|
|
161930
|
+
if (allowedModes.includes('explore')) {
|
|
161931
|
+
const exploreButton = document.createElement('button');
|
|
161932
|
+
exploreButton.id = 'modeExplore';
|
|
161933
|
+
exploreButton.className = 'mode-button';
|
|
161934
|
+
exploreButton.textContent = 'Explore';
|
|
161935
|
+
exploreButton.addEventListener('click', () => cameraManager.setCameraMode('explore'));
|
|
161936
|
+
toggleRow.appendChild(exploreButton);
|
|
161937
|
+
}
|
|
161938
|
+
if (allowedModes.includes('tour')) {
|
|
161939
|
+
const tourButton = document.createElement('button');
|
|
161940
|
+
tourButton.id = 'modeTour';
|
|
161941
|
+
tourButton.className = 'mode-button';
|
|
161942
|
+
tourButton.textContent = 'Tour';
|
|
161943
|
+
tourButton.addEventListener('click', () => cameraManager.setCameraMode('tour'));
|
|
161944
|
+
toggleRow.appendChild(tourButton);
|
|
161945
|
+
}
|
|
161946
|
+
if (allowedModes.includes('hybrid')) {
|
|
161947
|
+
const hybridButton = document.createElement('button');
|
|
161948
|
+
hybridButton.id = 'modeHybrid';
|
|
161949
|
+
hybridButton.className = 'mode-button';
|
|
161950
|
+
hybridButton.textContent = 'Hybrid';
|
|
161951
|
+
hybridButton.addEventListener('click', () => cameraManager.setCameraMode('hybrid'));
|
|
161952
|
+
toggleRow.appendChild(hybridButton);
|
|
161953
|
+
}
|
|
161954
|
+
if (allowedModes.includes('walk')) {
|
|
161955
|
+
const walkButton = document.createElement('button');
|
|
161956
|
+
walkButton.id = 'modeWalk';
|
|
161957
|
+
walkButton.className = 'mode-button';
|
|
161958
|
+
walkButton.textContent = 'Walk';
|
|
161959
|
+
walkButton.addEventListener('click', () => cameraManager.setCameraMode('walk'));
|
|
161960
|
+
toggleRow.appendChild(walkButton);
|
|
161961
|
+
}
|
|
161962
|
+
this.modeToggleContainer.appendChild(toggleRow);
|
|
161963
|
+
this.targetElement.appendChild(this.modeToggleContainer);
|
|
161964
|
+
// Update button states based on current mode
|
|
161965
|
+
this.updateModeToggleState(cameraManager.currentMode);
|
|
161966
|
+
// Listen for mode changes
|
|
161967
|
+
cameraManager.onCameraModeChange = (mode) => {
|
|
161968
|
+
this.updateModeToggleState(mode);
|
|
161969
|
+
};
|
|
161970
|
+
}
|
|
161971
|
+
/**
|
|
161972
|
+
* Create pro mode toggle (left side)
|
|
161973
|
+
*/
|
|
161974
|
+
createProModeToggle(cameraManager) {
|
|
161975
|
+
// Implementation for pro mode toggle
|
|
161976
|
+
// TODO: Implement mode toggle UI
|
|
161977
|
+
}
|
|
161978
|
+
/**
|
|
161979
|
+
* Create pro waypoint info display
|
|
161980
|
+
*/
|
|
161981
|
+
createProWaypointInfo() {
|
|
161982
|
+
const waypointInfo = document.createElement('div');
|
|
161983
|
+
waypointInfo.id = 'waypointInfo';
|
|
161984
|
+
waypointInfo.className = 'pro-waypoint-info';
|
|
161985
|
+
this.targetElement.appendChild(waypointInfo);
|
|
161986
|
+
}
|
|
161987
|
+
/**
|
|
161988
|
+
* Helper to create navigation buttons
|
|
161989
|
+
*/
|
|
161990
|
+
createNavButton(type, style) {
|
|
161991
|
+
const button = document.createElement('button');
|
|
161992
|
+
button.id = type === 'prev' ? 'prevButton' : 'nextButton';
|
|
161993
|
+
button.className = `${style}-nav-button ${type}`;
|
|
161994
|
+
button.innerHTML = type === 'prev' ? '←' : '→';
|
|
161995
|
+
button.title = type === 'prev' ? 'Previous' : 'Next';
|
|
161996
|
+
return button;
|
|
161997
|
+
}
|
|
161998
|
+
/**
|
|
161999
|
+
* Connect navigation controls to NavigationManager
|
|
162000
|
+
*/
|
|
162001
|
+
connectNavigationControls(navigationManager) {
|
|
162002
|
+
// Connect progress updates
|
|
162003
|
+
if (this.options.showProgressBar) ;
|
|
162004
|
+
// Connect button clicks
|
|
162005
|
+
if (this.options.showNavButtons) {
|
|
162006
|
+
const prevButton = document.getElementById('prevButton');
|
|
162007
|
+
const nextButton = document.getElementById('nextButton');
|
|
162008
|
+
prevButton === null || prevButton === void 0 ? void 0 : prevButton.addEventListener('click', () => navigationManager.previousWaypoint());
|
|
162009
|
+
nextButton === null || nextButton === void 0 ? void 0 : nextButton.addEventListener('click', () => navigationManager.nextWaypoint());
|
|
162010
|
+
}
|
|
162011
|
+
}
|
|
162012
|
+
/**
|
|
162013
|
+
* Apply minimal template styles
|
|
162014
|
+
*/
|
|
162015
|
+
applyMinimalStyles() {
|
|
162016
|
+
const style = document.createElement('style');
|
|
162017
|
+
style.textContent = `
|
|
162018
|
+
.template-minimal .minimal-controls {
|
|
162019
|
+
position: fixed;
|
|
162020
|
+
bottom: 20px;
|
|
162021
|
+
left: 50%;
|
|
162022
|
+
transform: translateX(-50%);
|
|
162023
|
+
display: flex;
|
|
162024
|
+
align-items: center;
|
|
162025
|
+
gap: 20px;
|
|
162026
|
+
z-index: 100;
|
|
162027
|
+
}
|
|
162028
|
+
|
|
162029
|
+
.template-minimal .minimal-progress-container {
|
|
162030
|
+
display: flex;
|
|
162031
|
+
align-items: center;
|
|
162032
|
+
gap: 10px;
|
|
162033
|
+
}
|
|
162034
|
+
|
|
162035
|
+
.template-minimal .minimal-progress-bar {
|
|
162036
|
+
width: 200px;
|
|
162037
|
+
height: 2px;
|
|
162038
|
+
background: rgba(255, 255, 255, 0.2);
|
|
162039
|
+
border-radius: 1px;
|
|
162040
|
+
overflow: hidden;
|
|
162041
|
+
}
|
|
162042
|
+
|
|
162043
|
+
.template-minimal .minimal-progress-fill {
|
|
162044
|
+
height: 100%;
|
|
162045
|
+
background: ${this.options.uiColor || '#4CAF50'};
|
|
162046
|
+
transition: width 0.3s ease;
|
|
162047
|
+
width: 0%;
|
|
162048
|
+
}
|
|
162049
|
+
|
|
162050
|
+
.template-minimal .minimal-percentage {
|
|
162051
|
+
color: white;
|
|
162052
|
+
font-size: 12px;
|
|
162053
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
162054
|
+
min-width: 35px;
|
|
162055
|
+
text-align: right;
|
|
162056
|
+
}
|
|
162057
|
+
|
|
162058
|
+
.template-minimal .minimal-nav-buttons {
|
|
162059
|
+
display: flex;
|
|
162060
|
+
gap: 10px;
|
|
162061
|
+
}
|
|
162062
|
+
|
|
162063
|
+
.template-minimal .minimal-nav-button {
|
|
162064
|
+
background: rgba(0, 0, 0, 0.5);
|
|
162065
|
+
border: none;
|
|
162066
|
+
color: white;
|
|
162067
|
+
width: 32px;
|
|
162068
|
+
height: 32px;
|
|
162069
|
+
border-radius: 50%;
|
|
162070
|
+
cursor: pointer;
|
|
162071
|
+
display: flex;
|
|
162072
|
+
align-items: center;
|
|
162073
|
+
justify-content: center;
|
|
162074
|
+
transition: background 0.2s ease;
|
|
162075
|
+
}
|
|
162076
|
+
|
|
162077
|
+
.template-minimal .minimal-nav-button:hover {
|
|
162078
|
+
background: rgba(0, 0, 0, 0.7);
|
|
162079
|
+
}
|
|
162080
|
+
|
|
162081
|
+
.template-minimal .minimal-mode-toggle {
|
|
162082
|
+
position: fixed;
|
|
162083
|
+
bottom: 70px;
|
|
162084
|
+
left: 50%;
|
|
162085
|
+
transform: translateX(-50%);
|
|
162086
|
+
display: flex;
|
|
162087
|
+
gap: 10px;
|
|
162088
|
+
z-index: 100;
|
|
162089
|
+
}
|
|
162090
|
+
|
|
162091
|
+
.template-minimal .mode-button {
|
|
162092
|
+
background: rgba(0, 0, 0, 0.5);
|
|
162093
|
+
border: none;
|
|
162094
|
+
color: white;
|
|
162095
|
+
padding: 6px 12px;
|
|
162096
|
+
border-radius: 4px;
|
|
162097
|
+
cursor: pointer;
|
|
162098
|
+
font-size: 12px;
|
|
162099
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
162100
|
+
transition: all 0.2s ease;
|
|
162101
|
+
min-width: 60px;
|
|
162102
|
+
}
|
|
162103
|
+
|
|
162104
|
+
.template-minimal .mode-button:hover {
|
|
162105
|
+
background: rgba(0, 0, 0, 0.7);
|
|
162106
|
+
}
|
|
162107
|
+
|
|
162108
|
+
.template-minimal .mode-button.selected {
|
|
162109
|
+
background: ${this.options.uiColor || '#4CAF50'};
|
|
162110
|
+
}
|
|
162111
|
+
|
|
162112
|
+
@media (max-width: 768px) {
|
|
162113
|
+
.template-minimal .minimal-controls {
|
|
162114
|
+
bottom: 10px;
|
|
162115
|
+
gap: 15px;
|
|
162116
|
+
}
|
|
162117
|
+
|
|
162118
|
+
.template-minimal .minimal-mode-toggle {
|
|
162119
|
+
bottom: 50px;
|
|
162120
|
+
}
|
|
162121
|
+
|
|
162122
|
+
.template-minimal .mode-button {
|
|
162123
|
+
padding: 5px 10px;
|
|
162124
|
+
font-size: 11px;
|
|
162125
|
+
min-width: 50px;
|
|
162126
|
+
}
|
|
162127
|
+
}
|
|
162128
|
+
`;
|
|
162129
|
+
document.head.appendChild(style);
|
|
162130
|
+
}
|
|
162131
|
+
/**
|
|
162132
|
+
* Apply standard template styles
|
|
162133
|
+
*/
|
|
162134
|
+
applyStandardStyles() {
|
|
162135
|
+
const style = document.createElement('style');
|
|
162136
|
+
style.textContent = `
|
|
162137
|
+
.template-standard .standard-controls {
|
|
162138
|
+
position: fixed;
|
|
162139
|
+
bottom: 0;
|
|
162140
|
+
left: 0;
|
|
162141
|
+
right: 0;
|
|
162142
|
+
background: rgba(0, 0, 0, 0.8);
|
|
162143
|
+
backdrop-filter: blur(10px);
|
|
162144
|
+
padding: 15px 20px;
|
|
162145
|
+
z-index: 100;
|
|
162146
|
+
display: flex;
|
|
162147
|
+
justify-content: center;
|
|
162148
|
+
}
|
|
162149
|
+
|
|
162150
|
+
.template-standard .standard-controls-content {
|
|
162151
|
+
width: 100%;
|
|
162152
|
+
max-width: 800px;
|
|
162153
|
+
display: flex;
|
|
162154
|
+
flex-direction: column;
|
|
162155
|
+
gap: 10px;
|
|
162156
|
+
}
|
|
162157
|
+
|
|
162158
|
+
.template-standard .standard-progress-section {
|
|
162159
|
+
display: flex;
|
|
162160
|
+
flex-direction: column;
|
|
162161
|
+
align-items: center;
|
|
162162
|
+
gap: 5px;
|
|
162163
|
+
}
|
|
162164
|
+
|
|
162165
|
+
.template-standard .standard-percentage {
|
|
162166
|
+
color: white;
|
|
162167
|
+
font-size: 14px;
|
|
162168
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
162169
|
+
}
|
|
162170
|
+
|
|
162171
|
+
.template-standard .standard-progress-container {
|
|
162172
|
+
width: 100%;
|
|
162173
|
+
height: 4px;
|
|
162174
|
+
background: rgba(255, 255, 255, 0.2);
|
|
162175
|
+
border-radius: 2px;
|
|
162176
|
+
overflow: hidden;
|
|
162177
|
+
}
|
|
162178
|
+
|
|
162179
|
+
.template-standard .standard-progress-bar {
|
|
162180
|
+
height: 100%;
|
|
162181
|
+
background: ${this.options.uiColor || '#4CAF50'};
|
|
162182
|
+
transition: width 0.3s ease;
|
|
162183
|
+
width: 0%;
|
|
162184
|
+
}
|
|
162185
|
+
|
|
162186
|
+
.template-standard .standard-buttons-container {
|
|
162187
|
+
display: flex;
|
|
162188
|
+
justify-content: center;
|
|
162189
|
+
align-items: center;
|
|
162190
|
+
gap: 15px;
|
|
162191
|
+
margin-top: 5px;
|
|
162192
|
+
}
|
|
162193
|
+
|
|
162194
|
+
.template-standard .standard-nav-button {
|
|
162195
|
+
background: rgba(255, 255, 255, 0.1);
|
|
162196
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
162197
|
+
color: white;
|
|
162198
|
+
padding: 8px 20px;
|
|
162199
|
+
border-radius: 20px;
|
|
162200
|
+
cursor: pointer;
|
|
162201
|
+
display: flex;
|
|
162202
|
+
align-items: center;
|
|
162203
|
+
gap: 8px;
|
|
162204
|
+
font-size: 14px;
|
|
162205
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
162206
|
+
transition: all 0.2s ease;
|
|
162207
|
+
}
|
|
162208
|
+
|
|
162209
|
+
.template-standard .standard-nav-button:hover {
|
|
162210
|
+
background: rgba(255, 255, 255, 0.2);
|
|
162211
|
+
transform: translateY(-1px);
|
|
162212
|
+
}
|
|
162213
|
+
|
|
162214
|
+
.template-standard .standard-autoplay {
|
|
162215
|
+
display: flex;
|
|
162216
|
+
align-items: center;
|
|
162217
|
+
}
|
|
162218
|
+
|
|
162219
|
+
.template-standard .standard-play-pause {
|
|
162220
|
+
background: rgba(255, 255, 255, 0.1);
|
|
162221
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
162222
|
+
color: white;
|
|
162223
|
+
width: 40px;
|
|
162224
|
+
height: 40px;
|
|
162225
|
+
border-radius: 50%;
|
|
162226
|
+
cursor: pointer;
|
|
162227
|
+
display: flex;
|
|
162228
|
+
align-items: center;
|
|
162229
|
+
justify-content: center;
|
|
162230
|
+
transition: all 0.2s ease;
|
|
162231
|
+
}
|
|
162232
|
+
|
|
162233
|
+
.template-standard .standard-play-pause:hover {
|
|
162234
|
+
background: rgba(255, 255, 255, 0.2);
|
|
162235
|
+
}
|
|
162236
|
+
|
|
162237
|
+
.template-standard .standard-play-pause svg {
|
|
162238
|
+
width: 16px;
|
|
162239
|
+
height: 16px;
|
|
162240
|
+
fill: currentColor;
|
|
162241
|
+
}
|
|
162242
|
+
|
|
162243
|
+
.template-standard .standard-mode-toggle {
|
|
162244
|
+
position: fixed;
|
|
162245
|
+
top: 20px;
|
|
162246
|
+
right: 20px;
|
|
162247
|
+
z-index: 100;
|
|
162248
|
+
}
|
|
162249
|
+
|
|
162250
|
+
.template-standard .standard-mode-toggle-row {
|
|
162251
|
+
display: flex;
|
|
162252
|
+
gap: 5px;
|
|
162253
|
+
background: rgba(0, 0, 0, 0.8);
|
|
162254
|
+
backdrop-filter: blur(10px);
|
|
162255
|
+
padding: 5px;
|
|
162256
|
+
border-radius: 8px;
|
|
162257
|
+
}
|
|
162258
|
+
|
|
162259
|
+
.template-standard .mode-button {
|
|
162260
|
+
background: rgba(255, 255, 255, 0.1);
|
|
162261
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
162262
|
+
color: white;
|
|
162263
|
+
padding: 8px 16px;
|
|
162264
|
+
border-radius: 4px;
|
|
162265
|
+
cursor: pointer;
|
|
162266
|
+
font-size: 13px;
|
|
162267
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
162268
|
+
transition: all 0.2s ease;
|
|
162269
|
+
min-width: 70px;
|
|
162270
|
+
}
|
|
162271
|
+
|
|
162272
|
+
.template-standard .mode-button:hover {
|
|
162273
|
+
background: rgba(255, 255, 255, 0.2);
|
|
162274
|
+
}
|
|
162275
|
+
|
|
162276
|
+
.template-standard .mode-button.selected {
|
|
162277
|
+
background: ${this.options.uiColor || '#4CAF50'};
|
|
162278
|
+
border-color: ${this.options.uiColor || '#4CAF50'};
|
|
162279
|
+
}
|
|
162280
|
+
|
|
162281
|
+
@media (max-width: 768px) {
|
|
162282
|
+
.template-standard .standard-controls {
|
|
162283
|
+
padding: 10px 15px;
|
|
162284
|
+
}
|
|
162285
|
+
|
|
162286
|
+
.template-standard .standard-nav-button {
|
|
162287
|
+
padding: 6px 15px;
|
|
162288
|
+
font-size: 13px;
|
|
162289
|
+
}
|
|
162290
|
+
|
|
162291
|
+
.template-standard .standard-mode-toggle {
|
|
162292
|
+
top: 10px;
|
|
162293
|
+
right: 10px;
|
|
162294
|
+
}
|
|
162295
|
+
|
|
162296
|
+
.template-standard .mode-button {
|
|
162297
|
+
padding: 6px 12px;
|
|
162298
|
+
font-size: 12px;
|
|
162299
|
+
min-width: 60px;
|
|
162300
|
+
}
|
|
162301
|
+
}
|
|
162302
|
+
`;
|
|
162303
|
+
document.head.appendChild(style);
|
|
162304
|
+
}
|
|
162305
|
+
/**
|
|
162306
|
+
* Apply pro template styles
|
|
162307
|
+
*/
|
|
162308
|
+
applyProStyles() {
|
|
162309
|
+
// TODO: Add pro template CSS
|
|
162310
|
+
}
|
|
162311
|
+
/**
|
|
162312
|
+
* Update progress display
|
|
162313
|
+
*/
|
|
162314
|
+
updateProgress(percentage) {
|
|
162315
|
+
const progressBar = document.getElementById('progressBar');
|
|
162316
|
+
const percentageDisplay = document.getElementById('scrollPercentage');
|
|
162317
|
+
if (progressBar) {
|
|
162318
|
+
progressBar.style.width = `${percentage}%`;
|
|
162319
|
+
}
|
|
162320
|
+
if (percentageDisplay) {
|
|
162321
|
+
percentageDisplay.textContent = `${Math.round(percentage)}%`;
|
|
162322
|
+
}
|
|
162323
|
+
}
|
|
162324
|
+
/**
|
|
162325
|
+
* Get preloader UI instance (for direct access if needed)
|
|
162326
|
+
*/
|
|
162327
|
+
getPreloaderUI() {
|
|
162328
|
+
return this.preloaderUI;
|
|
162329
|
+
}
|
|
162330
|
+
/**
|
|
162331
|
+
* Show/hide preloader
|
|
162332
|
+
*/
|
|
162333
|
+
showPreloader() {
|
|
162334
|
+
var _a;
|
|
162335
|
+
(_a = this.preloaderUI) === null || _a === void 0 ? void 0 : _a.show();
|
|
162336
|
+
}
|
|
162337
|
+
hidePreloader() {
|
|
162338
|
+
var _a;
|
|
162339
|
+
(_a = this.preloaderUI) === null || _a === void 0 ? void 0 : _a.hide();
|
|
162340
|
+
}
|
|
162341
|
+
/**
|
|
162342
|
+
* Update preloader progress
|
|
162343
|
+
*/
|
|
162344
|
+
updatePreloaderProgress(percentage, text) {
|
|
162345
|
+
var _a;
|
|
162346
|
+
(_a = this.preloaderUI) === null || _a === void 0 ? void 0 : _a.updateProgress(percentage, text);
|
|
162347
|
+
}
|
|
162348
|
+
/**
|
|
162349
|
+
* Update mode toggle button states
|
|
162350
|
+
*/
|
|
162351
|
+
updateModeToggleState(currentMode) {
|
|
162352
|
+
var _a;
|
|
162353
|
+
const buttons = (_a = this.modeToggleContainer) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.mode-button');
|
|
162354
|
+
buttons === null || buttons === void 0 ? void 0 : buttons.forEach(button => {
|
|
162355
|
+
const mode = button.id.replace('mode', '').toLowerCase();
|
|
162356
|
+
button.classList.toggle('selected', mode === currentMode);
|
|
162357
|
+
});
|
|
162358
|
+
}
|
|
162359
|
+
/**
|
|
162360
|
+
* Clean up and dispose
|
|
162361
|
+
*/
|
|
162362
|
+
dispose() {
|
|
162363
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
162364
|
+
// Dispose UI components
|
|
162365
|
+
(_a = this.preloaderUI) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
162366
|
+
(_b = this.startButtonUI) === null || _b === void 0 ? void 0 : _b.dispose();
|
|
162367
|
+
(_c = this.watermarkUI) === null || _c === void 0 ? void 0 : _c.dispose();
|
|
162368
|
+
(_d = this.helpPanelUI) === null || _d === void 0 ? void 0 : _d.dispose();
|
|
162369
|
+
(_e = this.muteButtonUI) === null || _e === void 0 ? void 0 : _e.dispose();
|
|
162370
|
+
// Remove template classes
|
|
162371
|
+
this.targetElement.classList.remove('template-minimal', 'template-standard', 'template-pro');
|
|
162372
|
+
// Remove created elements
|
|
162373
|
+
(_f = this.controlsContainer) === null || _f === void 0 ? void 0 : _f.remove();
|
|
162374
|
+
(_g = this.modeToggleContainer) === null || _g === void 0 ? void 0 : _g.remove();
|
|
162375
|
+
(_h = this.progressContainer) === null || _h === void 0 ? void 0 : _h.remove();
|
|
162376
|
+
(_j = this.navigationContainer) === null || _j === void 0 ? void 0 : _j.remove();
|
|
162377
|
+
}
|
|
162378
|
+
}
|
|
162379
|
+
|
|
161603
162380
|
/******************************************************************************
|
|
161604
162381
|
Copyright (c) Microsoft Corporation.
|
|
161605
162382
|
|
|
@@ -161913,7 +162690,7 @@ function createViewerOptions(rawData, userOptions) {
|
|
|
161913
162690
|
}
|
|
161914
162691
|
async function initializeViewer(targetElement, rawData, // Accept any JSON data
|
|
161915
162692
|
options) {
|
|
161916
|
-
var _a, _b, _c, _d
|
|
162693
|
+
var _a, _b, _c, _d;
|
|
161917
162694
|
// Register BabylonJS loaders at runtime
|
|
161918
162695
|
try {
|
|
161919
162696
|
registerBuiltInLoaders();
|
|
@@ -161980,11 +162757,7 @@ options) {
|
|
|
161980
162757
|
let navigationManager = null;
|
|
161981
162758
|
let collisionManager = null;
|
|
161982
162759
|
// let uiManager: UIManager | null = null; // REMOVED: Old monolithic UI Manager
|
|
161983
|
-
let
|
|
161984
|
-
let startButtonUI = null;
|
|
161985
|
-
let watermarkUI = null;
|
|
161986
|
-
let helpPanelUI = null;
|
|
161987
|
-
let muteButtonUI = null; // Add reference for MuteButtonUI
|
|
162760
|
+
let templateManager = null; // NEW: Template-based UI system
|
|
161988
162761
|
let audioManager = null;
|
|
161989
162762
|
let renderLoopManager = null; // Add RenderLoopManager reference
|
|
161990
162763
|
let xrExperience = null; // Add XR experience reference
|
|
@@ -162018,13 +162791,9 @@ options) {
|
|
|
162018
162791
|
splatSwapManager = null;
|
|
162019
162792
|
audioManager === null || audioManager === void 0 ? void 0 : audioManager.dispose();
|
|
162020
162793
|
audioManager = null;
|
|
162021
|
-
// Dispose
|
|
162022
|
-
|
|
162023
|
-
|
|
162024
|
-
watermarkUI === null || watermarkUI === void 0 ? void 0 : watermarkUI.dispose();
|
|
162025
|
-
helpPanelUI === null || helpPanelUI === void 0 ? void 0 : helpPanelUI.dispose();
|
|
162026
|
-
muteButtonUI === null || muteButtonUI === void 0 ? void 0 : muteButtonUI.dispose(); // Dispose mute button UI
|
|
162027
|
-
preloaderUI = startButtonUI = watermarkUI = helpPanelUI = muteButtonUI = null;
|
|
162794
|
+
// Dispose template manager (handles all UI components)
|
|
162795
|
+
templateManager === null || templateManager === void 0 ? void 0 : templateManager.dispose();
|
|
162796
|
+
templateManager = null;
|
|
162028
162797
|
// NavigationManager and CameraManager disposal is handled by scene dispose or specific logic within them
|
|
162029
162798
|
// Dispose features managed outside scene graph
|
|
162030
162799
|
if (scene && finalViewerOptions) {
|
|
@@ -162176,44 +162945,23 @@ options) {
|
|
|
162176
162945
|
splatSwapManager === null || splatSwapManager === void 0 ? void 0 : splatSwapManager.updateProgress(progress, waypointIndex);
|
|
162177
162946
|
};
|
|
162178
162947
|
}
|
|
162179
|
-
// --- 9. Initialize
|
|
162180
|
-
//
|
|
162181
|
-
|
|
162182
|
-
//
|
|
162183
|
-
//
|
|
162184
|
-
|
|
162185
|
-
|
|
162186
|
-
|
|
162187
|
-
|
|
162188
|
-
uiColor: (finalViewerOptions === null || finalViewerOptions === void 0 ? void 0 : finalViewerOptions.uiColor) || '#4CAF50'
|
|
162189
|
-
};
|
|
162190
|
-
const preloaderConfig = Object.assign(Object.assign({}, defaultPreloaderConfig), finalViewerOptions === null || finalViewerOptions === void 0 ? void 0 : finalViewerOptions.preloaderConfig);
|
|
162191
|
-
preloaderUI = new PreloaderUI(targetElement, preloaderConfig);
|
|
162192
|
-
preloaderUI.create();
|
|
162193
|
-
// Start Button
|
|
162194
|
-
if (finalViewerOptions === null || finalViewerOptions === void 0 ? void 0 : finalViewerOptions.showStartExperience) {
|
|
162195
|
-
startButtonUI = new StartButtonUI(targetElement, finalViewerOptions, () => {
|
|
162196
|
-
// Callback to initialize audio context on first interaction
|
|
162197
|
-
audioManager === null || audioManager === void 0 ? void 0 : audioManager.initialize(); // Use the correct initialize method
|
|
162198
|
-
});
|
|
162199
|
-
startButtonUI.create();
|
|
162200
|
-
}
|
|
162201
|
-
// Watermark
|
|
162202
|
-
watermarkUI = new WatermarkUI(targetElement, finalViewerOptions);
|
|
162203
|
-
watermarkUI.create(); // Creates conditionally based on options inside the class
|
|
162204
|
-
// Help Panel
|
|
162205
|
-
helpPanelUI = new HelpPanelUI(targetElement, finalViewerOptions);
|
|
162206
|
-
helpPanelUI.create(); // Creates conditionally based on options inside the class
|
|
162207
|
-
// Mute Button (Needs AudioManager instance)
|
|
162208
|
-
// We'll initialize this after AudioManager is created
|
|
162948
|
+
// --- 9. Initialize Template Manager ---
|
|
162949
|
+
// The template manager handles all UI components based on the uiType
|
|
162950
|
+
templateManager = new TemplateManager(targetElement, finalViewerOptions);
|
|
162951
|
+
// Initialize the template UI (but don't fully set up navigation controls yet)
|
|
162952
|
+
// We'll do that after navigation manager is created
|
|
162953
|
+
await templateManager.initializeUI(null, null, null, () => {
|
|
162954
|
+
// Callback to initialize audio context on first interaction
|
|
162955
|
+
audioManager === null || audioManager === void 0 ? void 0 : audioManager.initialize();
|
|
162956
|
+
});
|
|
162209
162957
|
// --- 10. Load Splat Data ---
|
|
162210
162958
|
console.log("StorySplat Viewer: Starting splat asset load...");
|
|
162211
162959
|
splatRootMeshes = await loadSplatAsset(scene, data, (percentage, text) => {
|
|
162212
|
-
// Update preloader UI via
|
|
162213
|
-
|
|
162960
|
+
// Update preloader UI via template manager
|
|
162961
|
+
templateManager === null || templateManager === void 0 ? void 0 : templateManager.updatePreloaderProgress(percentage, text);
|
|
162214
162962
|
});
|
|
162215
162963
|
console.log("StorySplat Viewer: Splat asset loaded.");
|
|
162216
|
-
|
|
162964
|
+
templateManager === null || templateManager === void 0 ? void 0 : templateManager.hidePreloader(); // Hide preloader after splat is loaded
|
|
162217
162965
|
// --- 11. Initialize/Setup Features ---
|
|
162218
162966
|
// Setup Particle Systems (sync)
|
|
162219
162967
|
// Ensure setupParticleSystems is correctly imported and called
|
|
@@ -162251,11 +162999,9 @@ options) {
|
|
|
162251
162999
|
if (!analyticsManager)
|
|
162252
163000
|
throw new Error("AnalyticsManager not initialized before AudioManager"); // Guard
|
|
162253
163001
|
audioManager = new AudioManager(scene, finalViewerOptions, analyticsManager);
|
|
162254
|
-
//
|
|
162255
|
-
|
|
162256
|
-
|
|
162257
|
-
muteButtonUI.create();
|
|
162258
|
-
}
|
|
163002
|
+
// Re-initialize template UI with audio manager now that it's available
|
|
163003
|
+
// This will create the mute button if needed
|
|
163004
|
+
await templateManager.initializeUI(audioManager, navigationManager, cameraManager);
|
|
162259
163005
|
// --- 12. Initialize Render Loop Manager ---
|
|
162260
163006
|
// Needs engine, scene, cameraManager, navigationManager
|
|
162261
163007
|
if (engine && scene && cameraManager) { // Ensure core components exist
|
|
@@ -162331,8 +163077,8 @@ options) {
|
|
|
162331
163077
|
console.log(`StorySplat Viewer: Starting splat swap to ${newSplatUrl}`);
|
|
162332
163078
|
analyticsManager === null || analyticsManager === void 0 ? void 0 : analyticsManager.trackSplatSwapStarted(newSplatUrl); // Corrected method call
|
|
162333
163079
|
// Show preloader
|
|
162334
|
-
|
|
162335
|
-
|
|
163080
|
+
templateManager === null || templateManager === void 0 ? void 0 : templateManager.showPreloader();
|
|
163081
|
+
templateManager === null || templateManager === void 0 ? void 0 : templateManager.updatePreloaderProgress(0, 'Preparing to load new splat...'); // Initial message
|
|
162336
163082
|
// Dispose existing splat meshes
|
|
162337
163083
|
console.log("StorySplat Viewer: Disposing current splat meshes...");
|
|
162338
163084
|
splatRootMeshes.forEach(mesh => {
|
|
@@ -162355,7 +163101,7 @@ options) {
|
|
|
162355
163101
|
// Ensure other potentially relevant fields from data are present if needed
|
|
162356
163102
|
waypoints: data.waypoints, hotspots: data.hotspots });
|
|
162357
163103
|
splatRootMeshes = await loadSplatAsset(scene, tempData, (percentage, text) => {
|
|
162358
|
-
|
|
163104
|
+
templateManager === null || templateManager === void 0 ? void 0 : templateManager.updatePreloaderProgress(percentage, text);
|
|
162359
163105
|
});
|
|
162360
163106
|
currentSplatUrl = newSplatUrl; // Update the tracked URL
|
|
162361
163107
|
console.log("StorySplat Viewer: New splat asset loaded successfully.");
|
|
@@ -162377,12 +163123,12 @@ options) {
|
|
|
162377
163123
|
console.error(`StorySplat Viewer: Failed to load new splat asset from ${newSplatUrl}:`, error);
|
|
162378
163124
|
analyticsManager === null || analyticsManager === void 0 ? void 0 : analyticsManager.trackSplatSwapFailed(error, newSplatUrl); // Corrected method call
|
|
162379
163125
|
// Hide preloader even on error
|
|
162380
|
-
|
|
163126
|
+
templateManager === null || templateManager === void 0 ? void 0 : templateManager.hidePreloader();
|
|
162381
163127
|
// Re-throw error to signal failure to the caller
|
|
162382
163128
|
throw error;
|
|
162383
163129
|
}
|
|
162384
163130
|
// Hide preloader on success
|
|
162385
|
-
|
|
163131
|
+
templateManager === null || templateManager === void 0 ? void 0 : templateManager.hidePreloader();
|
|
162386
163132
|
console.log("StorySplat Viewer: Splat swap complete.");
|
|
162387
163133
|
};
|
|
162388
163134
|
/**
|