daugaard47
daugaard47

Reputation: 1868

Auto Height Issue in Filter Gallery

I was wondering if I could get some advice here regarding my gallery.

I'm getting strange results using this filtering gallery. See gallery here.

http://chris.proitservicesllc.com/gallery.php

On page load everything is fine but when I switch to a different category there is a small height issue. Then when I switch back to the ALL category there is a major height issue.

I realize the height issue is due to all the images aligning to the left down the page when repositioning themselves, but not sure how to fix the problem.

Hoping someone can help me out on this.

FYI if you check this out in firebug you can see that the UL ID stage is getting an auto generated element.height style added to it. It is coming from the quicksand js file see below.

Here is the html code.

<!--======START GALLERY======-->
    <div class="row">
        <div class="column grid_12">
            <div class="row">
                <div class="column grid_12">
                    <!-- start Filter categories -->
                    <ul id="filter">
                        <li class="active"><a href="#" class="all">All</a></li>
                        <li><a href="#" class="treeremoval">Tree Removal</a></li>
                        <li><a href="#" class="treetrimming">Tree Trimming</a></li>
                        <li><a href="#" class="treebracing">Tree Bracing</a></li>       
                        <li><a href="#" class="stumpgrinding">Stump Grinding</a></li>
                        <li><a href="#" class="firewood">Firewood</a></li>                          
                        <li><a href="#" class="cleanup">Cleanup</a></li>                            
                    </ul>
                    <!-- End Filter categories -->  
                </div>
            </div>  

            <!-- Divider -->
            <div class="row">
                <div class="column grid_12">            
                    <div class="clear"></div>
                    <div class="divider spacer5"></div>     
                </div>
            </div>
            <!-- End divider -->

<div class="row">

<ul id="stage" class="gallery portfolio-4column">



<li data-id="id-12" data-type="treeremoval">
<div class="column grid_3">
<a class="fancybox" rel="gallery1" href="images/gallery/1.jpg" title="Tree Bracing Lake of the Ozarks">
<img src="images/gallery/1.jpg" alt="Tree Bracing Lake of the Ozarks" class="max-img-border"></a>
<h5>Lake of the Ozarks Tree Removal </h5>
</div>  
</li>



<li data-id="id-11" data-type="treetrimming">
<div class="column grid_3">
<a class="fancybox" rel="gallery1" href="images/gallery/2.jpg" title="Osage Beach Tree Trimming">
<img src="images/gallery/2.jpg" alt="Osage Beach Tree Trimming" class="max-img-border"></a>
<h5>Lake of the Ozarks Tree Removal</h5>
</div>  
</li>



<li data-id="id-10" data-type="treebracing">
<div class="column grid_3">
<a class="fancybox" rel="gallery1" href="images/gallery/3.jpg" title="Camdenton Tree Removal">
<img src="images/gallery/3.jpg" alt="Camdenton Tree Removal" class="max-img-border"></a>
<h5>Lake of the Ozarks Tree Removal</h5>
</div>  
</li>



<li data-id="id-9" data-type="stumpgrinding">
<div class="column grid_3">
<a class="fancybox" rel="gallery1" href="images/gallery/4.jpg" title="Residential Tree Removal">
<img src="images/gallery/4.jpg" alt="Residential Tree Removal" class="max-img-border"></a>
<h5>Lake of the Ozarks Tree Removal</h5>
</div>  
</li>




etc...



</ul><!--END LIST-->

</div>  
</div>
</div>

</div>

<!--======END GALLERY======-->

</div>
</div><!--End Row-->

Here are the two scripts associated with the gallery.

quicksand.js At the top of the script if I change the adjustHeight: to false it fixes the height issue but creates a jump / pop in the animation and the footer jumps up below the images then falls back into place. I might be able to live with that, but it's looks really buggy when it happens. Which tells me that there also might be some kind of z-index issue....?

