added a basic loading screen...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-08-18 17:48:53 +03:00
parent a6d04eff3b
commit 1f3adbbfb1
4 changed files with 173 additions and 30 deletions

View File

@ -45,7 +45,7 @@
- actions:
- "from selection"
- ~~Gallery: drag-n-drop~~
- ~~drop files/images~~ -- add loading indicator
- ~~drop files/images~~
- ~~drag to sort~~
- **drag marked**
- touch...

View File

@ -84,6 +84,8 @@ body {
.gallery {
--base-layer: 10;
position: relative;
padding-top: var(--gallery-padding-top);
padding-bottom: var(--gallery-padding-bottom);
padding-left: calc(
@ -93,6 +95,7 @@ body {
color: var(--gallery-text-color);
background: var(--gallery-background-color);
font-family: sans-serif;
overflow-x: clip;
}
@ -580,6 +583,49 @@ body {
/********************************************************* Splash ****/
.gallery .loading {
position: absolute;
display: block;
top: 0;
left: 0;
width: 100%;
height:100%;
text-align: center;
z-index: calc(var(--base-layer) * 2);
background: white;
}
.gallery.ready .loading {
animation: fadeOutAnimation ease 2s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
pointer-events: none;
}
@keyframes fadeOutAnimation {
0% {
opacity: 1;
}
100% {
opacity: 0;
visibility: hidden;
}
}
.gallery.ready .loading * {
display: none;
}
.gallery:not(.ready) .images img {
visibility: hidden;
}
/********************************************************** Utils ****/
.gallery:not(.lightboxed):not(.detailed) .hide-in-gallery,
@ -588,6 +634,40 @@ body {
display: none;
}
/* loading animation... */
.gallery .loading>div {
--bar-size: 0.2rem;
position: sticky;
top: var(--bar-size);
}
.gallery .loading>div:before,
.gallery .loading>div:after {
content: "";
position: absolute;
top: calc(var(--bar-size) * -1);
left: 0;
width: 100%;
height: var(--bar-size);
opacity: 0.3;
}
.gallery .loading>div:after {
background: gray;
animation: loadingBarAnimation ease infinite alternate 2s;
}
.gallery .loading>div:before {
width: 50%;
background: gray;
animation: loadingBarAnimation ease infinite alternate 1.5s;
}
@keyframes loadingBarAnimation {
0% {
translate: -100%;
}
100% {
translate: 100%;
}
}
/**********************************************************************

View File

@ -16,7 +16,7 @@ body.splash {
}
/* fade-in body... */
/* XXX add real splash screen... */
/* XXX add real splash screen...
body:not(.splash) {
animation: fadeInAnimation ease 2s;
animation-iteration-count: 1;
@ -31,6 +31,7 @@ body:not(.splash) {
opacity: 1;
}
}
*/
</style>
<script>
@ -89,6 +90,7 @@ For more info see: <a href="./README.md">README.md</a>
<h3>Settings</h3>
<button onclick="gallery.toolbar.movable()">toggle toolbar drag</button>
<button onclick="gallery.toggleLoading()">toggle splash screen</button>
<hr>
@ -175,6 +177,10 @@ For more info see: <a href="./README.md">README.md</a>
<div class="button close"></div>
</div>
</div>
<!-- loading screen -->
<div class="loading">
<div></div>
</div>
</div>
</body>

View File

@ -22,6 +22,7 @@ var RESIZE_SETTLE_TIMEOUT = 16
//---------------------------------------------------------------------
// Generic stuff...
var patchFlexRows =
function(elems,
@ -133,7 +134,6 @@ function(elem) {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// XXX move to types.js...
var ruler
var px2rem = function(px){
if(!ruler){
@ -150,9 +150,11 @@ var rem2px = function(rem){
var px = ruler.offsetWidth
return px }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var getTouch = function(evt, id){
var getTouch =
function(evt, id){
if(id != null && id !== false && evt.targetTouches){
for(var k in evt.targetTouches){
if(evt.targetTouches[k]?.identifier == id){
@ -171,41 +173,63 @@ var getTouch = function(evt, id){
// - scroll into view the dragged element
// - bound it by screen
// XXX need to check if element already set as movable...
var moveable = function(elem, options={}){
// XXX docs...
HTMLElement.prototype.moveable =
function(options={}){
var elem = this
if(elem.dataset.movable){
throw new Error('element already movable.') }
elem.dataset.movable = true
// options...
var {
cls,
handle,
// CSS class added to element while it is dragged...
cls = 'movable',
// Drag handle element -- watches the drag events...
handle = elem,
// Blement bounding box used to check bounds...
box = elem,
// Bounds object...
// can be:
// false
// {
// top: <top>,
// left: <left>,
// bottom: <bottom>,
// <right>: <right>,
// }
// XXX add support for:
// css selector
// element
bounds,
// can be:
// 'x'
// 'y'
// undefined
lock,
start = function(elem, data){
bounds
?? (data.bounds = bounds)
return data },
beforeMove,
// start(<elem>, <data>)
// -> undefined
// -> <data>
start,
// can be:
// 'strict'
// 'scroll' / true
// false
keepInView = true,
// move(<elem>, <data>)
move = function(elem, data){
data.x != null
&& (elem.style.left = data.x + 'px')
data.y != null
&& (elem.style.top = data.y + 'px') },
// end(<elem>, <data>)
end,
ignoreBounds = false,
} = options
handle = typeof(handle) == 'string' ?
handle =
typeof(handle) == 'string' ?
elem.querySelector(handle)
: handle instanceof Element ?
handle
: elem
: handle
var data
var handleMoveStart = function(evt){
@ -219,7 +243,7 @@ var moveable = function(elem, options={}){
var y = evt.clientY
?? evt.targetTouches[0].clientY
data = {
bounds: false,
bounds: bounds,
offset: {
x: x - elem.offsetLeft,
y: y - elem.offsetTop,
@ -248,7 +272,8 @@ var moveable = function(elem, options={}){
data.x =
lock == 'x' ?
null
: data.bounds != null ?
: (!ignoreBounds
&& data.bounds != null) ?
Math.min(
data.bounds.right,
Math.max(
@ -258,7 +283,8 @@ var moveable = function(elem, options={}){
data.y =
lock == 'y' ?
null
: data.bounds != null ?
: (!ignoreBounds
&& data.bounds != null) ?
Math.min(
data.bounds.bottom,
Math.max(
@ -266,13 +292,15 @@ var moveable = function(elem, options={}){
y - data.offset.y))
: y - data.offset.y
// restrict to viewport...
if(keepInView == 'strict'){
if(!ignoreBounds
&& keepInView == 'strict'){
var t, l
var bb = elem.getBoundingClientRect()
var screen = {
top: t = elem.offsetTop - bb.top,
left: l = elem.offsetLeft - bb.left,
bottom: window.innerHeight + t - elem.offsetHeight,
right: window.innerWidth + l - elem.offsetWidth,
top: t = box.offsetTop - bb.top,
left: l = box.offsetLeft - bb.left,
bottom: window.innerHeight + t - box.offsetHeight,
right: window.innerWidth + l - box.offsetWidth,
}
data.x = Math.min(
screen.right,
@ -294,7 +322,8 @@ var moveable = function(elem, options={}){
&& move(elem, data)
// keep in view...
// NOTE: this works best with CSS's scroll-margin...
;(keepInView == 'scroll'
!ignoreBounds
&& (keepInView == 'scroll'
|| keepInView === true)
&& elem.scrollIntoView({ block: 'nearest' })
delete data.animate }) } } }
@ -872,6 +901,18 @@ var Gallery = {
img.classList.toggle('marked') }
return this.updateMarkers() },
get loading(){
return !this.dom.classList.contains('ready') },
showLoading: function(){
this.dom.classList.remove('ready')
return this },
hideLoading: function(){
this.dom.classList.add('ready')
return this },
toggleLoading: function(){
this.dom.classList.toggle('ready')
return this },
show: function(){
return this.showLightbox() },
showLightbox: function(){
@ -1189,6 +1230,8 @@ var Gallery = {
// non-local drag...
if(!dragged){
that.showLoading()
var expand = (evt.shiftKey && dragged_over) ?
that.images.indexOf(dragged_over)
: undefined
@ -1231,12 +1274,14 @@ var Gallery = {
.flat())
.then(
function(images){
that.hideLoading()
// no images...
if(images.length == 0){
return }
return that.load(images, expand) },
function(err){
// XXX handle errors...
that.hideLoading()
}) }
dragged
&& dragged.classList.remove('dragged')
@ -1259,7 +1304,8 @@ var Gallery = {
return this
.updateMarkers()
.update() },
.update()
.hideLoading() },
}
@ -1270,8 +1316,10 @@ var Toolbar = {
gallery: undefined,
cls: 'toolbar',
// time to hold the handle to toggle autohide...
hold: 300,
// autohide timeout...
toolbar_autohide: 2000,
// XXX make these generic...
@ -1354,10 +1402,7 @@ var Toolbar = {
// toolbar: move...
// XXX to drag anywhere on the elem we need to prevent
// clicks while dragging...
// XXX prevent from scrolling off screen when placed a bottom
// and scrolling up -- i.e. keep within viewport and gallery
// at all times...
moveable(toolbar, {
toolbar.moveable({
cls: 'moving',
handle: '.drag-handle',
// set bounds...
@ -1378,6 +1423,15 @@ var Toolbar = {
data.y != null
&& elem.style.setProperty('--move-y', data.y + 'px') }, })
// keep toolbar in view while scrolling...
// NOTE: top is taken care of by position: sticky...
window.addEventListener('scroll', function(evt){
var bb = toolbar.getBoundingClientRect()
if(window.innerHeight <= bb.bottom){
var top = toolbar.offsetTop - bb.top
var bottom = window.innerHeight + top - toolbar.offsetHeight
toolbar.style.setProperty('--move-y', bottom + 'px') } })
return this },
}
@ -1618,6 +1672,7 @@ var Details = {
}
//---------------------------------------------------------------------
var setupGallery = function(gallery){
@ -1631,6 +1686,8 @@ var setup = function(){
window.gallery = setupGallery(gallery) }
// keyboard...
document.addEventListener('keydown', function(evt){
if(window.gallery.loading){
return }
var key = evt.key
if(key in keyboard){
keyboard[key](evt) } }) }