pisi / Reel

The premier 360° solution for jQuery.
http://reel360.org
MIT License
689 stars 210 forks source link

Skipping frames / dropping frames / not loading certain frames #173

Closed joeshock closed 11 years ago

joeshock commented 11 years ago

I'm having an issue mostly with PC browsers where certain frames in the reel aren't loaded, in fact they're skipped and all I get is a broken image icon (x).

All of the browsers reporting this issue do in fact acknowledge the total frame count, so they are aware of all of the frames that need to be loaded but will sporadically skip loading random frames. Logic confirming these images aren't loading at all comes from using Fiddler and some other utilities.

For example a sequence with 260 images may show up like this in Fiddler. ... ...... image-240.jpg image-241.jpg image-242.jpg image-243.jpg image-245.jpg image-247.jpg image-248.jpg image-249.jpg image-252.jpg ...... ...

Wondering if maybe there is an image load limit on these browsers or a cache limit and the browser just can't load anymore in memory?

Any thoughts appreciated. Thanks!

joeshock commented 11 years ago

Some clarification if it helps. This issue isn't just happening on PC browsers. It's happening on all browsers. The PC browsers just seem to have trouble figuring out how many frames ACTUALLY loaded and trimming the length of the reel. Instead there are blank frames left in the sequence where some images didn't load and hence the image not being found.

Safari on the Mac seems to figure this out just fine and load the sequence just fine even if there are a few dropped frames it still works and doesn't show a flicker where the other images are missing. It seems like it removes the gap in the virtual timeline if you will.

pisi commented 11 years ago

Looks to me like a bad configuration so far. Nothing much to say without actually seeing it... If you can not disclose publicly, mail confidentially to petr at vostrel dot cz. Alternativelly, perhaps the best, you can try to isolate the core of your problem into a jsFiddle for instance - this alone often helps tremendously in pin-pointing the problem.

Generally speaking, sky's the limit here. How do you feed the image sequence to .reel()? Is it with sequence string or is it a ready-made Array?

joeshock commented 11 years ago

Thanks so much for the feedback! I'm getting the same feeling you are here that it's an implementation issue. Maybe we're requesting the plugin loads too many images at a time and it misses some. Here is a snippet from my code that may help answer your question above.

This function is triggered by a link being clicked. A link that has a "rel" attribute that matches a naming convention variable to build the filename strings.

    function initAnimation(el) {
        var rel = (el.attr('rel') === undefined) ? el.attr('id') : el.attr('rel');
        var frames = animationsLength[rel]["length"];
        var prefix = rel.substring(0, 3);
        var cursor = 'hand';
        var loops = false;
        var cw = false;
        var path = 'images/360s/' + prefix;
        var wheelable = false;
        var speed = 0.35;
        var preload = "fidelity";
        var tempo = 12;
        var targetFrame = $(el).data().frames;
        var currentFrame = $(el).reel('frame');

        $('#' + rel)
            .reel({
                revolution: 360,
                wheelable: wheelable,
                cursor:cursor,
                loops:loops,
                cw: cw,
                speed: speed,
                preload: preload,
                path: path + '/',
                frames: frames,
                images: returnFrames(rel + "-",frames)
            })
            .bind('frameChange', function() {
                //console.log($(this).reel('frame'));
                //console.log(rel + "-" + $(this).reel('frame'));
                frameChange();
                if ($(this).reel('frame') == frames) {
                    $(this).trigger('stop');
                }
            });
        $(el).data('firstRun',false);
    }
pisi commented 11 years ago

I ment see it running, but this helps a little too. However the source of what returnFrames() returns is missing. Since I can not see it live and debug it, please, when the Reel is running, execute this line in the developers's console:

    $.reel.instances.eq(0).reel('images')

and report back.

However, link to a live version would be awesome.

joeshock commented 11 years ago

