marcamillion
marcamillion

Reputation: 33755

How do I make this carousel implementation better?

You can view the implementation here.

So what this does is automatically detect the window size and resizes the images to be displayed on the fly - the idea being that in all screen resolutions the proportions are the same.

Here are some problems I have found with it, that I would love solutions to make it more elegant and 'smooth':

You can either view source on that feedback page, but there is extraneous code there, so here are the relevant parts:

HTML:

<div id="compare_view" align="center">

    <div id="viewbar" class="compv-navbar">
        <a href=""><img src="images/2-up-icon-grey.png" alt="2-up-view" data-id="2"></a> | 
        <a href=""><img src="images/3-up-icon-grey.png" alt="3-up-view" data-id="3"></a> | 
        <a href=""><img src="images/4-up-icon-grey.png" alt="4-up-view" data-id="4"></a> | 
        <span id="viewname" class="view_name">2-up</span>
    </div>  

<div id="slider-code" align="center">
    <a class="buttons prev" href="#"></a>
    <div class="viewport">
        <ul class="overview">           
            <li><img src="images/red-stripe.jpg" /></li>
            <li><img src="images/red-stripe-bw.jpg" /></li>
            <li><img src="images/red-stripe-red.jpg" /></li>            
            <li><img src="images/red-stripe-dark.jpg" /></li>
            <li><img src="images/red-stripe.jpg" /></li>
            <li><img src="images/red-stripe-red.jpg" /></li>
            <li><img src="images/red-stripe-dark.jpg" /></li>           
        </ul>
    </div>
    <a class="buttons next" href="#"></a>
    </div>

    <div id="notice">
        Flip through the images using the <strong> buttons </strong> and your mouse.
    </div>

</div>

Here is the relevant CSS:

#slider-code { 
    height: 125px; 
    overflow:hidden;
    margin: 0 0 0 0;
}

#slider-code .viewport { 
/*  margin-left: auto;    -- With this enabled, the arrows don't work.
    margin-right: auto;  */
    float: left; 
    width: 240px; 
    height: 125px; 
    overflow: hidden; 
    position: relative;

}

#slider-code .viewport .overview img {
    border: 4px solid #f6f6f7;
    -moz-border-radius: 4px;
    -khtml-border-radius: 4px;
    -webkit-border-radius: 4px; 
}

#slider-code .buttons { 
    display: block; 
    margin: 0 0 0 0; /* 10px 10px 0 0;  */
    float: left;
    vertical-align: middle;
}

#slider-code .prev {
    width: 32px;
    height: 32px;
    background: transparent url('../images/left-arrow.png') no-repeat 0 0;
    vertical-align: middle;
    margin: 0 0 0 0; /* top, right, bottom, left */ 
    position: relative;
/*  top: 190.5px;   */
}

#slider-code .next { 
    width: 32px;
    height: 32px;
    background: transparent url('../images/right-arrow.png') no-repeat 0 0;
    margin: 0 0 0 0px;  /* 30px 0 0 10px; */
    vertical-align: middle;
    position: relative;
}

#slider-code .disable { 
     /* for IE */
    filter:alpha(opacity=40);
    /* for everything else */  
    opacity:0.4;
}

#slider-code .overview { 
    list-style: none; 
    position: absolute; 
    padding: 0; 
    margin: 0; 
    left: 0; 
    top: 0; 
}

#slider-code .overview li { 
    float: left; 
    margin: 0 20px 0 0; 
    padding: 1px; 
    height: 121px; 
    border: 1px solid #dcdcdc;
    width: 236px;
}

.view_name {
    font-family: "Helvetica", serif;
    color: #f9f4c0;
    font-style: normal;
    font-weight: bold;
    font-size: 11px;
    word-spacing: 0px;
    letter-spacing: 0px;
    background: #1a1a1a;    
    padding: 1px 3px 1px 3px; /* top, right, bottom, left */        
    -moz-border-radius: 5px;
    -khtml-border-radius: 5px;
    -webkit-border-radius: 5px; 
}

#compare_view .compv-navbar img {
    margin: 3px 3px -4px 3px;   
}

#compare_view .compv-navbar img a.hover {   
    margin: 3px 3px -4px 3px;   
}

Here is the JS:

