0

I have a problem that I need to sort out in javascript I believe, but dont know how to begin with it, so hopefully someone from the javascript community may be able to help please.

Basically, the following code allows me to load 10 images into a slideshow carousel. However, these images are either 600px x 400px Portrait or 400px x 600 Landscape. The problem I have is that the Landscape images are vertically aligned to the top of the container.

I have managed to get around this by creating two classes in my CSS file image-P & image-L

image-L has a "padding-top:100px " which successfully vertially aligns the landscape images in the centre.

What I'd like to do is for the code to check which images are landscape and then create

return '<img src="Images/' + item.url + '" class="image-L" alt="" />';

and anything else use

return '<img src="Images/' + item.url + '" class="image-P" alt="" />';

many thanks in advance.

Cheers Rob.

<script type="text/javascript">

    var mycarousel_itemList = [
        { url: "Image1.jpg" },
        { url: "Image2.jpg" },
        { url: "Image3.jpg" },
        { url: "Image4.jpg" },
        { url: "Image5.jpg" },
        { url: "Image6.jpg" },
        { url: "Image7.jpg" },
        { url: "Image8.jpg" },
        { url: "Image9.jpg" },
        { url: "Image10.jpg" }
    ];

    function mycarousel_itemLoadCallback(carousel, state) {
        for (var i = carousel.first; i <= carousel.last; i++) {
            if (carousel.has(i)) {
                continue;
            }

            if (i > mycarousel_itemList.length) {
                break;
            }

            carousel.add(i, mycarousel_getItemHTML(mycarousel_itemList[i - 1]));
        }
    };

    /**
    * Item html creation helper.
    */
    function mycarousel_getItemHTML(item) {
        return '<img src="Images/' + item.url + '" class="image-L" alt="" />';
    };

    jQuery(document).ready(function () {
        jQuery('#mycarousel').jcarousel({
            size: mycarousel_itemList.length,
            itemLoadCallback: { onBeforeAnimation: mycarousel_itemLoadCallback }
        });
    });

j0k
  • 22,600
  • 28
  • 79
  • 90

3 Answers3

0