Wow. Tracing that in the console returns all of the images in the sequence it seems but the console is logging two arrays of the sequence when I log it within the function as such. Could that be part of the problem you think or do you think that should be ok?

    function initAnimation(el) {
        var rel = (el.attr('rel') === undefined) ? el.attr('id') : el.attr('rel');
        var frames = animationsLength[rel]["length"];
        var prefix = rel.substring(0, 3);
        var cursor = 'hand';
        var loops = false;
        var cw = false;
        var path = 'images/360s/' + prefix;
        var wheelable = false;
        var speed = 0.35;
        var preload = "fidelity";
        var tempo = 12;
        var targetFrame = $(el).data().frames;
        var currentFrame = $(el).reel('frame');

        $('#' + rel)
            .reel({
                revolution: 360,
                wheelable: wheelable,
                cursor:cursor,
                loops:loops,
                cw: cw,
                speed: speed,
                preload: preload,
                path: path + '/',
                frames: frames,
                images: returnFrames(rel + "-",frames)
            })
            .bind('frameChange', function() {
                //console.log($(this).reel('frame'));
                //console.log(rel + "-" + $(this).reel('frame'));
                console.log($.reel.instances.eq(0).reel('images'));<------------------------------
                frameChange();
                if ($(this).reel('frame') == frames) {
                    $(this).trigger('stop');
                }
            });
        $(el).data('firstRun',false);
    }
pisi commented 11 years ago

Here you log it on every frame, hence the "duplication". What interest me is what that frameChange() does?

Just a side idea/note. images accepts also a string notation, which is explained here and takes care of the sequence generation for you. In your case (I only used 4 frames total for simplification) instead of direct Array:

    frames: 4,
    images: [
      'image-1.jpg',
      'image-2.jpg',
      'image-3.jpg',
      'image-4.jpg'
    ]

You can use a string sequence notation like this:

    frames: 4,
    images: 'image-#.jpg'

Both these are equivalent.

pisi commented 11 years ago

After doing the walkthrough of the site (impressive btw!) and when I returned back to the full split view (the with blue arrows), I tried what I always do, typed $.reel.instances into console. This is a jQuery object of all currently running Reel instances on the page. At that time, I would expect seeing just one Reel inside, but the clearance one stays alive too, so there were two simultaneous instances. After toying with in back and forth, I've end up with three (!) - three Reel instances running side by side at the same time. Are you sure the implementation initializing Reel is solid?

However, despite these findings, I had hard time replicating the issue at hand so far...

joeshock commented 11 years ago

Great feedback. Thanks again for the assistance so far pisi.

Here is the frameChange() function for your reference. I'm going to do a little more digging given your thoughts above and see if I can get some different behavior.

    function frameChange() {
        var frame = $(curView).reel('frame');
        var frameTotal = $(curView).data().frames;
        //console.log("frame " + frame + " of " + frameTotal);
        var overlay = $(curView + '-holder').find('div.overlay-holder');
        if(frame >= frameTotal - 17) {
            overlay.show();
        } else {
            overlay.hide();
        }
        if(frame == frameTotal) {
            //console.log("frame == frameTotal");
            setControls('cw');
        } else {
            setControls();

        }
        if(frame == 1) {
            setControls('ccw');
        }
    }

and the setControls() function as well since it's mentioned above.

    function setControls(dir) {
        if(dir === undefined) {
            $('.ccw').add('.cw').removeClass('inactive');
        } else if(dir == 'cw') {
            $('.cw').addClass('inactive');
            $('.ccw').removeClass('inactive');
        } else if(dir == 'ccw') {
            $('.ccw').addClass('inactive');
            $('.cw').removeClass('inactive');
        }
    }
joeshock commented 11 years ago

Pisi,

I believe I've narrowed down the issue with the multiple reels. It appears to only be happening after you've viewed a component animation and then click the X on the info tab. I'm going to look into what's happening when that X button is clicked next and hopefully provide an update on it.

$.reel.instances

This ^ has been very helpful.

pisi commented 11 years ago

The $.reel object has few more neat feats inside such as $.reel.cost holding processing cost per tick. This can give you an idea, how much the CPU is occupied each tick. The number is in milliseconds and per all instances. There's also $.reel.version string or $.reel.cdn configuration where Reel finds its cursors. See the annotated code, where sections Regular Expressions through Reel Instances document the global namespace members.

joeshock commented 11 years ago

Thanks again Pisi!

Progress for sure! Making sure there was only one reel instance in the object definitely helped out the trouble of images failing to load. It's still happening but nowhere near as frequently as when I had two reel instances in the object. I think I'm in a place that makes this experience acceptable for our client now. Thank you so much for all of your help. Feel free to revisit the link I shared privately via email to see if you notice any performance improvements if you'd like as well.

I sincerely appreciate your help and your plugin. Thanks again!

-joeshock