My Isotope somehow does strange things, when it loads it zooms like crazy and when you filter, the images zoom and scale. It only happens once but it looks super strange. I already tried to place the jQuery at first before all the other code and I also tried to disable the CSS animations for the hover but none of these worked out.
My jQuery is:
// init Isotope
var $grid = $('.grid').isotope({
itemSelector: '.grid-item',
percentPosition: true,
masonry: {
columnWidth: '.grid-sizer'
}
});
// Make filtering work
$('.filter-button-group').on( 'click', 'button', function() {
var filterValue = $(this).attr('data-filter');
$grid.isotope({ filter: filterValue });
});
// layout Isotope after each image loads
$grid.imagesLoaded().progress( function() {
$grid.isotope('layout');
});
// Highlight the active filter
$('.button-group').each( function( i, buttonGroup ) {
var $buttonGroup = $( buttonGroup );
$buttonGroup.on( 'click', 'button', function() {
$buttonGroup.find('.is-checked').removeClass('is-checked');
$(this).addClass('is-checked');
});
});
and a live demo can be found here:
http://dominikwierl.com/develop/v+v/projects
This can be closed.
I've found the answer with some more searching. It's called Isotope Shaking and it can happen when there are too many animations on one object.
See: https://isotope.metafizzy.co/faq.html#items-jump-after-transitioning-position
Related
I am trying to get Packery.js to work with LazyLoad.js, while having the ability to filter the gallery by tags.
www.temp.fokuspunkt.de
On the initial page load everything works fine:
After clicking throgh the tags and then clicking on the "all" button again, the layout is scrambled, however:
I assume this has to do with the lazy loading, as it can throw off the layout, as described in the documentation here:
https://packery.metafizzy.co/layout.html#imagesloaded
Adding the recommended solution
$grid.imagesLoaded().progress( function() {
$grid.isotope('layout');
});
throws an error, though:
My complete javascript file calling Isotope looks like this, I had tried to copy the above code right beneath the "$(window).on('load',function[...]" function block:
jQuery(function ($) {
var $grid = $('.isotope-list').packery({
layoutMode: 'packery',
filter: '*',
itemSelector: '.isotope-item',
gutter: 0,
});
$(window).on('load',function(){
$grid.packery('layout');
});
imagesLoaded( $grid ).on( 'progress', function() {
pckry.layout();
});
$('.filters li').click(function(){
//css button styling
$('.filters li').removeClass('current');
$(this).addClass('current');
// set isotope filter
var selector = $(this).attr('data-filter');
$grid.isotope({
filter: selector,
animationOptions: {
duration: 750,
easing: 'linear',
queue: false
}
});
$grid.packery('layout');
return false;
});
var $win = $(window),
$imgs = $("img"),
$loadVisible = function($els, trigger) {
$els.filter(function () {
var rect = this.getBoundingClientRect();
return rect.top >= 0 && rect.top <= window.innerHeight;
}).trigger(trigger);
}
$grid.packery('on', 'layoutComplete', function () {
$loadVisible($imgs, 'lazylazy');
$grid.packery('layout');
});
$win.on('scroll', function () {
$loadVisible($imgs, 'lazylazy');
});
$win.on('resize', function () {
$grid.packery('layout');
});
$imgs.lazyload({
effect: "fadeIn",
failure_limit: Math.max($imgs.length - 1, 0),
event: 'lazylazy'
});
});
I am certain I am doing something stupid, would anybody be kind enough to tell me what I am doing wrong? Thank you very much in advance!
So, it took a while, but I wanted to return and share my solution. Maybe it helps out somebody else in the future. My main problem was that I used isotope and packery (which is a standalone library), and not isotope and isotope-packery (which is an addon for isotope). I also changed my lazy loading plugin to "lozad", which makes a lot of thins easier.
In the code below you can also find a solution for using multiple filter terms in combination. In my case I use a row of row of radio buttons below the old button row you can see above.
jQuery(function ($) {
// initialize Packery
var $pckry = $('.isotope-list').isotope({
layoutMode: 'packery',
filter: '*',
itemSelector: '.isotope-item',
packery: {
gutter: 0
},
animationOptions: {
duration: 750,
easing: 'linear',
queue: false
}
});
// layout on first page load, so that the gutter gets set up
$(window).on('load', function () {
$pckry.isotope('layout');
});
// filter items on button click
$('.filters li').click(function () {
$('.filters li').removeClass('current');
$(this).addClass('current');
var combinedFilter = getFilter($('.filters li.current').attr('data-filter')) + getFilter($('input[name="isotope-type-filter"]:checked').val().toLowerCase());
$pckry.isotope({ filter: combinedFilter });
$pckry.isotope('layout');
});
// filter items on radio button change
$('input[name="isotope-type-filter"]').change(function () {
var combinedFilter = getFilter($('.filters li.current').attr('data-filter')) + getFilter($('input[name="isotope-type-filter"]:checked').val().toLowerCase());
$pckry.isotope({ filter: combinedFilter });
$pckry.isotope('layout');
});
function getFilter(buttonGroup) {
var filterValue = '';
if (buttonGroup === '*') {
filterValue = "";
} else {
filterValue = "." + buttonGroup;
}
return filterValue;
};
});
I have an issue with my masonry code.
It works fine on pageload, but the items that are inside the masonry can be filtered, I am doing this using ajax and I'm replacing the entire div with elements to show the filtered items.
After this happens, the masonry code is not applied again and it falls apart.
How can I make sure the masonry stays applied even when content changes after pageload?
In my footer I have the following code:
<script type="text/javascript">
$(document).ready(function() {
$('.gridlist').isotope({
itemSelector: '.masonryitem',
layoutMode: 'masonry',
});
});
</script>
Then in my custom.js I have the following:
$( document ).ready(function() {
/* Ajax code voor aanbiedingen */
$("#branche").on('change', function() {
var option = $('#branche > option').filter(':selected');
if(option.val() == 'default'){
$.post("includes/ledenall.php", {
filter: option.val()
}, function(result){
$("#content1").html(result);
});
}else{
$.post("includes/leden.php?option=" + option.val(), {
filter: option.val()
}, function(result){
$("#content1").html(result);
});
}
});
});
Which returns my php file, but this time without the masonry being applied.
What can I do about this?
You can try reapplying your isotope library after changing the DOM:
/* Ajax code voor aanbiedingen */
$("#branche").on('change', function() {
var option = $('#branche > option').filter(':selected');
if(option.val() == 'default'){
$.post("includes/ledenall.php", {
filter: option.val()
}, function(result){
$("#content1").html(result);
$('.gridlist').isotope({
itemSelector: '.masonryitem',
layoutMode: 'masonry',
});
});
}else{
$.post("includes/leden.php?option=" + option.val(), {
filter: option.val()
}, function(result){
$("#content1").html(result);
$('.gridlist').isotope({
itemSelector: '.masonryitem',
layoutMode: 'masonry',
});
});
}
});
I don't know if .gridlist is totally replaced in your updated DOM. If not, you may need to somehow "remove" the old isotope instance, but something like this is what you need to do.
Add your code to a function
function func() {
$('.gridlist').isotope({
itemSelector: '.masonryitem',
layoutMode: 'masonry',
});
}
Then you can call the function and apply your isotope at any point you want
I have the following jQuery code using Isotope plugin:
$(document).ready(function() {
/**
* Initialise Isotope
*/
var $grid = $('.grid').isotope({
"itemSelector": ".grid-item",
layoutMode: 'masonry',
"masonry": {
"columnWidth": 0
}
});
/**
* Trigger when arrangement completes
*/
$grid.on( 'arrangeComplete', function( event, filteredItems ) {
alert("HERE!");
});
});
The alert does not trigger at all although the Isotope grid works. What have I missed? Thanks!
I got my code working with the following change:
$('.grid').isotope().on( 'layoutComplete', function( event, filteredItems ) {
alert("HERE!");
});
I got the arrangeComplete from here so I do not understand why it does not work, as I have Isotope 2.2.2 which is the latest version. layoutComplete did the trick, which I found with some research.
$grid.on('arrangeComplete', function() {
console.log('arrangeComplete')
}).isotope();
So here's what I'm trying to do. I have a grid with a lot of images, so I'm using the imagesLoaded library along with masonry.
Here's my CSS:
.grid {
opacity:0;
}
And HTML:
<div class="grid">
<div class="grid-sizer"></div>
<div class="gutter-sizer"></div>
<div class="item">image</div>
<div class="item">image</div>
<div class="item">image</div>
</div>
And here's my JS:
var $container = $('.grid');
// initialize Masonry after all images have loaded
$container.imagesLoaded( function() {
$container.masonry({
columnWidth: '.grid-sizer',
itemSelector: '.item',
gutter: '.gutter-sizer'
});
$container.masonry('on', 'layoutComplete', function(){
console.log('got here');
$container.animate({'opacity':1});
});
});
My goal is to have the grid hidden until all images are load and the layout is complete, and then fade it in. For some reason in my code above, it's never getting into the on layoutComplete block.
If I move that block outside of imagesLoaded, $container.masonry is undefined that point.
Any ideas?
FIDDLE HERE
If you change the grid opacity to 1 you can see everything is getting laid out fine. Just trying to figure out how to get the layoutComplete to call to set the opacity to 1.
You don't need to use the layoutComplete event on masonry. As you can just add your animation code under the masonry initialization .
When all images are loaded, the imageLoaded function will execute. You can then create the masonry object and animate right away like so:
var $grid = $('.grid').imagesLoaded( function() {
// init Masonry after all images have loaded
$grid.masonry({
columnWidth: 200,
itemSelector: '.item',
gutter: 10
});
console.log('got here');
$('.grid').animate({'opacity':1});
});
Here is a jsfiddle that demonstrate that
jQuery(document).ready(function($){
var wdm_wait = function(){
jQuery("body").find("img").each(function(i) {
if(!this.complete)
{
return false;
}
});
// when code reaches here Its assured that all the images are loaded
clearInterval(waiting);
console.log('got here');
var $container = $('.grid');
// initialize Masonry after all images have loaded
$container.masonry({
columnWidth: 100,
itemSelector: '.item',
gutter: 10
});
$container.animate({'opacity':1});
}
waiting = setInterval(wdm_wait,100);
});
This would certainly assure that your js code executes only after all the images have been loaded (rendered)
Hope this helps! :)
have you ever try this one, I think this is your answer
var $container = $('.grid').masonry({
columnWidth: 200,
itemSelector: '.item',
gutter: 10
});
$container.masonry( 'on', 'layoutComplete', function() {
$container.animate({'opacity':1});
});
$container.masonry();
I'm having an issue with firefox and chrome not rendering the proper amount of columns when using Jquery Isotope and the images loaded option. Safari shows 3 columns all the time. However firefox and chrome sometimes only show 2. All of my images have the same width 28.333%. I have tried changing that to a lower number but it does not effect anything.
Here is what I currently have:
$(document).ready(function() {
var $container = $('#artContent'),
filters = {};
$container.imagesLoaded( function(){
$container.isotope({
itemSelector : '.isotopeItem'
});
});
I tried this which resulted in breaking all the jQuery
$(document).ready(function() {
var $container = $('#artContent'),
filters = {};
$container.imagesLoaded( function(){
$container.isotope({
itemSelector : '.isotopeItem',
masonry: { columnWidth: 33.333% }
});
});
Has anyone else had this issue? Or know of how to fix it.
If your using % in columnWidth, it needs to be like so (note the single quotes):
$(document).ready(function() {
var $container = $('#artContent'),
filters = {};
$container.imagesLoaded( function(){
$container.isotope({
itemSelector : '.isotopeItem',
masonry: { columnWidth: '33.333%' }
});
});