/*

Quicksand 1.2.2

Reorder and filter items with a nice shuffling animation.

Copyright (c) 2010 Jacek Galanciak (razorjack.net) and agilope.com
Big thanks for Piotr Petrus (riddle.pl) for deep code review and wonderful docs & demos.

Dual licensed under the MIT and GPL version 2 licenses.
http://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt
http://github.com/jquery/jquery/blob/master/GPL-LICENSE.txt

Project site: http://razorjack.net/quicksand
Github site: http://github.com/razorjack/quicksand

*/

(function ($) {
    $.fn.quicksand = function (collection, customOptions) {     
        var options = {
            duration: 750,
            easing: 'swing',
            attribute: 'data-id', // attribute to recognize same items within source and dest
            adjustHeight: 'auto', // 'dynamic' animates height during shuffling (slow), 'auto' adjusts it before or after the animation, false leaves height constant
            useScaling: true, // disable it if you're not using scaling effect or want to improve performance
            enhancement: function(c) {}, // Visual enhacement (eg. font replacement) function for cloned elements
            selector: '> *',
            dx: 0,
            dy: 0
        };
        $.extend(options, customOptions);

        if ($.browser.msie || (typeof($.fn.scale) == 'undefined')) {
            // Got IE and want scaling effect? Kiss my ass.
            options.useScaling = false;
        }

        var callbackFunction;
        if (typeof(arguments[1]) == 'function') {
            var callbackFunction = arguments[1];
        } else if (typeof(arguments[2] == 'function')) {
            var callbackFunction = arguments[2];
        }


        return this.each(function (i) {
            var val;
            var animationQueue = []; // used to store all the animation params before starting the animation; solves initial animation slowdowns
            var $collection = $(collection).clone(); // destination (target) collection
            var $sourceParent = $(this); // source, the visible container of source collection
            var sourceHeight = $(this).css('height'); // used to keep height and document flow during the animation

            var destHeight;
            var adjustHeightOnCallback = false;

            var offset = $($sourceParent).offset(); // offset of visible container, used in animation calculations
            var offsets = []; // coordinates of every source collection item            

            var $source = $(this).find(options.selector); // source collection items

            // Replace the collection and quit if IE6
            if ($.browser.msie && $.browser.version.substr(0,1)<7) {
                $sourceParent.html('').append($collection);
                return;
            }

            // Gets called when any animation is finished
            var postCallbackPerformed = 0; // prevents the function from being called more than one time
            var postCallback = function () {

                if (!postCallbackPerformed) {
                    postCallbackPerformed = 1;

                    // hack: 
                    // used to be: $sourceParent.html($dest.html()); // put target HTML into visible source container
                    // but new webkit builds cause flickering when replacing the collections
                    $toDelete = $sourceParent.find('> *');
                    $sourceParent.prepend($dest.find('> *'));
                    $toDelete.remove();

                    if (adjustHeightOnCallback) {
                        $sourceParent.css('height', destHeight);
                    }
                    options.enhancement($sourceParent); // Perform custom visual enhancements on a newly replaced collection
                    if (typeof callbackFunction == 'function') {
                        callbackFunction.call(this);
                    }                    
                }
            };

            // Position: relative situations
            var $correctionParent = $sourceParent.offsetParent();
            var correctionOffset = $correctionParent.offset();
            if ($correctionParent.css('position') == 'relative') {
                if ($correctionParent.get(0).nodeName.toLowerCase() == 'body') {

                } else {
                    correctionOffset.top += (parseFloat($correctionParent.css('border-top-width')) || 0);
                    correctionOffset.left +=( parseFloat($correctionParent.css('border-left-width')) || 0);
                }
            } else {
                correctionOffset.top -= (parseFloat($correctionParent.css('border-top-width')) || 0);
                correctionOffset.left -= (parseFloat($correctionParent.css('border-left-width')) || 0);
                correctionOffset.top -= (parseFloat($correctionParent.css('margin-top')) || 0);
                correctionOffset.left -= (parseFloat($correctionParent.css('margin-left')) || 0);
            }

            // perform custom corrections from options (use when Quicksand fails to detect proper correction)
            if (isNaN(correctionOffset.left)) {
                correctionOffset.left = 0;
            }
            if (isNaN(correctionOffset.top)) {
                correctionOffset.top = 0;
            }

            correctionOffset.left -= options.dx;
            correctionOffset.top -= options.dy;

            // keeps nodes after source container, holding their position
            $sourceParent.css('height', $(this).height());

            // get positions of source collections
            $source.each(function (i) {
                offsets[i] = $(this).offset();
            });

            // stops previous animations on source container
            $(this).stop();
            var dx = 0; var dy = 0;
            $source.each(function (i) {
                $(this).stop(); // stop animation of collection items
                var rawObj = $(this).get(0);
                if (rawObj.style.position == 'absolute') {
                    dx = -options.dx;
                    dy = -options.dy;
                } else {
                    dx = options.dx;
                    dy = options.dy;                    
                }

                rawObj.style.position = 'absolute';
                rawObj.style.margin = '0';

                rawObj.style.top = (offsets[i].top - parseFloat(rawObj.style.marginTop) - correctionOffset.top + dy) + 'px';
                rawObj.style.left = (offsets[i].left - parseFloat(rawObj.style.marginLeft) - correctionOffset.left + dx) + 'px';
            });

            // create temporary container with destination collection
            var $dest = $($sourceParent).clone();
            var rawDest = $dest.get(0);
            rawDest.innerHTML = '';
            rawDest.setAttribute('id', '');
            rawDest.style.height = 'auto';
            rawDest.style.width = $sourceParent.width() + 'px';
            $dest.append($collection);      
            // insert node into HTML
            // Note that the node is under visible source container in the exactly same position
            // The browser render all the items without showing them (opacity: 0.0)
            // No offset calculations are needed, the browser just extracts position from underlayered destination items
            // and sets animation to destination positions.
            $dest.insertBefore($sourceParent);
            $dest.css('opacity', 0.0);
            rawDest.style.zIndex = -1;

            rawDest.style.margin = '0';
            rawDest.style.position = 'absolute';
            rawDest.style.top = offset.top - correctionOffset.top + 'px';
            rawDest.style.left = offset.left - correctionOffset.left + 'px';





            if (options.adjustHeight === 'dynamic') {
                // If destination container has different height than source container
                // the height can be animated, adjusting it to destination height
                $sourceParent.animate({height: $dest.height()}, options.duration, options.easing);
            } else if (options.adjustHeight === 'auto') {
                destHeight = $dest.height();
                if (parseFloat(sourceHeight) < parseFloat(destHeight)) {
                    // Adjust the height now so that the items don't move out of the container
                    $sourceParent.css('height', destHeight);
                } else {
                    //  Adjust later, on callback
                    adjustHeightOnCallback = true;
                }
            }

            // Now it's time to do shuffling animation
            // First of all, we need to identify same elements within source and destination collections    
            $source.each(function (i) {
                var destElement = [];
                if (typeof(options.attribute) == 'function') {

                    val = options.attribute($(this));
                    $collection.each(function() {
                        if (options.attribute(this) == val) {
                            destElement = $(this);
                            return false;
                        }
                    });
                } else {
                    destElement = $collection.filter('[' + options.attribute + '=' + $(this).attr(options.attribute) + ']');
                }
                if (destElement.length) {
                    // The item is both in source and destination collections
                    // It it's under different position, let's move it
                    if (!options.useScaling) {
                        animationQueue.push(
                                            {
                                                element: $(this), 
                                                animation: 
                                                    {top: destElement.offset().top - correctionOffset.top, 
                                                     left: destElement.offset().left - correctionOffset.left, 
                                                     opacity: 1.0
                                                    }
                                            });

                    } else {
                        animationQueue.push({
                                            element: $(this), 
                                            animation: {top: destElement.offset().top - correctionOffset.top, 
                                                        left: destElement.offset().left - correctionOffset.left, 
                                                        opacity: 1.0, 
                                                        scale: '1.0'
                                                       }
                                            });

                    }
                } else {
                    // The item from source collection is not present in destination collections
                    // Let's remove it
                    if (!options.useScaling) {
                        animationQueue.push({element: $(this), 
                                             animation: {opacity: '0.0'}});
                    } else {
                        animationQueue.push({element: $(this), animation: {opacity: '0.0', 
                                         scale: '0.0'}});
                    }
                }
            });

            $collection.each(function (i) {
                // Grab all items from target collection not present in visible source collection

                var sourceElement = [];
                var destElement = [];
                if (typeof(options.attribute) == 'function') {
                    val = options.attribute($(this));
                    $source.each(function() {
                        if (options.attribute(this) == val) {
                            sourceElement = $(this);
                            return false;
                        }
                    });                 

                    $collection.each(function() {
                        if (options.attribute(this) == val) {
                            destElement = $(this);
                            return false;
                        }
                    });
                } else {
                    sourceElement = $source.filter('[' + options.attribute + '=' + $(this).attr(options.attribute) + ']');
                    destElement = $collection.filter('[' + options.attribute + '=' + $(this).attr(options.attribute) + ']');
                }

                var animationOptions;
                if (sourceElement.length === 0) {
                    // No such element in source collection...
                    if (!options.useScaling) {
                        animationOptions = {
                            opacity: '1.0'
                        };
                    } else {
                        animationOptions = {
                            opacity: '1.0',
                            scale: '1.0'
                        };
                    }
                    // Let's create it
                    d = destElement.clone();
                    var rawDestElement = d.get(0);
                    rawDestElement.style.position = 'absolute';
                    rawDestElement.style.margin = '0';
                    rawDestElement.style.top = destElement.offset().top - correctionOffset.top + 'px';
                    rawDestElement.style.left = destElement.offset().left - correctionOffset.left + 'px';
                    d.css('opacity', 0.0); // IE
                    if (options.useScaling) {
                        d.css('transform', 'scale(0.0)');
                    }
                    d.appendTo($sourceParent);

                    animationQueue.push({element: $(d), 
                                         animation: animationOptions});
                }
            });

            $dest.remove();
            options.enhancement($sourceParent); // Perform custom visual enhancements during the animation
            for (i = 0; i < animationQueue.length; i++) {
                animationQueue[i].element.animate(animationQueue[i].animation, options.duration, options.easing, postCallback);
            }
        });
    };
})(jQuery);

The last script is the filter settings.

filter_settings.js

$(document).ready(function(){ 


    /*********************
    quicksand
    *********************/      
    $clientsHolder = $('#stage');
    $clientsClone = $clientsHolder.clone(); 

    $('#filter a').click(function(e) {
        e.preventDefault();

        $filterClass = $(this).attr('class');

        $('#filter li').removeClass('active');
        $(this).parent().addClass('active');

        if($filterClass == 'all'){
            $filters = $clientsClone.find('li');
        } else {
            $filters = $clientsClone.find('li[data-type~='+ $filterClass +']');
        }

       $clientsHolder.quicksand( $filters, {
            duration: 1000,
            easing: 'easeInOutQuad'
        }, function(){

        });

    });
});

As always any help on this would be greatly appreciated, as I have been trying to figure this out for a week now.

Let me know if you need anymore info from me and I will be happy to provide it.

Thank You!

Upvotes: 0

Views: 1042

Answers (1)

daugaard47
daugaard47

Reputation: 1868

I figured it out I just needed to download the updated version of quicksand.js. Doh!

If anyone needs it here is the link.

https://github.com/razorjack/quicksand

Upvotes: 0

Related Questions