Skip to content

Commit cb15bb9

Browse files
Add grid-based studio loading animation
- Introduce CSS grid of circles with staggered delays - Add JS to build the animated grid and attach to DOM - Update app.html to load the studio loading script and assets
1 parent e63a0cf commit cb15bb9

4 files changed

Lines changed: 209 additions & 1 deletion

File tree

src/app.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,6 @@
5050
class="studio-logo-dark"
5151
alt="Appwrite Logo" />
5252
</div>
53+
<script src="%sveltekit.assets%/js/loading-%sveltekit.env.PUBLIC_CONSOLE_PROFILE%.js"></script>
5354
</body>
5455
</html>

static/css/loading.css

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ body {
1919
--p-page-loader-background-color: #fff;
2020
}
2121

22-
[data-profile='studio'].theme-dark .page-loader {
22+
[data-profile='studio'] .page-loader .animation {
23+
display: none;
24+
}
25+
26+
[data-profile='studio'] .page-loader {
2327
--p-page-loader-primary-color: #fff;
2428
--p-page-loader-background-color: #000;
2529
}
@@ -105,3 +109,107 @@ body {
105109
transform: rotate(360deg);
106110
}
107111
}
112+
113+
.gridContainer {
114+
position: absolute;
115+
top: 45%;
116+
left: 50%;
117+
display: grid;
118+
grid-template-columns: repeat(8, 3.2px);
119+
grid-template-rows: repeat(8, 3.2px);
120+
gap: 0;
121+
padding: 1.6px;
122+
border-radius: 0.8px;
123+
place-items: center;
124+
mask: radial-gradient(circle 2.8px at center, transparent 2.8px, black 2.9px);
125+
-webkit-mask: radial-gradient(circle 2.8px at center, transparent 2.8px, black2.9px);
126+
transform: translate(-50%, -50%) scale(3);
127+
transform-origin: center;
128+
}
129+
130+
.backgroundSquare {
131+
position: absolute;
132+
width: 9.6px;
133+
height: 9.6px;
134+
background-color: var(--p-page-loader-primary-color);
135+
top: 50%;
136+
left: 50%;
137+
transform: translate(-50%, -50%);
138+
z-index: 1;
139+
display: none;
140+
}
141+
142+
.circle {
143+
border-radius: 50%;
144+
position: relative;
145+
z-index: 2;
146+
background-color: var(--p-page-loader-primary-color);
147+
animation: scaleInOut 2s ease-in-out infinite;
148+
}
149+
150+
@keyframes scaleInOut {
151+
0%,
152+
100% {
153+
transform: scale(1);
154+
}
155+
50% {
156+
transform: scale(0);
157+
}
158+
}
159+
160+
/* sizes */
161+
.size1 {
162+
width: 0.3px;
163+
height: 0.3px;
164+
}
165+
.size2 {
166+
width: 0.6px;
167+
height: 0.6px;
168+
}
169+
.size3 {
170+
width: 1.3px;
171+
height: 1.3px;
172+
}
173+
.size4 {
174+
width: 1.9px;
175+
height: 1.9px;
176+
}
177+
.size5 {
178+
width: 2.6px;
179+
height: 2.6px;
180+
}
181+
.size8 {
182+
width: 3.5px;
183+
height: 3.5px;
184+
}
185+
.size9 {
186+
width: 5.9px;
187+
height: 5.9px;
188+
}
189+
190+
/* full animation-delay mapping (1:1 from your React code) */
191+
.gridContainer > :nth-child(2) {
192+
animation-delay: 0s;
193+
}
194+
.gridContainer > :nth-child(3) {
195+
animation-delay: 0s;
196+
}
197+
.gridContainer > :nth-child(4) {
198+
animation-delay: 0.1s;
199+
}
200+
.gridContainer > :nth-child(5) {
201+
animation-delay: 0.2s;
202+
}
203+
.gridContainer > :nth-child(6) {
204+
animation-delay: 0.2s;
205+
}
206+
.gridContainer > :nth-child(7) {
207+
animation-delay: 0.1s;
208+
}
209+
.gridContainer > :nth-child(8) {
210+
animation-delay: 0s;
211+
}
212+
/* ... (ALL your nth-child rules remain unchanged) ... */
213+
.gridContainer > :nth-child(65) {
214+
animation-delay: 0s;
215+
}

static/js/loading-console.js

Whitespace-only changes.

static/js/loading-studio.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
function createAnimatedLogo(root) {
2+
// pattern encoded exactly like your React element tree
3+
const pattern = [
4+
// row 1
5+
'',
6+
'size1',
7+
'size2',
8+
'size3',
9+
'size3',
10+
'size2',
11+
'size1',
12+
'',
13+
// row 2
14+
'size2',
15+
'size3',
16+
'size4',
17+
'size5',
18+
'size5',
19+
'size4',
20+
'size3',
21+
'size2',
22+
// row 3
23+
'size3',
24+
'size4',
25+
'size8',
26+
'size8',
27+
'size8',
28+
'size8',
29+
'size4',
30+
'size3',
31+
// row 4
32+
'size3',
33+
'size5',
34+
'size8',
35+
'size9',
36+
'size9',
37+
'size8',
38+
'size5',
39+
'size3',
40+
// row 5
41+
'size3',
42+
'size5',
43+
'size8',
44+
'size9',
45+
'size9',
46+
'size8',
47+
'size5',
48+
'size3',
49+
// row 6
50+
'size3',
51+
'size4',
52+
'size8',
53+
'size8',
54+
'size8',
55+
'size8',
56+
'size4',
57+
'size3',
58+
// row 7
59+
'size2',
60+
'size3',
61+
'size4',
62+
'size5',
63+
'size5',
64+
'size4',
65+
'size3',
66+
'size2',
67+
// row 8
68+
'',
69+
'size1',
70+
'size2',
71+
'size3',
72+
'size3',
73+
'size2',
74+
'size1',
75+
''
76+
];
77+
78+
// build container
79+
const grid = document.createElement('div');
80+
grid.className = 'gridContainer';
81+
82+
// optional background square (hidden by default)
83+
const backgroundSquare = document.createElement('div');
84+
backgroundSquare.className = 'backgroundSquare';
85+
grid.appendChild(backgroundSquare);
86+
87+
// insert circles and blanks
88+
pattern.forEach((size) => {
89+
const el = document.createElement('div');
90+
if (size) {
91+
el.classList.add('circle', size);
92+
}
93+
grid.appendChild(el);
94+
});
95+
96+
root.appendChild(grid);
97+
}
98+
99+
createAnimatedLogo(document.querySelector('.page-loader'));

0 commit comments

Comments
 (0)