I have a problem with my Jquery code. I’m trying to make a gallery. I want that when a person clicks on a image, to attach that image to a div and display it in the center of the screen. My problem is with images that are larger than the current screen size. I resize the image to match the screen size, but when I fade it in into the div it lags. I can’t figure out why is that, and I’m sure it’s not just because the image is big, if I don’t resize it and let is go off the screen it fades in just fine.
The HTML :
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Gallery</title>
<link rel="stylesheet" href="Gallery.css">
</head>
<body>
<div class="gallery">
<div class="images">
<ul class="resize">
<li><img src="img/img1.jpg" alt="image1"></li>
<li><img src="img/img2.jpg" alt="image2"></li>
<li><img src="img/img3.jpg" alt="image3"></li>
<li><img src="img/img4.jpg" alt="image4"></li>
<li><img src="img/img5.jpg" alt="image5"></li>
<li><img src="img/img6.jpg" alt="image6"></li>
<li><img src="img/img7.jpg" alt="image7"></li>
<li><img src="img/img8.jpg" alt="image8"></li>
</ul>
</div>
<div class="backgroundOpacity"></div>
<div class="imageBox">
<img class="displayImage" src="" alt="displayImage">
<img class="loadingGif" src="img/loading.gif" alt="loadgindGif">
<img class="closeImage" src="img/closeImage.png" alt="close">
<p class="imageNumber">1</p>
</div>
</div>
<script type="text/javascript" src="jquery-1.8.2.js"></script>
<script type="text/javascript" src="Gallery.js"></script>
<script type="text/javascript">
var content = $('.gallery'),
gallery = new Gallery(content);
</script>
</body>
</html>
The CSS :
*{
margin: 0;
padding: 0;
}
/*-------------------------gallery-----------------------*/
.gallery{
width: 1300px;
margin: 100px auto 0;
};
/*------------------------------------------------*/
/*-------------------------images-----------------------*/
.images{
width: inherit;
height: inherit;
}
.images li{
list-style-type: none;
float: left;
margin: 0 20px 20px 0;
width: 300px;
height: 150px;
cursor: pointer;
}
.resize img{
width: inherit;
height: inherit;
}
/*------------------------------------------------*/
/*-------------------------imageBox-----------------------*/
.imageBox{
background-color: white;
clear: both;
width: 300px;
height: 150px;
display: none;
position: fixed;
overflow: visible;
}
.backgroundOpacity{
background-color: black;
width: 5000px;
height: 5000px;
position: fixed;
left: 0px;
top: 0px;
opacity: 0.7;
display: none;
}
.loadingGif{
display: block;
position: absolute;
}
.displayImage{
display: none;
}
.closeImage{
position: absolute;
top: -10px;
right: -10px;
cursor: pointer;
}
.imageNumber{
position: absolute;
bottom: 0px;
left: 0px;
font-family: sans-serif;
font-size: 18px;
font-weight: bold;
opacity: 0.6;
}
/*------------------------------------------------
*/
and the Java :
function Gallery (galleryDiv, resizeDuration, fadeInDuration) {
this.config = {
resizeDuration: 1000,
fadeInDuration: 500
};
this.galleryDiv = galleryDiv;
this.imagesUl = this.galleryDiv.find('.images ul');
this.images = this.imagesUl.find('img');
this.backgroundOpacity = this.galleryDiv.find('.backgroundOpacity'); // the background div which when is clicked hides the imageBox
this.imageBox = this.galleryDiv.find('.imageBox'); // where the images will be displayed when they'r clicked
this.closeButton = this.imageBox.find('.closeImage'); // top-right x
this.loadingGif = this.imageBox.find('.loadingGif'); // the animated gif that gives the effect of 'loading'
this.imageNumber = this.imageBox.find('.imageNumber'); // bottom-left text
this.displayImage = this.imageBox.find('.displayImage'); // image to be displayed
this.imagesWidth = new Array(); // the images default widths
this.imagesHeight = new Array(); // the images default heights
this.imagesLength = this.images.length // number of images
this.imageBoxSize = new Array(); // [0] is width, [1] is height
this.loadingGifSize = new Array() // [0] is width, [1] is height
this.resizeDuration = resizeDuration || this.config.resizeDuration; // duration to resize imageBox
this.fadeInDuration = fadeInDuration || this.config.fadeInDuration; // duration for image to fadeIn
this.init();
};
Gallery.prototype.init = function () { // puts things into move
this.getImageSize();
this.bind();
};
Gallery.prototype.bind = function () { // bind events
var self = this;
this.images.on('click', function () {
var index = $(self.images).index( $(this) );
self.showImage(index);
});
$(window).on('resize', function () { // center the imagebox whenever the window is resized
self.centerImageBox(self.imageBoxSize[0], self.imageBoxSize[1]);
});
$(this.closeButton).on('click', function () { // hide the image
// self.hideImage();
self.displayImage.hide();
self.displayImage.fadeIn(500);
});
$(this.backgroundOpacity).on('click', function () {
self.hideImage();
});
return this;
};
Gallery.prototype.getImageSize = function () { // get the default images sizes
var self = this;
this.imagesUl.removeClass('resize');
$.each(this.images, function (index, value) {
self.imagesWidth[index] = value.width;
self.imagesHeight[index] = value.height;
});
this.imagesUl.addClass('resize');
this.imageBox.show();
this.loadingGifSize = [this.loadingGif.width(), this.loadingGif.height()];
this.imageBox.hide();
return this;
};
Gallery.prototype.showImage = function (index) { // shows the image when it is clicked
var self = this,
imageWidth = this.imagesWidth[index], imageHeight = this.imagesHeight[index],
imageSrc = $(this.images[index]).attr('src'),
windowWidth = $(window).width(), windowHeight = $(window).height(),
ratio = imageWidth / imageHeight, margin = 100, // margin - the distance from the image borders to the window borders (if image is to big)
imageBoxHeight, imageBoxWidth;
// resize the image to the current monitor size
while(imageWidth > (windowWidth - margin) || imageHeight > (windowHeight-margin)){
if(imageWidth > windowWidth){
imageWidth = windowWidth - margin;
imageHeight = imageWidth / ratio;
}
else{
imageHeight = windowHeight - margin;
imageWidth = imageHeight * ratio;
}
}
//show imageBox and resize it
this.imageBoxSize = [imageWidth, imageHeight]; // captures the current imageBox size
this.imageNumber.text('Image ' + (index+1) + ' of ' + this.imagesLength) // set bottom-left text
this.displayImage.attr('src', imageSrc).css({
'width': imageWidth,
'height': imageHeight
});
this.backgroundOpacity.show();
this.imageBox.show();
this.loadingGif.show();
this.imageBox.animate({
'width': imageWidth,
'height': imageHeight
},{
duration: self.resizeDuration,
step: function () {
// center the image box with every resize;
imageBoxWidth = self.imageBox.width();
imageBoxHeight = self.imageBox.height();
self.centerImageBox(imageBoxWidth, imageBoxHeight);
// center the loadingGif
self.loadingGif.css({
'right': (imageBoxWidth - self.loadingGifSize[0])/2,
'top': (imageBoxHeight - self.loadingGifSize[1])/2
});
},
complete: function () {
self.closeButton.show();
self.imageNumber.show();
self.loadingGif.hide();
self.displayImage.fadeIn(500);
}
});
return this;
};
Gallery.prototype.hideImage = function () { // hide the image
this.imageBox.hide();
this.backgroundOpacity.hide();
this.closeButton.hide();
this.imageNumber.hide();
this.displayImage.hide();
return this;
};
Gallery.prototype.centerImageBox = function (width, height) {
var windowWidth = $(window).width(),
windowHeight = $(window).height();
this.imageBox.css({
'right': (windowWidth - width)/2,
'top': (windowHeight - height)/2
});
return this;
};
Try with a big image, bigger than 2000×2000
This is due to the fact that the images are too big. Animations with jQuery are in fact pretty slow in performance. I would recommend that you use imagemagick on your server to create small images in the size of whatever you want the gallery to be wide. Afterwards the animations will run smoothly.