You could try loading the image into JavaScript [1] with the Image class [2] and check the height/width of the image itself to determine which class to apply, but this would slow things down if you did it at load time. (I don't know if the browser would cache the file or not for when you went to display it later).

It seems like it'd be better to wait and apply the style after the image has been added to the document/displayed.

You could probably use jQuery to get the height of the (browser) view and the height of the image then absolutely position the image to be centered. (That'd be more flexible if you wanted to use different image sizes later).

  1. http://www.techrepublic.com/article/preloading-and-the-javascript-image-object/5214317
  2. http://www.w3schools.com/jsref/dom_obj_image.asp
paul
  • 1,655
  • 11
  • 23
  • Thanks. I used the first link to add an image preloader for the 10 images. the page did not fall over so I guess that part worked. It now looks like this – user1382650 May 09 '12 at 10:45
  • I need a piece of code that can now check if the Height is = < 400px to apply the correct CSS class. Any ideas how to put that together please? – user1382650 May 09 '12 at 11:01
  • Don't do the pre-loading of all the images in a separate function; do a pre-load of each image you pass to the `mycarousel_getItemHTML` function *in that function* and check the height property after that (`var x = new Image(); x.src = item.url; if (x.height <= 400) {...`), then you can decide which class to apply to it and put that in your return value. – paul May 10 '12 at 12:46
  • I would still recommend positioning the images dynamically after the page loaded instead of this method. – paul May 10 '12 at 12:54
  • it sort of works but both portrait and landscape are both lowered. – user1382650 May 10 '12 at 18:34
  • 'code' function mycarousel_getItemHTML(item) { var x = new Image(); x.src = item.url; if (x.height <= 400) return ''; else return ''; }; – user1382650 May 10 '12 at 18:38
  • Try adding a check/wait to make sure the image load completed before doing the conditional (so after the `x.src = item.url;` line); http://corpocrat.com/2009/07/02/how-to-check-if-image-loaded-or-not-in-javascript/ (perhaps `while (!x.complete) ;` though this is really bad form...) – paul May 10 '12 at 18:51
  • I tried this, hopefully I followed your instruction. both while and if did not change anything. same as before where both portrait and landscape images have moved down. – user1382650 May 10 '12 at 20:36
  • function mycarousel_getItemHTML(item) { var x = new Image(); x.src = item.url; if (!x.complete) { if (x.height <= 400) return ''; else return ''; } }; – user1382650 May 10 '12 at 20:37
  • You don't want to do the height comparison until after the load completes, so instead of putting that in the `if` that looks at `x.complete`, do this: `while (!x.complete) {}` (note the empty curly braces) and then write the `if (x.height...` part. Doing it the way you've specified it will try to check the height before the image completes loading. Anyway, if *both* of the images moved down by the same amount from where you want them, why not adjust the CSS? – paul May 11 '12 at 00:44
  • I have two CSS classes one for landscape and another for portrait. The landscape has a margin-top: 100px. I think from what you are saying is that the code did not work and the first return is using the landsacpe class and applied to all images. Anyway, I'll try your suggestion above later when i get back from work and see how that goes and let you know. BTW - Many thanks for your help so far, it's very much appreciated. Ive not done much with JS and pretty new to it. – user1382650 May 11 '12 at 08:02
  • I tried your suggestion and with the open curly braces the page does not load and crashes, without them it loads ok but shifts both image orientations. I assume its just picking up the first class and applying to all images.`function mycarousel_getItemHTML(item) { var x = new Image(); x.src = item.url; while (!x.complete) {} if (x.height <= 400) return ''; else return ''; };` – user1382650 May 11 '12 at 17:14
  • Could you update your answer post with all the relevant code you're using (HTML, CSS, JavaScript) so I can see it in context? I'll try fiddling with it. – paul May 12 '12 at 01:02
  • Hi, here is the CSS classes I use from the Site.css stylesheet the html and script are above in the latest answer. Thanks. `.image-P { border-style: solid; border-color: #c7c7c7; border-width: 1px; } .image-L { border-style: solid; border-color: #c7c7c7; border-width: 1px; margin-top: 100px; }` – user1382650 May 12 '12 at 10:36
  • It occurred to me that you could just put a `class` attribute along with the `url` for each item in your array (e.g. `{url: "image.jpg", class: "image-L"}`) and use that when constructing the HTML for the item. I presume these images will either be static so you'll always know what size they should be or that you will be able to access them when the page is generated so you could have ASP/C# detect what the image sizes are and plug in the appropriate class name. – paul May 14 '12 at 00:01
  • Btw, you'll need to add `itemFallbackDimension: 400,` to your carousel stuff (see: http://stackoverflow.com/questions/3784925/jcarousel-no-width-height-set-for-items-this-will-cause-an-infinite-loop-abor) – paul May 14 '12 at 00:10
  • Hi Paul, I went with your idea of `{ url: "Image1.jpg", class: "image-P" }`, which seems to be the simplest way to achieve what I'm after. The itemfallbackDimesion did not work for me. Anyway, I just wanted to say thanks for all your help with trying to figure this one out. Cheers Rob. – user1382650 May 14 '12 at 22:00
  • Glad I could be of help. Sorry a solution took so long and was so round-about -- my JavaScript is rusty and I don't know jQuery. – paul May 14 '12 at 23:15
0

My solution:

    <script type="text/javascript">

    function preloader() {

        // counter     
        var i = 0;

        // create object     
        imageObj = new Image();

        // set image list     
        images = new Array();
        images[0] = "Images/image1.jpg"
        images[1] = "Images/image2.jpg"
        images[2] = "Images/image3.jpg"
        images[3] = "Images/image4.jpg"
        images[4] = "Images/image5.jpg"
        images[5] = "Images/image6.jpg"
        images[6] = "Images/image7.jpg"
        images[7] = "Images/image8.jpg"
        images[8] = "Images/image9.jpg"
        images[9] = "Images/image10.jpg"

        // start preloading     
        for (i = 0; i <= 9; i++) {
            imageObj.src = images[i];
        }
    }   
</script>


<script type="text/javascript">

    var mycarousel_itemList = [
{ url: "Images/Image1.jpg" },
{ url: "Images/Image2.jpg" },
{ url: "Images/Image3.jpg" },
{ url: "Images/Image4.jpg" },
{ url: "Images/Image5.jpg" },
{ url: "Images/Image6.jpg" },
{ url: "Images/Image7.jpg" },
{ url: "Images/Image8.jpg" },
{ url: "Images/Image9.jpg" },
{ url: "Images/Image10.jpg" }
];

    function mycarousel_itemLoadCallback(carousel, state) {
        for (var i = carousel.first; i <= carousel.last; i++) {
            if (carousel.has(i)) {
                continue;
            }

            if (i > mycarousel_itemList.length) {
                break;
            }

            carousel.add(i, mycarousel_getItemHTML(mycarousel_itemList[i - 1]));
        }
    };

    /**
    * Item html creation helper.
    */
    function mycarousel_getItemHTML(item) {
        return '<img src="' + item.url + '" class="image" alt="" />';
    };

    jQuery(document).ready(function () {
        jQuery('#mycarousel').jcarousel({
            size: mycarousel_itemList.length,
            itemLoadCallback: { onBeforeAnimation: mycarousel_itemLoadCallback }
        });
    });

</script>
eeerahul
  • 1,629
  • 4
  • 27
  • 38
0
<%@ Page Title="" Language="C#" MasterPageFile="~/rwmSite.master" AutoEventWireup="true"
    CodeFile="Portfolio.aspx.cs" Inherits="Portfolio" %>

<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="Server">
    <link href="../Styles/Site.css" rel="stylesheet" type="text/css" />
    <script src="../Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
    <script src="../Scripts/jquery.jcarousel.min.js" type="text/javascript"></script>
    <script type="text/javascript">


        var mycarousel_itemList = [
            { url: "Image1.jpg" },
            { url: "Image2.jpg" },
            { url: "Image3.jpg" },
            { url: "Image4.jpg" },
            { url: "Image5.jpg" },
            { url: "Image6.jpg" },
            { url: "Image7.jpg" },
            { url: "Image8.jpg" },
            { url: "Image9.jpg" },
            { url: "Image10.jpg"}];

        function mycarousel_itemLoadCallback(carousel, state) {
            for (var i = carousel.first; i <= carousel.last; i++) {
                if (carousel.has(i)) {
                    continue;
                }

                if (i > mycarousel_itemList.length) {
                    break;
                }

                carousel.add(i, mycarousel_getItemHTML(mycarousel_itemList[i - 1]));
            }
        };

        /**
        * Item html creation helper.
        */
        function mycarousel_getItemHTML(item) {

            var x = new Image(); x.src = item.url;
            while (!x.complete)

                if (x.height <= 400)

                    return '<img src="../Images/' + item.url + '" class="image-L" alt="" />';
                else
                    return '<img src="../Images/' + item.url + '" class="image-P" alt="" />';
        };

        jQuery(document).ready(function () {
            jQuery('#mycarousel').jcarousel({
                size: mycarousel_itemList.length,
                itemLoadCallback: { onBeforeAnimation: mycarousel_itemLoadCallback }
            });
        });
    </script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="Server">
    <div id="wrap" align="center">
        <div class=" jcarousel-skin-tango">
            <div class="jcarousel-container jcarousel-container-horizontal">
                <div class="jcarousel-clip jcarousel-clip-horizontal">
                    <ul id="mycarousel" class="jcarousel-list jcarousel-list-horizontal">
                    </ul>
                </div>
                <div class="jcarousel-prev jcarousel-prev-horizontal">
                </div>
                <div class="jcarousel-next jcarousel-next-horizontal">
                </div>
            </div>
        </div>
    </div>
</asp:Content>