$(window).load(function() {
// --------------------------- Begin Comparison Code --------------------------------------------------------       
        var win_width = $(window).width();
        var num_of_images = 2; //The number of images expected in view (2 for 2-up, 3 for 3-up, etc.) The default value is 2.

        $("#viewbar img").click(function(e) {                       
            num_of_images = parseInt($(this).attr("data-id"), 10); // This accepts the integer associated with the navbar.          
            $('#viewname').text(num_of_images + '-up');         
            //--- All of this function is a duplicate of the 'default' case which is below. This is not very DRY-like, but it works for now.

            var oImg_height = $('#slider-code .viewport .overview img:eq(1)').height(); //size of original image height
            var oImg_width =  $('#slider-code .viewport .overview img:eq(1)').width(); //size of original image width
            var oImg_ratio = oImg_height / oImg_width; //aspect ratio of original image
            var tImg_width = (win_width * 0.915) / num_of_images; // Target image width = (90% of the window) / 2
            var tImg_height = tImg_width * oImg_ratio; // Target image height, resized according to the original image ratio.
            var sliderCode_w = $('#slider-code').width();
            var sliderCode_h = $('#slider-code').height();
            var ul_width = $('#slider-code .viewport ul').width();

            $('#slider-code .viewport .overview img:lt(26)').css({'width' : tImg_width, 'height' : tImg_height});   //resizes the images

            var rImg_width = $('#slider-code .viewport .overview img:eq(1)').width(); // size of resized image width 
            var rImg_height = $('#slider-code .viewport .overview img:eq(1)').height(); // size of resized image width

            $('#slider-code .next').css({'top' : rImg_height / 2}); //This needs to be resolved for various size windows
            $('#slider-code .prev').css({'top' : rImg_height / 2});     
            $('#slider-code').css({'width': '100%', 'height': rImg_height + 10}); //to accomodate borders, extra padding was added to heights. To make it truly dynamic, a variable (as a percentage) of the width of the window, could be used to be added to the height
            $('#slider-code .viewport').css({'width': win_width * 0.94, 'height': rImg_height + 10});
            $('#slider-code .overview li').css({'width': rImg_width + 5});
            var view_new_w = $('#slider-code .viewport').width();
            var view_new_h = $('#slider-code .viewport').height();
            var li_w = $('#slider-code .overview li').width();
            var rUl_width = $('#slider-code .viewport ul').width();

            $('#slider-code').tinycarousel({ controls: true, animation: true, display: 1 });        

            e.preventDefault();
        }); 

        //This is the default case that executes before a click is done. Because the code has been repeated above, it isn't very DRY-like.

        var oImg_height = $('#slider-code .viewport .overview img:eq(1)').height(); //size of original image height
        var oImg_width =  $('#slider-code .viewport .overview img:eq(1)').width(); //size of original image width
        var oImg_ratio = oImg_height / oImg_width; //aspect ratio of original image
        var tImg_width = (win_width * 0.915) / num_of_images; // Target image width = (90% of the window) / 2
        var tImg_height = tImg_width * oImg_ratio; // Target image height, resized according to the original image ratio.
        var sliderCode_w = $('#slider-code').width();
        var sliderCode_h = $('#slider-code').height();
        var ul_width = $('#slider-code .viewport ul').width();

    //  console.log("Original Image Height: ", oImg_height, " Original Image Width: ", oImg_width, " Original Image Aspect Ratio: ", oImg_ratio, " Slider Code Width: ", sliderCode_w, " Slider Code Height: ", sliderCode_h, " Window Width: ", win_width, " UL Width: ", ul_width, " Target Image Width: ", tImg_width, " Target Image Height: ", tImg_height);

        $('#slider-code .viewport .overview img:lt(26)').css({'width' : tImg_width, 'height' : tImg_height});   //resizes the images

        var rImg_width = $('#slider-code .viewport .overview img:eq(1)').width(); // size of resized image width 
        var rImg_height = $('#slider-code .viewport .overview img:eq(1)').height(); // size of resized image width

        $('#slider-code .next').css({'top' : rImg_height / 2}); //This needs to be resolved for various size windows
        $('#slider-code .prev').css({'top' : rImg_height / 2});     
        $('#slider-code').css({'width': '100%', 'height': rImg_height + 10}); //to accomodate borders, extra padding was added to heights. To make it truly dynamic, a variable (as a percentage) of the width of the window, could be used to be added to the height
        $('#slider-code .viewport').css({'width': win_width * 0.94, 'height': rImg_height + 10});
        $('#slider-code .overview li').css({'width': rImg_width + 5});
        var view_new_w = $('#slider-code .viewport').width();
        var view_new_h = $('#slider-code .viewport').height();
        var li_w = $('#slider-code .overview li').width();
        var rUl_width = $('#slider-code .viewport ul').width();


//      console.log("Viewport New Width: ", view_new_w, view_new_h, " List Item Width: ", li_w, " Resized Image Width: ", rImg_width, " Resized Image Height: ", rImg_height, " Resized UL Width: ", rUl_width);

        $('#slider-code').tinycarousel({ controls: true, animation: true, display: 1 });            

// --------------- End Comparison Code --------------------------------------------------------------------------

})

