0

When I run the javascript code below, it load specified amount of images from Flickr.

By var photos = photoGroup.getPhotos(10) code, I get 10 images from cache.

Then, I can see the object has exactly 10 items by checking console.log(photos);

But actual image appeared on the page is less than 10 items...

I have no idea why this work this way..

Thank you in advance.

<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script>
    var PhotoGroup = function(nativePhotos, callback) {
        var _cache = new Array();

        var numberOfPhotosLoaded = 0;
        var containerWidth = $("#contents").css('max-width');
        var containerHeight = $("#contents").css('max-height');

        $(nativePhotos).each(function(key, photo) {
            $("<img src='"+"http://farm" + photo["farm"] + ".staticflickr.com/" + photo["server"] + "/" + photo["id"] + "_" + photo["secret"] + "_b.jpg"+"'/>")
                .attr("alt", photo['title'])
                .attr("data-cycle-title", photo['ownername'])
                .load(function() { 
                    if(this.naturalWidth >= this.naturalHeight) {
                        $(this).attr("width", containerWidth);
                    } else {
                        $(this).attr("height", containerHeight);
                    }

                    _cache.push(this);

                    if(nativePhotos.length == ++numberOfPhotosLoaded)
                        callback();
                })
        });

        var getRandom = function(max) {
            return Math.floor((Math.random()*max)+1);
        }

        this.getPhotos = function(numberOfPhotos) {
            var photoPool = new Array();
            var maxRandomNumber = _cache.length-1;

            while(photoPool.length != numberOfPhotos) {
                var index = getRandom(maxRandomNumber);

                if($.inArray(_cache[index], photoPool)) 
                    photoPool.push(_cache[index]);
            }

            return photoPool;
        }
    }

    var Contents = function() {
        var self = this;
        var contentTypes = ["#slideShowWrapper", "#video"];

        var switchTo = function(nameOfContent) {
            $(contentTypes).each(function(contentType) {
                $(contentType).hide();
            });

            switch(nameOfContent) {
                case("EHTV") :
                    $("#video").show();
                    break;
                case("slideShow") :
                    $("#slideShowWrapper").show();
                    break;
                default :
                    break;
            }
        }

        this.startEHTV = function() {
            switchTo("EHTV");

            document._video = document.getElementById("video");
            document._video.addEventListener("loadstart", function() {
                document._video.playbackRate = 0.3;
            }, false);
            document._video.addEventListener("ended", startSlideShow, false);
            document._video.play();
        }

        this.startSlideShow = function() {
            switchTo("slideShow");
            var photos = photoGroup.getPhotos(10)
            console.log(photos);
            $('#slideShow').html(photos);
        }

        var api_key = '6242dcd053cd0ad8d791edd975217606';
        var group_id = '2359176@N25';
        var flickerAPI = 'http://api.flickr.com/services/rest/?jsoncallback=?';
        var photoGroup;

        $.getJSON(flickerAPI, {
            api_key: api_key,
            group_id: group_id,
            format: "json",
            method: "flickr.groups.pools.getPhotos",
        }).done(function(data) {
            photoGroup = new PhotoGroup(data['photos']['photo'], self.startSlideShow);
        });

    }

    var contents = new Contents();
</script>
</head>
<body>
<div id="slideShow"></div>
</body>
</html>

1 Answer 1

2

I fix your method getRandom() according to this article, and completely re-write method getPhotos():

    this.getPhotos = function(numberOfPhotos) {
        var available = _cache.length;
        if (numberOfPhotos >= available) {
            // just clone existing array
            return _cache.slice(0);
        }

        var result = [];
        var indices = [];

        while (result.length != numberOfPhotos) {
            var r = getRandom(available);
            if ($.inArray(r, indices) == -1) {
                indices.push(r);
                result.push(_cache[r]);
            }
        }

        return result;
    }

Check full solution here: http://jsfiddle.net/JtDzZ/

But this method still slow, because loop may be quite long to execute due to same random numbers occurred.

If you care about performance, you need to create other stable solution. For ex., randomize only first index of your images sequence.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks Nataliia. Was the getRandom method occurring less items?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.