mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-06 08:22:24 +01:00
feature (loader): awesome loader on intial page load
This commit is contained in:
parent
63670050ff
commit
c2361c105a
3 changed files with 330 additions and 3 deletions
|
|
@ -60,4 +60,4 @@ Filestash can be used in different settings:
|
||||||
|
|
||||||
# Credits
|
# Credits
|
||||||
- [Contributors](https://github.com/mickael-kerjean/filestash/graphs/contributors) and folks developing awesome libraries (libvips, libraw, ...)
|
- [Contributors](https://github.com/mickael-kerjean/filestash/graphs/contributors) and folks developing awesome libraries (libvips, libraw, ...)
|
||||||
- Logo derived from the work of [ssnjrthegr8](https://github.com/ssnjrthegr8), Iconography from [flaticon](https://www.flaticon.com/), [fontawesome](https://fontawesome.com) and [material](https://material.io/icons/)
|
- Logo derived from the work of [ssnjrthegr8](https://github.com/ssnjrthegr8), Iconography from [flaticon](https://www.flaticon.com/), [fontawesome](https://fontawesome.com) and [material](https://material.io/icons/), loader adapted from [Mr Alien](https://codepen.io/mr_alien/pen/FDLjg)
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,268 @@
|
||||||
$style = document.querySelector("style");
|
$style = document.querySelector("style");
|
||||||
$style.innerText = $style.innerText.replace("#f2f3f5", "#9AD1ED")
|
$style.innerText = $style.innerText.replace("#f2f3f5", "#9AD1ED")
|
||||||
}
|
}
|
||||||
|
window.initTime = new Date();
|
||||||
|
window.setTimeout(function(){
|
||||||
|
var $loader = document.querySelector(".index-loader");
|
||||||
|
if($loader) $loader.removeAttribute("style");
|
||||||
|
}, 2000);
|
||||||
</script>
|
</script>
|
||||||
|
<div class="index-loader" style="display:none">
|
||||||
|
<div class="guy">
|
||||||
|
<span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</span>
|
||||||
|
<div class="base">
|
||||||
|
<span></span>
|
||||||
|
<div class="face"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="longfazers">
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
|
.guy {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
margin-left: -50px;
|
||||||
|
left: 40%;
|
||||||
|
animation: speeder 1s linear infinite;
|
||||||
|
}
|
||||||
|
.guy > span {
|
||||||
|
height: 5px;
|
||||||
|
width: 35px;
|
||||||
|
background: #626466;
|
||||||
|
position: absolute;
|
||||||
|
top: -19px;
|
||||||
|
left: 60px;
|
||||||
|
border-radius: 2px 10px 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.base span {
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-top: 6px solid transparent;
|
||||||
|
border-right: 100px solid #626466;
|
||||||
|
border-bottom: 6px solid transparent;
|
||||||
|
}
|
||||||
|
.base span:before {
|
||||||
|
content: "";
|
||||||
|
height: 22px;
|
||||||
|
width: 22px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #626466;
|
||||||
|
position: absolute;
|
||||||
|
right: -110px;
|
||||||
|
top: -16px;
|
||||||
|
}
|
||||||
|
.base span:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-top: 0 solid transparent;
|
||||||
|
border-right: 55px solid #626466;
|
||||||
|
border-bottom: 16px solid transparent;
|
||||||
|
top: -16px;
|
||||||
|
right: -98px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.face {
|
||||||
|
position: absolute;
|
||||||
|
height: 12px;
|
||||||
|
width: 20px;
|
||||||
|
background: #626466;
|
||||||
|
border-radius: 20px 20px 0 0;
|
||||||
|
transform: rotate(-40deg);
|
||||||
|
right: -125px;
|
||||||
|
top: -15px;
|
||||||
|
}
|
||||||
|
.face:after {
|
||||||
|
content: "";
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
background: #626466;
|
||||||
|
right: 4px;
|
||||||
|
top: 7px;
|
||||||
|
position: absolute;
|
||||||
|
transform: rotate(40deg);
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
border-radius: 0 0 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guy > span > span:nth-child(1),
|
||||||
|
.guy > span > span:nth-child(2),
|
||||||
|
.guy > span > span:nth-child(3),
|
||||||
|
.guy > span > span:nth-child(4) {
|
||||||
|
width: 30px;
|
||||||
|
height: 1px;
|
||||||
|
background: #626466;
|
||||||
|
position: absolute;
|
||||||
|
animation: fazer1 .2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guy > span > span:nth-child(2) {
|
||||||
|
top: 3px;
|
||||||
|
animation: fazer2 .4s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guy > span > span:nth-child(3) {
|
||||||
|
top: 1px;
|
||||||
|
animation: fazer3 .4s linear infinite;
|
||||||
|
animation-delay: -1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guy > span > span:nth-child(4) {
|
||||||
|
top: 4px;
|
||||||
|
animation: fazer4 1s linear infinite;
|
||||||
|
animation-delay: -1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fazer1 {
|
||||||
|
0% {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: -80px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fazer2 {
|
||||||
|
0% {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: -100px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fazer3 {
|
||||||
|
0% {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: -50px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fazer4 {
|
||||||
|
0% {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: -150px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes speeder {
|
||||||
|
0% {
|
||||||
|
transform: translate(1px, 1px) rotate(0deg);
|
||||||
|
}
|
||||||
|
10% {
|
||||||
|
transform: translate(-1px, -1px) rotate(-1deg);
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
transform: translate(-2px, 0px) rotate(1deg);
|
||||||
|
}
|
||||||
|
30% {
|
||||||
|
transform: translate(1px, 2px) rotate(0deg);
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
transform: translate(1px, -1px) rotate(1deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translate(-1px, 3px) rotate(-1deg);
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
transform: translate(-1px, 1px) rotate(0deg);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: translate(3px, 1px) rotate(-1deg);
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
transform: translate(-2px, -1px) rotate(1deg);
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
transform: translate(2px, 1px) rotate(0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.longfazers {
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.longfazers span {
|
||||||
|
position: absolute;
|
||||||
|
height: 2px;
|
||||||
|
width: 20%;
|
||||||
|
background: #626466;
|
||||||
|
}
|
||||||
|
.longfazers span:nth-child(1) {
|
||||||
|
top: 20%;
|
||||||
|
animation: lf .6s linear infinite;
|
||||||
|
animation-delay: -5s;
|
||||||
|
}
|
||||||
|
.longfazers span:nth-child(2) {
|
||||||
|
top: 40%;
|
||||||
|
animation: lf2 .8s linear infinite;
|
||||||
|
animation-delay: -1s;
|
||||||
|
}
|
||||||
|
.longfazers span:nth-child(3) {
|
||||||
|
top: 60%;
|
||||||
|
animation: lf3 .6s linear infinite;
|
||||||
|
}
|
||||||
|
.longfazers span:nth-child(4) {
|
||||||
|
top: 80%;
|
||||||
|
animation: lf4 .5s linear infinite;
|
||||||
|
animation-delay: -3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes lf {
|
||||||
|
0% {
|
||||||
|
left: 200%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: -200%;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes lf2 {
|
||||||
|
0% {
|
||||||
|
left: 200%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: -200%;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes lf3 {
|
||||||
|
0% {
|
||||||
|
left: 200%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: -100%;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes lf4 {
|
||||||
|
0% {
|
||||||
|
left: 200%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: -100%;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<noscript>
|
<noscript>
|
||||||
<div>
|
<div>
|
||||||
<h2>Error: Javascript is off</h2>
|
<h2>Error: Javascript is off</h2>
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,82 @@ import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Router from './router';
|
import Router from './router';
|
||||||
|
|
||||||
import { Config } from "./model/"
|
import { Config } from "./model/";
|
||||||
|
|
||||||
import './assets/css/reset.scss';
|
import './assets/css/reset.scss';
|
||||||
|
|
||||||
|
const $loader = document.querySelector(".index-loader");
|
||||||
|
const $loader_guy = $loader.querySelector(".guy");
|
||||||
|
const $loader_particules = $loader.querySelector(".longfazers");
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", () => {
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
const className = 'ontouchstart' in window ? 'touch-yes' : 'touch-no';
|
const className = 'ontouchstart' in window ? 'touch-yes' : 'touch-no';
|
||||||
document.body.classList.add(className);
|
document.body.classList.add(className);
|
||||||
|
|
||||||
Config.refresh().then(() => {
|
function render(){
|
||||||
ReactDOM.render(<Router/>, document.getElementById('main'));
|
ReactDOM.render(<Router/>, document.getElementById('main'));
|
||||||
|
return Promise.resolve();
|
||||||
|
};
|
||||||
|
function waitFor(n){
|
||||||
|
return new Promise((done) => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
window.requestAnimationFrame(() => done());
|
||||||
|
}, n);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function removeLoaderWithAnimation(){
|
||||||
|
if(!$loader) return Promise.resolve();
|
||||||
|
if(!$loader.animate){
|
||||||
|
$loader.remove();
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
const moveTheGuy = () => {
|
||||||
|
return new Promise((done) => {
|
||||||
|
$loader_guy.animate([
|
||||||
|
{ left: "40%", opacity: 1 },
|
||||||
|
{ left: "110%", opacity: 0.5 }
|
||||||
|
], {
|
||||||
|
easing: "ease-out",
|
||||||
|
duration: 1000,
|
||||||
|
iterations: 1,
|
||||||
|
}).onfinish = () => {
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const FadeParticules = () => {
|
||||||
|
return new Promise((done) => {
|
||||||
|
$loader_particules.animate([
|
||||||
|
{ opacity: 1 },
|
||||||
|
{ opacity: 0 }
|
||||||
|
], {
|
||||||
|
duration: 500,
|
||||||
|
iterations: 1,
|
||||||
|
}).onfinish = () => {
|
||||||
|
$loader_particules.remove();
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return Promise.all([moveTheGuy(), FadeParticules()]).then(() => {
|
||||||
|
$loader.remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function removeLoader(){
|
||||||
|
if($loader) $loader.remove();
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.refresh().then(() => {
|
||||||
|
const timeSinceBoot = new Date() - window.initTime;
|
||||||
|
if(timeSinceBoot >= 2000){
|
||||||
|
const timeoutToAvoidFlickering = timeSinceBoot > 2500 ? 0 : 500;
|
||||||
|
return waitFor(timeoutToAvoidFlickering)
|
||||||
|
.then(removeLoaderWithAnimation)
|
||||||
|
.then(render);
|
||||||
|
}
|
||||||
|
return removeLoader().then(render);
|
||||||
});
|
});
|
||||||
|
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue