I'm using photoswpie to create image gallery. But I can't make animation when some image is closed (when you click somewhere outside image). I want to looks in this way as this example:
I'm using custom code. I've changed it and my whole code is: (please see where comment is "animation" - that's the part I need to do)
Now, it's throwing error:
TypeError: thumbnail.getBoundingClientRect is not a function
$(document).ready(function() {
$('.my-gallery').each( function() {
var $pic = $(this),
getItems = function() {
var items = [];
$pic.find('a').each(function() {
var $width = $(this).data('width');
var $height = $(this).data('height');
var $href = $(this).data('src'),
// $size = $(this).data('size').split('x'),
$width = $width ,
$height = $height;
var item = {
src : $href,
w : $width,
h : $height
}
items.push(item);
// alert($height);
});
return items;
}
var items = getItems();
var $pswp = $('.pswp')[0];
$pic.on('click', '.pic-gallery', function(event) {
event.preventDefault();
var $index = $(this).index();
// alert($index);
var options = {
index: $index,
bgOpacity: 0.7,
showHideOpacity: true,
// fadeOutSpeed:100,
enableMouseWheel: false, enableKeyboard: false,
showHideOpacity:true, getThumbBoundsFn:false,
//animation
getThumbBoundsFn: function(index) {
$pic.find('a').each(function() {
var thumbnail = $(this).data('src');
var pageYScroll = window.pageYOffset || document.documentElement.scrollTop;
var rect = thumbnail.getBoundingClientRect();
return {x: rect.left, y: rect.top + pageYScroll, w: rect.width};
});
//end animation
}
var lightBox = new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options);
lightBox.init();
});
});
});
<div id="post_gallery" class="my-gallery">
@foreach($gallery as $pic)
<div class="left pic-gallery">
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<?php $img_src = 'myproject.com/'. $pic['path'] .'/'. $pic['filename']; list($width, $height) = getimagesize($img_src);?>
<a itemprop="contentUrl" data-size="{{$width}}x{{$height}}" title="{{ $pic['title'] }}" data-width="{{$width}}" data-height="{{$height}}" data-src="myproject.com/{{ $pic['path'] }}/{{ $pic['filename'] }}" href="myproject.com/{{ $pic['path'] }}/{{ $pic['filename'] }}" rel="bookmark">
<img class="left img-thumbnail" width="100" height="75" src="myproject.com/{{ $pic['path'] }}/thumbs/thumbs_{{ $pic['filename'] }}" alt="thumbnail {{ $pic['title'] }}">
</a>
</figure>
</div>
@endforeach
In examples this is done by using the following:
options = {
// define gallery index (for URL)
galleryUID: galleryElement.getAttribute('data-pswp-uid'),
getThumbBoundsFn: function(index) {
// See Options -> getThumbBoundsFn section of documentation for more info
var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
}
};
First, there is a large number of errors in your code. I tried to edit it but realized it won't fit into simple formatting change. You're missing some items, required parts of code are commented... its a mess. I'm working my way through the same plugin, so I can tell. Also, we're using same source for jQuery implementation of PhotoSwipe.
Now, for the correct code. To implement PhotoSwipe in your case you'll need to make a number of changes:
Get size attribute from figure a
, and break it up into width
and height
(that part was commented out). Then you'll need to use $size[0]
and $size[1]
to get height and width of the image.
Next, you're missing some closing bracket }
and you're repeating getThumbBoundsFn
My HTML (I'm not using PHP, its plain HTML, I tried to imitate your tags):
<div class="row my-gallery" itemscope itemtype="http://schema.org/ImageGallery" id="img-gallery">
<figure class="pic-gallery" itemprop="associatedMedia" itemscope="" itemtype="http://schema.org/ImageObject">
<a href="images/nature/DSC_7216.jpg" itemprop="contentUrl" data-size="1200x795" data-src="images/nature/DSC_7216.jpg">
<img src="images/nature/DSC_7216_t.jpg" itemprop="thumbnail">
</a>
</figure>
<figure class="pic-gallery" itemprop="associatedMedia" itemscope="" itemtype="http://schema.org/ImageObject">
<a href="images/nature/DSC_7218.jpg" itemprop="contentUrl" data-size="1200x795" data-src="images/nature/DSC_7218.jpg">
<img src="images/nature/DSC_7218_t.jpg" itemprop="thumbnail">
</a>
</figure>
</div>
Correct Javascript to recreate your issue:
$(document).ready(function() {
$('.my-gallery').each( function() {
var $pic = $(this),
getItems = function() {
var items = [];
$pic.find('a').each(function() {
var $width = $(this).data('width');
var $height = $(this).data('height');
var $href = $(this).data('src'),
$size = $(this).data('size').split('x'),
$width = $size[0],
$height = $size[1];
var item = {
src : $href,
w : $width,
h : $height
};
items.push(item);
// alert($height);
});
return items;
}
var items = getItems();
var $pswp = $('.pswp')[0];
$pic.on('click', '.pic-gallery', function(event) {
event.preventDefault();
var $index = $(this).index();
// alert($index);
var options = {
index: $index,
bgOpacity: 0.7,
showHideOpacity: true,
//fadeOutSpeed:100,
enableMouseWheel: false,
enableKeyboard: false,
//animation
getThumbBoundsFn: function(index) {
$pic.find('a').each(function() {
var thumbnail = $(this).data('src');
var pageYScroll = window.pageYOffset || document.documentElement.scrollTop;
var rect = thumbnail.getBoundingClientRect();
return {x: rect.left, y: rect.top + pageYScroll, w: rect.width};
});
}//end animation
};
var lightBox = new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options);
lightBox.init();
});
});
});
Now, the best part. You're trying to use src
, which is a string
, with getBoundingClientRect
method. String
doesn't have this method. Information about getBoundingClientRect method
What you're supposed to do is provide an element of the page. You can do it like this:
var thumbnail = event.target;
After fixing this error you should be able to load the gallery correctly when you click on a thumbnail. The problem is: you still won't have zooming animation, like on the demo page of PhotoSwipe.
In order for gallery opening animation to work, you need to provide one more element in items
array - msrc
, which contains a link to thumbnail image.
To get zoom animation you'll need to add thumbnail source link into the item array as 'msrc' property. You will also need to remove cycle from getThumbBoundsFn (no idea what is it doing there). The completed javascript will look like this:
$(document).ready(function() {
$('.my-gallery').each( function() {
var $pic = $(this),
getItems = function() {
var items = [];
$pic.find('a').each(function() {
var width = $(this).data('width');
var height = $(this).data('height');
var href = $(this).data('src'),
thumb = $(this).children("img").attr("src"),
size = $(this).data('size').split('x'),
width = size[0],
height = size[1];
var item = {
src : href,
msrc : thumb,
w : width,
h : height
};
items.push(item);
});
return items;
}
//var items = getItems();
var items = itemArray;
var $pswp = $('.pswp')[0];
$pic.on('click', '.pic-gallery', function(event) {
event.preventDefault();
var $index = $(this).index();
// alert($index);
var options = {
index: $index,
bgOpacity: 0.7,
showHideOpacity: true,
//fadeOutSpeed:100,
enableMouseWheel: false,
enableKeyboard: false,
//animation
getThumbBoundsFn: function(index) {
var thumbnail = event.target;
var pageYScroll = window.pageYOffset || document.documentElement.scrollTop;
var rect = thumbnail.getBoundingClientRect();
return {x: rect.left, y: rect.top + pageYScroll, w: rect.width};
}//end animation
};
var lightBox = new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options);
lightBox.init();
});
});
});
With this code you'll have zoom-in zoom-out animation, just like the main page of PhotoSwipe.
There is a problem I cannot fix myself: if you change slide and close gallery, closing animation will be played over the wrong thumbnail (works right on demo page). I'm working on this problem myself. In your case the problem is barely noticable since your slide fades out when gallery closes, though.
Hope this helps!
Edit:
I managed to figure out how to animate the right rectangle: you need to provide proper thumbnail element. Instead of using "event.target", you need to find item index and use it to calculate bounding rectangle.
Final code will look something like this (works with my HTML piece provided earlier):
$(document).ready(function() {
$('.my-gallery').each( function() {
var $pic = $(this),
getItems = function() {
var items = [];
$pic.find('a').each(function() {
var width = $(this).data('width');
var height = $(this).data('height');
var href = $(this).data('src'),
thumb = $(this).children("img").attr("src"),
size = $(this).data('size').split('x'),
width = size[0],
height = size[1];
var item = {
src : href,
msrc : thumb,
w : width,
h : height
};
item.el = $(this).find("img")[0];
items.push(item);
});
return items;
}
var items = getItems();
//var items = itemArray;
var $pswp = $('.pswp')[0];
$pic.on('click', '.pic-gallery', function(event) {
event.preventDefault();
var $index = $(this).index();
// alert($index);
var options = {
index: $index,
bgOpacity: 0.7,
showHideOpacity: true,
//fadeOutSpeed:100,
enableMouseWheel: false,
enableKeyboard: false,
//animation
getThumbBoundsFn: function(index) {
var thumbnail = items[index].el;
var pageYScroll = window.pageYOffset || document.documentElement.scrollTop;
var rect = thumbnail.getBoundingClientRect();
return {x: rect.left, y: rect.top + pageYScroll, w: rect.width};
}//end animation
};
var lightBox = new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options);
lightBox.init();
});
});
});
Hope this helps!