-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathloader.js
More file actions
172 lines (145 loc) · 4.97 KB
/
Copy pathloader.js
File metadata and controls
172 lines (145 loc) · 4.97 KB
1
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/**
* Loader Module
* Handles loader animations for the application
*
* Usage:
* - showCalcLoader('Message here', nodeCount) - Display the loader with custom message and conditional behavior
* - updateLoaderProgress('New message') - Update the message during processing
* - hideCalcLoader() - Hide the loader when processing completes
*/
import { $ } from '../utils/dom.js';
// Constants for transition timing (in ms)
const FADE_IN_DURATION = 500;
const ELEMENTS_TRANSITION_DELAY = 300;
const FADE_OUT_DURATION = 700;
// Node count threshold for simple vs full loader
const NODE_COUNT_THRESHOLD = 10;
// Track loading state to prevent overlapping operations
let isLoading = false;
/**
* Show the global loader with an optional message and conditional behavior based on node count
* @param {string} [message='Processing Graph...'] - Message to display
* @param {number} [nodeCount=50] - Number of nodes in the graph (determines loader type)
* @returns {Promise} Resolves when animations have completed
*/
export const showCalcLoader = (message = 'Processing Graph...', nodeCount = 50) => {
return new Promise(resolve => {
// If already loading, just update the message and resolve
if (isLoading) {
updateLoaderProgress(message);
resolve();
return;
}
// For small graphs, skip loader entirely - just resolve immediately
if (nodeCount < NODE_COUNT_THRESHOLD) {
resolve();
return;
}
// Use full orbital animation for larger graphs
// Set loading state flag
isLoading = true;
// Get all required elements
const elements = {
loader: $('#global-loader'),
progress: $('#loader-progress'),
graphCircle: $('#orbit-graph-circle'),
cyContainer: $('#cy'),
orbitalPaths: $('.orbit-paths')
};
// Update message
if (elements.progress) {
elements.progress.textContent = message;
}
// Fade in the loader
if (elements.loader) {
elements.loader.classList.add('show');
}
// Add loading class to main circle for glow effect
if (elements.graphCircle) {
elements.graphCircle.classList.add('loading');
}
// Hide animated elements with proper opacity
if (elements.cyContainer) {
elements.cyContainer.style.opacity = '0.01';
}
if (elements.orbitalPaths) {
elements.orbitalPaths.style.opacity = '0.01';
}
// Wait for transitions to complete before allowing processing to continue
setTimeout(resolve, FADE_IN_DURATION);
});
};
/**
* Update the loader progress message
* @param {string} message - New message to display
*/
export const updateLoaderProgress = (message) => {
const progress = $('#loader-progress');
if (progress) {
progress.textContent = message;
}
};
/**
* Hide the global loader with a smooth transition
* @returns {Promise} Resolves when animations have completed
*/
export const hideCalcLoader = () => {
return new Promise(resolve => {
// If not in loading state, just resolve immediately
if (!isLoading) {
resolve();
return;
}
// Get all required elements
const elements = {
loader: $('#global-loader'),
graphCircle: $('#orbit-graph-circle'),
cyContainer: $('#cy'),
orbitalPaths: $('.orbit-paths')
};
// First restore the animated elements opacity BEFORE hiding the loader
// This way they start fading in while the loader is still visible
if (elements.cyContainer) {
elements.cyContainer.style.opacity = '1';
}
if (elements.orbitalPaths) {
elements.orbitalPaths.style.opacity = '1';
}
// Remove loading class from main circle
if (elements.graphCircle) {
elements.graphCircle.classList.remove('loading');
}
// Wait a moment to let elements start becoming visible
// before starting to fade out the loader
setTimeout(() => {
// Only now start fading out the loader
if (elements.loader) {
elements.loader.classList.remove('show');
}
// Reset loading state
isLoading = false;
// Give extra time for all transitions to complete
// This longer delay ensures everything is fully visible before resolving
setTimeout(resolve, FADE_OUT_DURATION);
}, ELEMENTS_TRANSITION_DELAY);
});
};
/**
* Cancel any loading operation immediately (for error states)
* Bypasses animations for critical situations
*/
export const cancelLoading = () => {
const elements = {
loader: $('#global-loader'),
graphCircle: $('#orbit-graph-circle'),
cyContainer: $('#cy'),
orbitalPaths: $('.orbit-paths')
};
// Reset all elements immediately
if (elements.loader) elements.loader.classList.remove('show');
if (elements.graphCircle) elements.graphCircle.classList.remove('loading');
if (elements.cyContainer) elements.cyContainer.style.opacity = '1';
if (elements.orbitalPaths) elements.orbitalPaths.style.opacity = '1';
// Reset loading state
isLoading = false;
};