Btw, I put the JS in the window.load function because when I put it in document ready it wasn't working properly, because the code had to detect the window size before resizing the images - and if the window hadn't loaded it would just stall and not load the carousel with the correct images.

I know the task seems daunting, but I REALLY hope the community can come through for me.

Thanks.

Edit: No one brave enough to take a stab?

Edit 2: I have made the changes suggested by JonP, but I am having some new issues now that I am trying to work through. Anyone have any suggestions on how I can get it back to normal? Reload the above link to see the new version.

Upvotes: 0

Views: 1343

Answers (1)

Jon P
Jon P

Reputation: 19772

Completely untested and a stab in the dark as I am not overly familiar with tiny carosel.

This might help DRY you out a bit and provide a small performance improvement through caching some repeated selectors.

It wont help with your 4-up issue though

    //Go Global with our varibles
    var oImg, sliderCode, sliderViewPort,sliderOverViewImg , win_width;
    var oImg_height, oImg_width, oImg_ratio, tImg_width, tImg_height, sliderCode_w, sliderCode_h, ul_width;
    var rImg_width, rImg_height, view_new_w, view_new_h, li_w, rUl_width;

    function setUp(numImages) {
        oImg_height = oImg.height(); //size of original image height 
        oImg_width = oImg.width(); //size of original image width 
        oImg_ratio = oImg_height / oImg_width; //aspect ratio of original image 
        tImg_width = (win_width * 0.915) / num_of_images; // Target image width = (90% of the window) / 2 
        tImg_height = tImg_width * oImg_ratio; // Target image height, resized according to the original image ratio. 
        sliderCode_w = sliderCode.width();
        sliderCode_h = sliderCode.height();
        var ul_width = $('#slider-code .viewport ul').width();

        //  console.log("Original Image Height: ", oImg_height, " Original Image Width: ", oImg_width, " Original Image Aspect Ratio: ", oImg_ratio, " Slider Code Width: ", sliderCode_w, " Slider Code Height: ", sliderCode_h, " Window Width: ", win_width, " UL Width: ", ul_width, " Target Image Width: ", tImg_width, " Target Image Height: ", tImg_height); 

        $('#slider-code .viewport .overview img:lt(26)').css({ 'width': tImg_width, 'height': tImg_height });   //resizes the images

        rImg_width = sliderOverViewImg.width(); // size of resized image width  
        rImg_height = sliderOverViewImg.height(); // size of resized image width 

        $('#slider-code .next').css({ 'top': rImg_height / 2 }); //This needs to be resolved for various size windows 
        $('#slider-code .prev').css({ 'top': rImg_height / 2 });
        sliderCode.css({ 'width': '100%', 'height': rImg_height + 10 }); //to accomodate borders, extra padding was added to heights. To make it truly dynamic, a variable (as a percentage) of the width of the window, could be used to be added to the height 
        sliderViewport.css({ 'width': win_width * 0.94, 'height': rImg_height + 10 });
        $('#slider-code .overview li').css({ 'width': rImg_width + 5 });
        view_new_w = sliderViewPort.width();
        view_new_h = sliderViewPort.height();
        li_w = $('#slider-code .overview li').width();
        rUl_width = $('#slider-code .viewport ul').width();

        //      console.log("Viewport New Width: ", view_new_w, view_new_h, " List Item Width: ", li_w, " Resized Image Width: ", rImg_width, " Resized Image Height: ", rImg_height, " Resized UL Width: ", rUl_width); 

        sliderCode.tinycarousel({ controls: true, animation: true, display: 1 });

    }

    $(window).load(function() {
        //Cache Some Common Elements
        oImg = $('#slider-code .viewport .overview img:eq(1)');
        sliderCode = $('#slider-code');
        sliderViewPort = $('#slider-code .viewport');
        sliderOverViewImg = $('#slider-code .viewport .overview img:eq(1)')

        // --------------------------- Begin Comparison Code --------------------------------------------------------        
        win_width = $(window).width();
        num_of_images = 2; //The number of images expected in view (2 for 2-up, 3 for 3-up, etc.) The default value is 2. 

        $("#viewbar img").click(function(e) {
            num_of_images = parseInt($(this).attr("data-id"), 10); // This accepts the integer associated with the navbar.           
            $('#viewname').text(num_of_images + '-up');

            setUp(num_of_images);

            e.preventDefault();
        });

        //Default set up
        setUp(num_of_images);


        // --------------- End Comparison Code -------------------------------------------------------------------------- 

    }) 

Good Luck.

Upvotes: 2

Related Questions