@drozdik.m/image-gallery
Version:
Efficient native modal image gallery.
404 lines (403 loc) • 17.1 kB
JavaScript
exports.__esModule = true;
exports.ImageGallery = void 0;
var GalleryImage_1 = require("./GalleryImage");
var loading_animation_1 = require("@drozdik.m/loading-animation");
var rem_1 = require("@drozdik.m/rem");
var window_events_1 = require("@drozdik.m/window-events");
var dimensions_helper_1 = require("@drozdik.m/dimensions-helper");
var ImageGallery = /** @class */ (function () {
//--------------------------------------------------
//----------CONSTRUCTOR-----------------------------
//--------------------------------------------------
function ImageGallery(images) {
//--------------------------------------------------
//----------VARIABLES-------------------------------
//--------------------------------------------------
this.images = [];
this.currentImageIndex = 0;
this.showAnimationLength = 250;
this.showTimeout = null;
this.isOpen = false;
ImageGallery.EnsureEnvironment();
this.images = images;
if (this.images.length == 0)
console.warn("Gallery recieved empty image array");
var object = this;
ImageGallery.GetArrowLeft().addEventListener("click", function (e) {
if (!object.isOpen)
return;
e.preventDefault ? e.preventDefault() : (e.returnValue = false);
object.Previous();
});
ImageGallery.GetArrowRight().addEventListener("click", function (e) {
if (!object.isOpen)
return;
e.preventDefault ? e.preventDefault() : (e.returnValue = false);
object.Next();
});
ImageGallery.GetBackground().addEventListener("click", function (e) {
if (!object.isOpen)
return;
e.preventDefault ? e.preventDefault() : (e.returnValue = false);
object.Close();
});
ImageGallery.GetClose().addEventListener("click", function (e) {
if (!object.isOpen)
return;
e.preventDefault ? e.preventDefault() : (e.returnValue = false);
object.Close();
});
window_events_1.WindowEvents.OnResize.Add(function () {
if (object.isOpen)
object.ResizeCurrentImage();
});
}
//--------------------------------------------------
//----------METHODS---------------------------------
//--------------------------------------------------
/**
* Moves to the next in the gallery
* */
ImageGallery.prototype.Next = function () {
this.ShowImage(this.currentImageIndex + 1);
};
/**
* Moves to the previous in the gallery
* */
ImageGallery.prototype.Previous = function () {
this.ShowImage(this.currentImageIndex - 1);
};
/**
* Tells if the gallery is at the last image
* */
ImageGallery.prototype.IsAtLast = function () {
return this.currentImageIndex == this.images.length - 1;
};
/**
* Tells if the gallery is at the last image
* */
ImageGallery.prototype.IsAtFirst = function () {
return this.currentImageIndex == 0;
};
/**
* Opens the gallery if not. Show a gallery image.
* @param index Index of the gallery image to show.
*/
ImageGallery.prototype.ShowImage = function (index) {
//Check for zero condition
if (this.images.length == 0)
return;
index = (index + this.images.length) % this.images.length;
this.currentImageIndex = index;
//console.log("current: " + this.currentImageIndex);
if (!this.isOpen)
this.Open();
//Set end/start classes
var imageGallery = ImageGallery.GetImageGallery();
imageGallery.classList.remove("atLast");
imageGallery.classList.remove("atFirst");
if (this.IsAtLast())
imageGallery.classList.add("atLast");
if (this.IsAtFirst())
imageGallery.classList.add("atFirst");
//Load and prerender images
var image = this.images[this.currentImageIndex];
//this.PrerenderImage(index + 1);
//this.PrerenderImage(index + 2);
//this.PrerenderImage(index - 1);
//Add loading
if (image.IsLoaded()) {
ImageGallery.GetLoadingAnimation().Hide();
this.AppendImage(image);
}
else {
ImageGallery.GetImageGalleryTarget().innerHTML = "";
//LoadingAnimation.Show();
ImageGallery.GetLoadingAnimation().Show();
image.Preload();
var object_1 = this;
var targetImageId_1 = this.currentImageIndex;
image.OnLoad.Add(function () {
if (object_1.currentImageIndex != targetImageId_1)
return;
object_1.AppendImage(image);
//LoadingAnimation.Hide();
ImageGallery.GetLoadingAnimation().Hide();
});
}
};
/**
* Appends an image into the DOM
* @param image Image to append
*/
ImageGallery.prototype.AppendImage = function (image) {
//Append it
var appendTarget = ImageGallery.GetImageGalleryTarget();
appendTarget.innerHTML = "";
appendTarget.appendChild(image.GetResultElement());
//Counter
var counter = document.createElement("span");
counter.innerHTML = "".concat(this.currentImageIndex + 1, "/").concat(this.images.length);
counter.classList.add("currentGalleryImageNumber");
appendTarget.querySelector(".currentGalleryImageWrapper").appendChild(counter);
this.ResizeCurrentImage();
};
/**
* Resizes current image into proper shape
* */
ImageGallery.prototype.ResizeCurrentImage = function () {
var image = this.images[this.currentImageIndex];
if (!image)
return;
//CALCULATE IMAGE SIZE
//Calculate ratios
var widthMargin = rem_1.Rem.InPx() * 2;
var heightMargin = rem_1.Rem.InPx() * 4;
var screenNaturalWidth = window_events_1.WindowEvents.Width();
var screenNaturalHeight = window_events_1.WindowEvents.Height();
var screenWidth = window_events_1.WindowEvents.Width() - (widthMargin * 2);
var screenHeight = window_events_1.WindowEvents.Height() - (heightMargin * 2);
var imageNaturalWidth = image.GetImageNaturalWidth();
var imageNaturalHeight = image.GetImageNaturalHeight();
//let imageWidthRatio = imageNaturalWidth;
var imageHeightRatio = imageNaturalHeight;
var ratioCorrection = imageNaturalWidth / screenNaturalWidth;
//let screenWidthRatio = screenNaturalWidth * ratioCorrection;
var screenHeightRatio = screenNaturalHeight * ratioCorrection;
//console.log("imageWidthRatio " + imageWidthRatio);
//console.log("imageHeightRatio " + imageHeightRatio);
//console.log("screenWidthRatio " + screenWidthRatio);
//console.log("screenHeightRatio " + screenHeightRatio);
//Compare height ratios (width are the same)
var imageElement = image.GetImageElement();
//let resizedElement = ImageGallery.GetResizeTarget();
if (imageHeightRatio < screenHeightRatio) {
//Use width as correct resize axis
if (imageNaturalWidth < screenWidth) {
//Image is smaller than screen
imageElement.style.width = imageNaturalWidth + "px";
imageElement.style.height = "auto";
}
else {
//Image is bigger than screen
imageElement.style.width = screenWidth + "px";
imageElement.style.height = "auto";
}
}
else {
//Use height as correct resize axis
//Use width as correct resize axis
if (imageNaturalHeight < screenHeight) {
//Image is smaller than screen
imageElement.style.height = imageNaturalHeight + "px";
imageElement.style.width = "auto";
}
else {
//Image is bigger than screen
imageElement.style.height = screenHeight + "px";
imageElement.style.width = "auto";
}
}
//Center the image
var imageResizeHelper = new dimensions_helper_1.DimensionsHelper(imageElement);
var resizeTarget = ImageGallery.GetResizeTarget();
var resizeTargetHelper = new dimensions_helper_1.DimensionsHelper(resizeTarget);
resizeTargetHelper.SetHeight(imageResizeHelper.Height());
resizeTargetHelper.SetWidth(imageResizeHelper.Width());
var offsetLeft = (screenNaturalWidth - resizeTargetHelper.Width()) / 2;
var offsetTop = (screenNaturalHeight - resizeTargetHelper.Height()) / 2;
resizeTarget.style.top = (offsetTop / 2) + "px";
resizeTarget.style.left = offsetLeft + "px";
};
/**
* Invoked prerender method in a gallery image
* @param index Target gallery image index
*/
ImageGallery.prototype.PrerenderImage = function (index) {
index = (index + this.images.length) % this.images.length;
this.images[index].Preload();
};
/**
* Opens the gallery at an image
* @param index The initial image index
*/
ImageGallery.prototype.Open = function () {
if (this.isOpen)
return;
this.isOpen = true;
if (this.showTimeout != null)
clearTimeout(this.showTimeout);
ImageGallery.GetImageGallery().style.display = "block";
this.ResizeCurrentImage();
setTimeout(function () {
var gallery = ImageGallery.GetImageGallery();
gallery.classList.add("open");
gallery.classList.remove("closed");
}, 1);
};
/**
* Closes the image gallery
* */
ImageGallery.prototype.Close = function () {
if (!this.isOpen)
return;
this.isOpen = false;
var gallery = ImageGallery.GetImageGallery();
gallery.classList.remove("open");
gallery.classList.add("close");
if (this.showTimeout != null)
clearTimeout(this.showTimeout);
var object = this;
this.showTimeout = setTimeout(function () {
ImageGallery.GetImageGallery().style.display = "none";
object.showTimeout = null;
}, this.showAnimationLength);
};
/*
* Tells if this image gallery is open
* */
ImageGallery.prototype.IsOpen = function () {
return this.isOpen;
};
//--------------------------------------------------
//----------FACTORY---------------------------------
//--------------------------------------------------
/**
* Creates an image gallery based on selector to all links/gallery images.
* @param selector Selector to gallery images as links
*/
ImageGallery.FromLinksSelector = function (selector) {
var links = document.querySelectorAll(selector);
var images = [];
//Add to gallery image array
for (var i = 0; i < links.length; i++) {
if (links.item(i).tagName != "A")
console.warn("One of elements from FromLinksSelector is not link");
images.push(GalleryImage_1.GalleryImage.FromLinkElement(links.item(i)));
}
var res = new ImageGallery(images);
var _loop_1 = function (i) {
links[i].addEventListener("click", function (e) {
e.preventDefault ? e.preventDefault() : (e.returnValue = false);
res.ShowImage(i);
});
};
//Setup events
for (var i = 0; i < links.length; i++) {
_loop_1(i);
}
return res;
};
/**
* Ensures that there is suitable environment created for ImageGallery functionality
* */
ImageGallery.EnsureEnvironment = function () {
if (ImageGallery.environmentInitiated)
return;
var environmentHTML = "<div id=\"imageGallery\">\n <div id=\"imageGalleryBackground\"> </div>\n <div id=\"imageGalleryCenteringWrapper\">\n\n <div id=\"imageGalleryTarget\"></div>\n <button type=\"button\" id=\"imageGalleryLeft\">\n Previous\n <div class=\"icon\"> </div>\n </button>\n <button type=\"button\" id=\"imageGalleryRight\">\n Next\n <div class=\"icon\"> </div>\n </button>\n <button type=\"button\" id=\"imageGalleryClose\">\n Close\n <div class=\"icon\"> </div>\n </button>\n </div>\n </div>";
//Target example:
/*
<div class="currentGalleryImageWrapper">
<img class="currentGalleryImage" src="images/test1.jpgx " />
<span class="currentGalleryImageTitle">Image title</span>
<span class="currentGalleryImageNumber">5/10</span>
</div>
*/
document.body.insertAdjacentHTML("beforeend", environmentHTML);
ImageGallery.environmentInitiated = true;
};
/**
* Returns target for image operations and appending
* */
ImageGallery.GetImageGalleryTarget = function () {
if (ImageGallery.imageGalleryTarget == null) {
ImageGallery.EnsureEnvironment();
ImageGallery.imageGalleryTarget = document.getElementById("imageGalleryTarget");
}
return ImageGallery.imageGalleryTarget;
};
/**
* Returns the container for resizing
* */
ImageGallery.GetResizeTarget = function () {
if (ImageGallery.resizeTarget == null) {
ImageGallery.EnsureEnvironment();
ImageGallery.resizeTarget = document.getElementById("imageGalleryCenteringWrapper");
}
return ImageGallery.resizeTarget;
};
/**
* Returns button for closing the gallery
* */
ImageGallery.GetClose = function () {
if (ImageGallery.close == null) {
ImageGallery.EnsureEnvironment();
ImageGallery.close = document.getElementById("imageGalleryClose");
}
return ImageGallery.close;
};
/**
* Returns the image gallery environment root div
* */
ImageGallery.GetImageGallery = function () {
if (ImageGallery.imageGallery == null) {
ImageGallery.EnsureEnvironment();
ImageGallery.imageGallery = document.getElementById("imageGallery");
}
return ImageGallery.imageGallery;
};
/**
* Return environment arrow to the left
* */
ImageGallery.GetArrowLeft = function () {
if (ImageGallery.arrowLeft == null) {
ImageGallery.EnsureEnvironment();
ImageGallery.arrowLeft = document.getElementById("imageGalleryLeft");
}
return ImageGallery.arrowLeft;
};
/**
* Return environment arrow to the right
* */
ImageGallery.GetArrowRight = function () {
if (ImageGallery.arrowRight == null) {
ImageGallery.EnsureEnvironment();
ImageGallery.arrowRight = document.getElementById("imageGalleryRight");
}
return ImageGallery.arrowRight;
};
/**
* Return environment background
* */
ImageGallery.GetBackground = function () {
if (ImageGallery.background == null) {
ImageGallery.EnsureEnvironment();
ImageGallery.background = document.getElementById("imageGalleryBackground");
}
return ImageGallery.background;
};
/**
* Returns the loading animation
* */
ImageGallery.GetLoadingAnimation = function () {
if (!ImageGallery.loadingAnimation) {
var centeringWrapper = ImageGallery.GetResizeTarget();
ImageGallery.loadingAnimation = new loading_animation_1.LoadingAnimation(centeringWrapper);
}
return ImageGallery.loadingAnimation;
};
//--------------------------------------------------
//----------ENVIRONMENT-----------------------------
//--------------------------------------------------
ImageGallery.environmentInitiated = false;
ImageGallery.imageGalleryTarget = null;
ImageGallery.imageGallery = null;
ImageGallery.arrowLeft = null;
ImageGallery.arrowRight = null;
ImageGallery.close = null;
ImageGallery.background = null;
ImageGallery.resizeTarget = null;
ImageGallery.loadingAnimation = null;
return ImageGallery;
}());
exports.ImageGallery = ImageGallery;