User Interface Controls & Modal Management
Control user interface elements and modal dialogs within your virtual spaces to create seamless, integrated user experiences. UI controls help manage information display, user interactions, and communication features.
closeModal
closeModal(modalName: string, [callback: Function])
Closes a specific modal dialog by name. This function provides programmatic control over modal visibility, allowing you to manage user interface flow and information display.
Parameters:
modalName: string
- The name/identifier of the modal to close
// Close a product information modal
api.closeModal('product-details', function() {
console.log('Product details modal closed');
// Return focus to the 3D environment
api.setCanvasFocus();
});
// Close settings modal after configuration
api.closeModal('settings-panel', function() {
console.log('Settings saved and modal closed');
applyNewSettings();
});
2
3
4
5
6
7
8
9
10
11
12
13
openTextChat
openTextChat()
Opens the text chat interface for communication in multiplayer virtual spaces. This function enables social interaction and collaboration between users.
Note: This function returns void
and executes immediately without a callback.
// Open chat when user clicks communication button
document.getElementById('chat-button').addEventListener('click', function() {
api.openTextChat();
console.log('Text chat opened');
// Update UI to show chat is active
updateChatButtonState(true);
});
// Open chat with welcome message
function startConversation() {
api.openTextChat();
// Optionally send a welcome message or instruction
setTimeout(() => {
showChatWelcomeMessage();
}, 500);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
closeTextChat
closeTextChat()
Closes the text chat interface, hiding the communication panel and returning focus to the 3D environment.
Note: This function returns void
and executes immediately without a callback.
// Close chat when user wants to focus on 3D content
document.getElementById('close-chat').addEventListener('click', function() {
api.closeTextChat();
console.log('Text chat closed');
// Update UI to show chat is inactive
updateChatButtonState(false);
// Return focus to 3D viewer
api.setCanvasFocus();
});
// Auto-close chat after period of inactivity
let chatInactivityTimer;
function resetChatInactivityTimer() {
clearTimeout(chatInactivityTimer);
chatInactivityTimer = setTimeout(() => {
api.closeTextChat();
console.log('Chat closed due to inactivity');
}, 300000); // 5 minutes
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
UI Management Examples
Modal Management System:
class ModalManager {
constructor() {
this.openModals = new Set();
this.modalStack = [];
}
openModal(modalName, content) {
// Track open modals
this.openModals.add(modalName);
this.modalStack.push(modalName);
// Create and show modal
this.createModal(modalName, content);
console.log(`Modal opened: ${modalName}`);
}
closeModal(modalName) {
if (!this.openModals.has(modalName)) {
console.warn(`Modal not open: ${modalName}`);
return;
}
// Close via API
api.closeModal(modalName, () => {
this.openModals.delete(modalName);
this.modalStack = this.modalStack.filter(name => name !== modalName);
console.log(`Modal closed: ${modalName}`);
// If no modals remain, return focus to viewer
if (this.modalStack.length === 0) {
api.setCanvasFocus();
}
});
}
closeAllModals() {
this.openModals.forEach(modalName => {
this.closeModal(modalName);
});
}
createModal(modalName, content) {
// Implementation would create actual modal DOM elements
console.log(`Creating modal: ${modalName}`);
}
}
const modalManager = new ModalManager();
// Usage
modalManager.openModal('product-info', {
title: 'Product Details',
content: 'Detailed product information...'
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Chat Integration System:
class ChatManager {
constructor() {
this.isChatOpen = false;
this.unreadMessages = 0;
this.chatHistory = [];
}
toggleChat() {
if (this.isChatOpen) {
this.closeChat();
} else {
this.openChat();
}
}
openChat() {
api.openTextChat();
this.isChatOpen = true;
this.unreadMessages = 0;
// Update UI indicators
this.updateChatUI();
// Track chat opening for analytics
this.trackChatEvent('opened');
}
closeChat() {
api.closeTextChat();
this.isChatOpen = false;
// Update UI indicators
this.updateChatUI();
// Return focus to 3D environment
api.setCanvasFocus();
// Track chat closing for analytics
this.trackChatEvent('closed');
}
updateChatUI() {
const chatButton = document.getElementById('chat-toggle');
const unreadBadge = document.getElementById('unread-badge');
if (chatButton) {
chatButton.textContent = this.isChatOpen ? 'Close Chat' : 'Open Chat';
chatButton.classList.toggle('active', this.isChatOpen);
}
if (unreadBadge) {
unreadBadge.textContent = this.unreadMessages;
unreadBadge.style.display = this.unreadMessages > 0 ? 'block' : 'none';
}
}
onMessageReceived(message) {
this.chatHistory.push(message);
if (!this.isChatOpen) {
this.unreadMessages++;
this.updateChatUI();
}
}
trackChatEvent(action) {
// Analytics tracking
console.log(`Chat ${action} at ${new Date().toISOString()}`);
}
}
const chatManager = new ChatManager();
// Set up chat controls
document.getElementById('chat-toggle').addEventListener('click', () => {
chatManager.toggleChat();
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Integrated UI Controller:
class VirtualSpaceUI {
constructor() {
this.modalManager = new ModalManager();
this.chatManager = new ChatManager();
this.activeInterfaces = new Set();
}
showProductDetails(productId) {
const modalName = `product-${productId}`;
// Fetch product data
this.fetchProductData(productId).then(productData => {
this.modalManager.openModal(modalName, {
title: productData.name,
content: this.createProductContent(productData),
actions: [
{
label: 'Add to Cart',
action: () => this.addToCart(productId)
},
{
label: 'Close',
action: () => this.modalManager.closeModal(modalName)
}
]
});
});
}
startGuidedTour() {
// Close any open interfaces
this.modalManager.closeAllModals();
this.chatManager.closeChat();
// Start tour modal
this.modalManager.openModal('guided-tour', {
title: 'Virtual Space Tour',
content: 'Welcome to your guided tour...',
type: 'tour'
});
}
enableCollaborationMode() {
// Open chat for team collaboration
this.chatManager.openChat();
// Show collaboration tools modal
this.modalManager.openModal('collaboration-tools', {
title: 'Collaboration Tools',
content: this.createCollaborationInterface(),
persistent: true
});
}
async fetchProductData(productId) {
// Simulate API call
return {
id: productId,
name: 'Sample Product',
description: 'Product description...',
price: '$99.99'
};
}
createProductContent(productData) {
return `
<div class="product-details">
<h2>${productData.name}</h2>
<p>${productData.description}</p>
<div class="price">${productData.price}</div>
</div>
`;
}
createCollaborationInterface() {
return `
<div class="collaboration-tools">
<button onclick="shareScreen()">Share Screen</button>
<button onclick="startVoiceChat()">Voice Chat</button>
<button onclick="createAnnotation()">Add Note</button>
</div>
`;
}
}
const spaceUI = new VirtualSpaceUI();
// Example usage
document.addEventListener('DOMContentLoaded', () => {
// Set up UI event listeners
document.getElementById('tour-button').addEventListener('click', () => {
spaceUI.startGuidedTour();
});
document.getElementById('collaborate-button').addEventListener('click', () => {
spaceUI.enableCollaborationMode();
});
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
Keyboard Shortcuts for UI:
class UIKeyboardController {
constructor(spaceUI) {
this.spaceUI = spaceUI;
this.setupKeyboardListeners();
}
setupKeyboardListeners() {
document.addEventListener('keydown', (event) => {
// Only handle shortcuts when not typing in input fields
if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
return;
}
switch (event.key) {
case 'c':
case 'C':
this.spaceUI.chatManager.toggleChat();
break;
case 'Escape':
this.spaceUI.modalManager.closeAllModals();
this.spaceUI.chatManager.closeChat();
api.setCanvasFocus();
break;
case 'h':
case 'H':
this.showHelpModal();
break;
}
});
}
showHelpModal() {
this.spaceUI.modalManager.openModal('help', {
title: 'Keyboard Shortcuts',
content: `
<ul>
<li><kbd>C</kbd> - Toggle Chat</li>
<li><kbd>Esc</kbd> - Close All UI</li>
<li><kbd>H</kbd> - Show Help</li>
</ul>
`
});
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Best Practices
User Experience:
- Provide clear visual feedback for UI state changes
- Use consistent modal naming conventions
- Always return focus to the 3D environment when appropriate
Performance:
- Close unused modals to free memory
- Limit the number of simultaneously open interfaces
- Use event delegation for dynamic UI elements
Accessibility:
- Support keyboard navigation for all UI controls
- Provide alternative ways to access chat and modal functions
- Ensure UI elements are properly labeled for screen readers