Change loading animation to Sven Scharfenberg's that does not rely on JS.

This commit is contained in:
天クマ 2026-07-17 21:07:08 -03:00
commit 73e0496260
3 changed files with 111 additions and 94 deletions

View file

@ -12,15 +12,6 @@
<link rel="stylesheet" href="metroicons.css"> <link rel="stylesheet" href="metroicons.css">
</head> </head>
<body> <body>
<script defer>
document.addEventListener("DOMContentLoaded", () => {
setTimeout(() => {
document.querySelectorAll(".dots").forEach(el => {
el.classList.add("animate");
});
}, 100);
});
</script>
<div class="app-container no-active-chat"> <div class="app-container no-active-chat">
<aside id="desktop-aside"> <aside id="desktop-aside">
<button id="chats-sidebar-btn" class="icon-btn mif-qa mif-2x" data-page="chat-page"></button> <button id="chats-sidebar-btn" class="icon-btn mif-qa mif-2x" data-page="chat-page"></button>
@ -47,12 +38,14 @@
<div class="chat-list-container"> <div class="chat-list-container">
<div class="loading-chats" id="chats-loader"> <div class="loading-chats" id="chats-loader">
<div class='dots'> <div class='loading-animation-wrapper'>
<span></span> <div class="animation">
<span></span> <div class="dot"></div>
<span></span> <div class="dot"></div>
<span></span> <div class="dot"></div>
<span></span> <div class="dot"></div>
<div class="dot"></div>
</div>
</div> </div>
</div> </div>
<ul class="chat-list" id="chat-list"> <ul class="chat-list" id="chat-list">

View file

@ -224,16 +224,15 @@ async function selectChat(chat, isPopState = false, smoothScroll = true) {
elements.activeChatAvatar.textContent = chat.name ? chat.name.substring(0, 1).toUpperCase() : '?'; elements.activeChatAvatar.textContent = chat.name ? chat.name.substring(0, 1).toUpperCase() : '?';
elements.messagesContainer.innerHTML = ` elements.messagesContainer.innerHTML = `
<div class="loading-chats"> <div class='loading-animation-wrapper'>
<div class='dots'> <div class="animation">
<span></span> <p class="animation"></p>
<span></span> <div class="dot"></div>
<span></span> <div class="dot"></div>
<span></span> <div class="dot"></div>
<span></span> <div class="dot"></div>
<div class="dot"></div>
</div> </div>
<span>Loading messages...
</span>
</div>`; </div>`;
elements.appContainer.classList.remove('no-active-chat'); elements.appContainer.classList.remove('no-active-chat');

View file

@ -1,91 +1,116 @@
.dots { .loading-animation-wrapper {
width: 200px;
height: 40px;
margin: 10px auto 0 auto;
padding-top: 4px;
}
.loading-animation-wrapper .caption {
margin: 0;
padding: 0;
text-align: center;
color: #fff;
font: 12px/1.4em Arial;
}
.loading-animation-wrapper .dot {
position: relative; position: relative;
width: 100%;
}
.dots span:nth-child(1) {
animation-delay: 0.05s;
}
.dots span:nth-child(1):after {
left: -20px;
}
.dots span:nth-child(2) {
animation-delay: 0.1s;
}
.dots span:nth-child(2):after {
left: -40px;
}
.dots span:nth-child(3) {
animation-delay: 0.15s;
}
.dots span:nth-child(3):after {
left: -60px;
}
.dots span:nth-child(4) {
animation-delay: 0.2s;
}
.dots span:nth-child(4):after {
left: -80px;
}
.dots span:nth-child(5) {
animation-delay: 0.25s;
}
.dots span:nth-child(5):after {
left: -100px;
}
.dots span {
display: inline-block; display: inline-block;
position: absolute; width: 10px;
animation-duration: 4s; height: 10px;
animation-iteration-count: infinite; background: #fff;
-moz-border-radius: 100%;
-webkit-border-radius: 100%;
border-radius: 100%;
-moz-animation: movingdot 4s infinite;
-webkit-animation: movingdot 4s infinite;
animation: movingdot 4s infinite;
-moz-animation-timing-function: cubic-bezier(0.03, 0.615, 0.995, 0.415);
-webkit-animation-timing-function: cubic-bezier(0.03, 0.615, 0.995, 0.415);
animation-timing-function: cubic-bezier(0.03, 0.615, 0.995, 0.415);
-moz-animation-fill-mode: both;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
.loading-animation-wrapper .dot:nth-child(1) {
-moz-animation-delay: 1s;
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
.loading-animation-wrapper .dot:nth-child(2) {
-moz-animation-delay: 0.9s;
-webkit-animation-delay: 0.9s;
animation-delay: 0.9s;
}
.loading-animation-wrapper .dot:nth-child(3) {
-moz-animation-delay: 0.8s;
-webkit-animation-delay: 0.8s;
animation-delay: 0.8s;
}
.loading-animation-wrapper .dot:nth-child(4) {
-moz-animation-delay: 0.7s;
-webkit-animation-delay: 0.7s;
animation-delay: 0.7s;
}
.loading-animation-wrapper .dot:nth-child(5) {
-moz-animation-delay: 0.6s;
-webkit-animation-delay: 0.6s;
animation-delay: 0.6s;
} }
.dots span:after { @-moz-keyframes movingdot {
content: ""; 0% {
position: absolute; -moz-transform: translateX(-30px);
display: inline-block; transform: translateX(-30px);
background-color: #f0f0f0;
width: 8px;
height: 8px;
border-radius: 50%;
}
.dots.animate span {
animation-name: dots;
}
@keyframes dots {
0%,20% {
left: 0;
animation-timing-function: ease-out;
opacity: 0; opacity: 0;
} }
25% { 25% {
opacity: 1; opacity: 1;
} }
35% { 50% {
left: 45%; -moz-transform: translateX(200px);
animation-timing-function: linear; transform: translateX(200px);
}
65% {
left: 55%;
animation-timing-function: ease-in;
}
75% {
opacity: 1;
}
80%,100% {
left: 100%;
opacity: 0; opacity: 0;
} }
} 100% {
opacity: 0;
}
}
@-webkit-keyframes movingdot {
0% {
-webkit-transform: translateX(-30px);
transform: translateX(-30px);
opacity: 0;
}
25% {
opacity: 1;
}
50% {
-webkit-transform: translateX(200px);
transform: translateX(200px);
opacity: 0;
}
100% {
opacity: 0;
}
}
@keyframes movingdot {
0% {
-moz-transform: translateX(-30px);
-ms-transform: translateX(-30px);
-webkit-transform: translateX(-30px);
transform: translateX(-30px);
opacity: 0;
}
25% {
opacity: 1;
}
50% {
-moz-transform: translateX(200px);
-ms-transform: translateX(200px);
-webkit-transform: translateX(200px);
transform: translateX(200px);
opacity: 0;
}
100% {
opacity: 0;
}
}