Files
david/src/widgets/lightbox/Lightbox.js
T
2025-11-25 01:21:34 +02:00

326 lines
6.2 KiB
JavaScript

import './lightbox.css';
import { Ut } from '../../utils/Ut';
import { $ } from '../../utils/dom';
import { Boot } from '../../core/Boot';
////////////////////
// LightBox
////////////////////
export class Lightbox {
/**
* Lightbox, Contructor
*/
constructor(target) {
this.target = target;
if (this.target.dxData('lightbox')) {
return;
}
this.target.dxData('lightbox', this);
this.setEvents();
this.widget = Boot.intData.widget.lightbox.children;
this.opened = false;
this.busy = false;
}
resize(load) {
this.img.style.removeProperty('width');
this.img.style.removeProperty('height');
let imWidth = this.img.dxGetProp('width').split('px')[0];
let imHeight = this.img.dxGetProp('height').split('px')[0];
let viewWidth = window.innerWidth - (0.1 * window.innerWidth);
let viewHeight = window.innerHeight - (0.2 * window.innerHeight);
if (imWidth > viewWidth) {
imWidth = viewWidth + 'px';
imHeight = 'auto';
}
else if (imHeight > viewHeight) {
imHeight = viewHeight + 'px';
imWidth = 'auto';
}
this.img.style.width = imWidth;
this.img.style.height = imHeight;
imWidth = this.img.dxGetProp('width').split('px')[0],
imHeight = this.img.dxGetProp('height').split('px')[0];
this.ui.style.width = imWidth + 'px';
this.ui.style.height = imHeight + 'px';
if (load) {
this.update();
}
}
update() {
this.img.classList.remove('hidden');
this.ui.append(this.img);
this.img.focus();
this.img.classList.add('loaded');
this.loader.classList.add('hidden');
this.updateLabel();
this.busy = false;
}
updateLabel() {
if (this.title) {
this.labelTitle.classList.remove('hide');
this.labelTitle.textContent = this.title;
}
else {
this.labelTitle.classList.add('hide');
}
this.labelCounter.textContent = this.widget.label.position.replace('%index', this.index + 1).replace('%count', this.square.length);
}
create(a, update) {
this.busy = true;
this.title = a.getAttribute('title');
let src = a.href;
if (update) {
this.loader.classList.remove('hidden');
this.img.classList.add('hidden');
this.img.setAttribute('src', src);
}
else {
this.modal = $('<div class="sp-lightbox-overlay" />');
this.ui = $('<div class="sp-lightbox-container" />');
this.loader = $('<div class="loader" />');
this.arrowLeft = $('<a class="nav-arrow arrow-left"></a>');
this.arrowRight = $('<a class="nav-arrow arrow-right"></a>');
let label = $('<div class="nav-label"> \
<div> \
<div class="label-title"></div> \
<div class="label-number"></div> \
</div> \
<a href="#" class="close-popup"> \
<span class="container-close"> \
<span class="border border-1"></span> \
<span class="border border-2"></span> \
</span> \
<span class="close-btn">ÎNCHIDE</span> \
</a> \
</div>');
this.labelTitle = label.dxFind('.label-title');
this.labelCounter = label.dxFind('.label-number');
this.close = label.dxFind('.close-popup');
this.modal.append(this.ui);
this.ui.append(this.loader);
if (!Ut.device.touchCapable) {
this.ui.append(this.arrowLeft);
this.ui.append(this.arrowRight);
}
this.ui.append(label);
document.body.append(this.modal);
this.img = $('<img src="'+ src +'" />');
this.opened = true;
}
this.img.classList.add('hidden');
this.img.classList.remove('loaded');
document.body.append( this.img );
// Set Arrows
this.arrowRight.classList.toggle('hide', this.square.length == this.index + 1);
this.arrowLeft.classList.toggle('hide', !this.index);
Stack.add(this);
}
hidden() {
this.modal.remove();
this.busy = false;
this.opened = false;
document.dxOff('keyup.lightbox' + this.ekey + ' resize.lightbox' + this.ekey + ' orientationchange.lightbox' + this.ekey);
}
setEvents() {
let that = this,
tm = null;
// Click inside target
this.target.dxOn('click.lightbox', 'a', function(e) {
// No target attr
if (this.target) {
return;
}
e.preventDefault();
// Already opened
if (that.opened) {
return;
}
// Set square at this point
that.square = that.target.dxFind('a:not([target])', true);
// Set Start Index
that.index = this.dxIndex(that.square);
that.create(this);
// UI TransitionEnd Handler
that.ui.addEventListener('transitionend', function(e) {
if (that.busy && (e.propertyName == 'width' || e.propertyName == 'height')) {
that.update();
}
});
// Load Img Handler
that.img.dxOn('load', function() {
that.resize(true);
});
// Click on UI
that.ui.dxOn('click', function(e) {
e.stopPropagation();
});
// Nav Arrows Handlers
that.arrowLeft.dxOn('click', function(e) {
that.prevIm();
});
that.arrowRight.dxOn('click', function(e) {
that.nextIm();
});
// Swipe Handlers
that.ui.dxOn('swipeleft', function() {
that.nextIm();
});
that.ui.dxOn('swiperight', function() {
that.prevIm();
});
// Click On Modal
that.modal.dxOn('click', function() {
that.hidden();
});
// Click on close icon
that.close.dxOn('click', function(e) {
e.stopPropagation();
that.hidden();
});
// Resize Handler
window.dxOn('resize.popup.' + that.ekey + ' ' + 'orientationchange.popup' + that.ekey, function() {
if (tm) {
clearTimeout(tm);
tm = null;
}
tm = setTimeout(_ => {
that.resize();
}, 300);
});
// Keydown Handler
document.dxOn('keydown.popup' + this.ekey, function(e) {
switch (e.key) {
case 'ArrowLeft':
that.prevIm();
break;
case 'ArrowRight':
that.nextIm();
break;
case 'Escape':
that.hidden();
break;
}
});
});
}
prevIm() {
if (this.busy || !this.index) {
return;
}
this.index--;
this.create(this.square.item(this.index), true);
}
nextIm() {
if (this.busy || this.square.length == this.index + 1) {
return;
}
this.index++;
this.create(this.square.item(this.index), true);
}
destroy() {
this.modal.remove();
this.target.dxOff('click.lightbox');
document.dxOff('keyup.lightbox' + this.ekey + ' resize.lightbox' + this.ekey + ' orientationchange.lightbox' + this.ekey);
Stack.delete(this);
this.target.dxRemoveData('lightbox');
}
}
//Ut.extendNodeUx(Lightbox);