ProgressiveImageSequence Breaks in chrome, jquery

2019-08-08 17:09发布

PROBLEM: ProgressiveImageSequence Breaks in chrome but not other browsers

BACKGROUND: I am building an interactive web page that takes a jpg sequence and plays through it as the user scroll up or down the page. the page that inspired this and that I am using to base my code off of is http://360langstrasse.srf.ch/page/. using 360lang's beautifully built ProgressiveImageSequence Created by Hinderling Volkart AG. There is a turtorial that goes over the basics of it, Though the demos they give dont respond to touch screens and if the jpg sequence is large enough will begin to break in browsers, specially chrome.

The link to my webpage is http://blackbirdstudio5.com/videoscroll2/

DETAILS: I have gotten the page to work on touch screens and all browsers except for CHROME. (I believe it works on IE but my testing has been limited). If you open my webpage the page will work for a bit and then about half way down will crash and I will get the "AWW SNAP" message from chrome. If you scroll SLOWLY down the page, you will see this happen.(emphasize slowly because it seems to break faster when you scroll slow)(Also the text boxes will stick in firefox if used enough but I believe that because they overlap. But if not I would love to know the answer)

HELP: Can someone please help me fix this page so it works in Chrome.

  • (not important: I would also like to have a loading overlay page till 10% of the image sequence is loaded)
  • (not important: Fire fox seems to freeze some of the text divs. i believe its because they overlap but if its because another reason it would be great to know)

I am mediocre at best with jquery so please act like im a newbie and explain your answers.

NOTES:

  • If I take out all text the page will last longer but will still
  • break If I take out all text and replace it with images the page will last longer but still break
  • In reaserching people said chrome has an issue with cache-ing ajax requests
  • there is allot of code here that I know I dont need but every time i try to take it away it breaks my sequence. I would love to have the jquery bare bones.

CODE:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=780,user-scalable=no"/>
<title>video scroll</title>
<meta name="viewport" content="width=1024,user-scalable=no"/>
<link rel="stylesheet" href="css/makingcigar.css" type="text/css">
<script src="js/jquery-1.11.1.min.js"></script>
<script src="js/modernizr.js"></script>

</head>
<div id="main" style="height: 10000px;">
  <div class="navigation">
    <ul>
  <li><a href="#cigar">Art Form</a></li>
  <li><a href="#nursery">Start Small</a></li>
  <li><a href="#nursery2">Nursery</a></li>
  <li><a href="#nursery3">Nursery Cont.</a></li>
  <li><a href="#fields1">Fields</a></li>
  <li><a href="#fields2">Wrapper, Binder, Filler</a></li>
    </ul>
  </div>
  <div class="street-view"><img src="making_images/vid-0001.jpg"></div>
  <div id="cigar" class="hotspot left" data-day="14" data-night="16" data-speed="2.8">
<div class="content">
  <div class="title">
    <h3>Cigar as an Art Form</h3>
  </div>
  <div class="description">
    <p>Great cigars are more...</p>
    <h6>DISCOVER HOW CIGARS ARE CREATED</h6>
    <div class="clearfix"> </div>
    <h4>SCROLL TO DISCOVER MORE</h4>
  </div>
</div>
  </div>
  <div id="nursery" class="hotspot right" data-day="16.8" data-night="17.2" data-speed="1.8">
<div class="content">
  <div class="title">
    <h3>Nursery</h3>
    <h5>Think Big. Start Small.</h5>
    <div class="divider"></div>
  </div>
  <div class="description">
    <p>All great ideas start out small...</p>
  </div>
</div>
 </div>
 <div id="nursery2" class="hotspot left" data-day="19" data-night="18.5" data-speed="2">
<div class="content">
  <div class="title">
    <h3>NURSERY</h3>
    <div class="divider"></div>
  </div>
  <div class="description">
    <p>At our main ...</p>
  </div>
</div>
 </div>
 <div id="nursery3" class="hotspot right" data-day="21.15" data-night="21" data-speed="3">
<div class="content">
  <div class="title">
    <h3>NURSERY</h3>
    <h5>Only the best. No exceptions.</h5>
    <div class="divider"></div>
  </div>
  <div class="description">
    <p>Before leaving the mai...</p>
  </div>
</div>
 </div>
 <div id="fields1" class="hotspot left" data-day="25.5" data-night="22.25" data-speed="2.2">
<div class="content">
  <div class="title">
    <h3>FIELDS</h3>
    <h5>From the ground up</h5>
    <div class="divider"></div>
  </div>
  <div class="description">
    <p>Prior to each ...</p>
  </div>
</div>
 </div>
 <div id="fields2" class="hotspot right" data-day="28" data-night="24.25" data-speed="2.5">
<div class="content">
  <div class="title">
    <h3>CIGAR'S CONSTRUCTION </h3>
    <h5>Wrapper, Binder, & Filler</h5>
    <div class="divider"></div>
  </div>
  <div class="description">
    <p>Our cigars are p... AND A BUNCH MORE OF THESE DESCRIPTION DIVS ALL IN THE SAME FORMAT</p>
  </div>
</div>
</div>
</div>

<script src="js/jquery-migrate-1.2.1.min.js"></script> 
<script src="js/ProgressiveImageSequence.class.js"></script> 
<script>        
$(document).ready(function(){
        var $doc = $(document);
        var $win = $(window);
        var isTouch = 'ontouchstart' in window;


        var isChrome = navigator.userAgent.indexOf('Chrome') > 0;


        // dimensions
        var windowHeight, windowWidth;
        var fullHeight, scrollHeight;
        var bgImgWidth = 512, bgImgHeight = 320;
        calculateDimensions();

        // states
        var isNight = false;
        var currentPosition = getScrollTop() / scrollHeight;
        var targetPosition = currentPosition;

        // collect timeline elements
        var $videoImage = $('.street-view > img');
        var $allNavAnchors = $('#main .navigation a');

        var $timeElements = $('[data-day]');
        var timeElements = [];
        var hotspots = {};
    $timeElements.each(function(){
            var $view = $(this);
            var id = $view.attr('id');
            var elem = new TimeElement(this);
            timeElements.push( elem );

            if ( id ) hotspots[id] = elem;

        //  console.log(timeElements);

            var offset = $view.offset();
            $view.css({position: 'fixed' , top: offset.top });
        });

        // handle anchor links
        $('a[href^="#"]').click(function(event){
            event.preventDefault();
            var target = $(this).attr('href').substr(1);

            console.log(target);

            var hotspot = hotspots[target];
            if ( hotspot ) {
                var pos = hotspot.getPosition();
                setScrollTop( pos * scrollHeight );
            }
        });
        function setScrollTop(value) {
            $win.scrollTop(value);
        }       
        function getScrollTop() {
            return $win.scrollTop() || (document.documentElement && document.documentElement.scrollTop);
        }           
        function calculateDimensions() {
            windowWidth = $win.width();
            windowHeight = $win.height();
            fullHeight = $('#main').height();
            scrollHeight = fullHeight - windowHeight;
        }
        function setTargetPosition( position , immediate ) {
            targetPosition = position;
            if ( immediate ) currentPosition = targetPosition;
        }
        function handleResize() {
            calculateDimensions();
            renderBackgroundImage();
            renderTimeline( currentPosition );
            renderNavigation();
            handleScroll();
        }
        function handleScroll() {
            setTargetPosition( getScrollTop() / scrollHeight );
            activateElement( $('.navigation') , targetPosition < 0.001 );
        }

        // rendering
        var scrollActivateTimeout;

        function renderTimeline( position ) {
            var minY = -500, maxY = windowHeight + 500;
            // element position
            $.each(timeElements,function(index,element){
                var elemPosition = element.getPosition();
                var elemY = windowHeight/2 + element.speed * (elemPosition-position) * scrollHeight;
                var active = false;
                if ( elemY < minY ||elemY > maxY ) {
                    element.view.css({'visiblity':'none', top: '-1000px','webkitTransform':'none'});
                } else {
                    element.view.css('visiblity','visible');
                    positionElement(element.view,null,elemY);
                    if ( elemY < windowHeight/2 ) {
                        var x = (windowHeight/2 - elemY)/100;
                        x = x*x * 20;
                        if ( element.view.hasClass('hotspot') ) {
                            if ( element.view.hasClass('right') ) {
                                element.view.css('margin-right',-x);
                            } else
                            if ( element.view.hasClass('left') ) {
                                element.view.css('margin-left',-x);
                            }
                        }
                    } else
                    if ( element.view.hasClass('hotspot') ) {
                        element.view.css({'margin-left':0,'margin-right':0});
                    }

                    if ( element.view.is('.twitter') ) {
                        var sinMargin = Math.sin(elemY/300)*100;
                        element.view.css({'margin-left':sinMargin,'margin-right':sinMargin});
                    }
                    active = Math.abs(windowHeight/2 - elemY) < Math.max(windowHeight/5,100);
                }
                if ( getElementActive(element.view) != active ) {
                    clearTimeout( element.scrollActivateTimeout );
                    setElementActive(element.view,active);
                    function doit() {
                        activateElement( element.view , active );
                    }
                    if ( active ) {
                        if (active) playSound(element.view.attr('id'));
                        element.scrollActivateTimeout = setTimeout( doit , 1000 );
                    } else {
                        doit();
                    }
                    activateElement( element.anchor , active );
                }
            });

            // video
            showImage( currentPosition );
        }
        function renderNavigation() {
            var MINGAP = 30;
            var $navigation = $('#main > .navigation');
            var scrollThumbHeight = Math.max( 30 , (windowHeight/fullHeight)*windowHeight );
            var availableHeight = windowHeight - scrollThumbHeight;
            var all = [];
            // put all hotspots in array and sort by position
            $.each(hotspots,function(k,v){ all.push(v); });
            all.sort(function(a,b){return a.getPosition()-b.getPosition();});
            var y = 0;
            $.each(all,function(index,element){
                if ( !element.anchor ) return;
                var $anchor = $(element.anchor);
                var pos = element.getPosition();
                y = Math.max( y + MINGAP , pos * availableHeight + scrollThumbHeight/2 );
                $anchor.css('top',y);
            });
        }
        function positionElement( elem , x , y ) {
            if ( Modernizr.csstransforms ) {
                var xpos = ( x === null ? $.data(elem,'x') : x ) || 0;
                var ypos = ( y === null ? $.data(elem,'y') : y ) || 0;
                $.data(elem,'x',xpos);
                $.data(elem,'y',ypos);
            }

            if ( $.browser.safari) { //&& !isTouch && !isChrome ) {
                elem.css({top:-1000,webkitTransform:'translate3d('+(xpos)+'px,'+(ypos+1000)+'px,0px)'});
            } else 
            if ( Modernizr.csstransforms ) {
                var transform = 'translate('+(xpos)+'px,'+(ypos+1000)+'px)';
                elem.css({
                    '-webkit-transform':transform,
                    '-moz-transform':transform,
                    '-o-transform':transform,
                    '-ms-transform':transform
                });
            } else
            {
                if ( x !== null ) {
                    elem.css('left',x);
                }
                if ( y !== null ) {
                    elem.css('top',y);
                }
            }
        }
        function activateElement( elem , active ) {
            $.data( elem , 'active' , active );
            active ? elem.addClass('active') : elem.removeClass('active');
        }
        function setElementActive( elem , active ) {
            $.data( elem , 'active' , active );
        }
        function getElementActive( elem ) {
            return $.data( elem , 'active' );
        }

        function renderBackgroundImage(){
            // get image container size             
            var scale = Math.max( windowHeight/bgImgHeight , windowWidth/bgImgWidth );
            var width = scale * bgImgWidth , height = scale * bgImgHeight;
            var left = (windowWidth-width)/2, top = (windowHeight-height)/2;
            if ( ($.browser.safari || isTouch) && !isChrome ) {
                var transform = 'translate3d('+[-bgImgWidth/2,-bgImgHeight/2,0].join('px,')+'px) scale3d('+scale+','+scale+',1) translate3d('+[windowWidth/2/scale,windowHeight/2/scale,0].join('px,')+')';
                $videoImage
                    .width(bgImgWidth).height(bgImgHeight)
                    .css('-webkit-transform',transform)
                      .css({'position':'fixed', top: 0, left: 0});
            } else
            if ( Modernizr.csstransforms ) {
                console.log('Using 2D transforms');
                var transform = 'translate('+[-bgImgWidth/2,-bgImgHeight/2].join('px,')+'px) scale('+scale+') translate('+[windowWidth/2/scale,windowHeight/2/scale].join('px,')+'px)';
                $videoImage
                    .width(bgImgWidth).height(bgImgHeight)
                    .css({
                        '-webkit-transform':transform,
                        '-moz-transform':transform,
                        '-o-transform':transform,
                        '-ms-transform':transform
                    })
                      .css({'position':'fixed', top: 0, left: 0});
            } else {
                $videoImage
                      .width(width).height(height)
                      .css('position','fixed')
                      .css('left',left+'px')
                      .css('top',top+'px');
            }
        }
        // main render loop
        window.requestAnimFrame = (function(){
          return  window.requestAnimationFrame       ||
                  window.webkitRequestAnimationFrame ||
                  window.mozRequestAnimationFrame    ||
                  window.oRequestAnimationFrame      ||
                  window.msRequestAnimationFrame     ||
                  function(/* function */ callback, /* DOMElement */ element){
                    window.setTimeout(callback, 1000 / 60);
                  };
        })();
        function animloop(){
          requestAnimFrame(animloop);
            if ( Math.floor(currentPosition*5000) != Math.floor(targetPosition*5000) ) {
                var deaccelerate = Math.max( Math.min( Math.abs(targetPosition-currentPosition)*5000 , 10 ) , 2 );
                currentPosition += (targetPosition - currentPosition) / deaccelerate;
                renderTimeline(currentPosition);
            }
        }
        animloop();
        // video handling
        var daySeqLoader = new ProgressiveImageSequence( "making_images/vid-{index}.jpg", 633,  {
            indexSize: 4,
            onProgress: handleLoadProgress,
            onComplete: handleLoadComplete,
            stopAt: isSlowBrowser() ? (isTouch?4:8) : 1
        } );
        var imageSeqLoader = daySeqLoader;

        var loadCounterForIE = 0; // there seems to be a problem with ie calling the callback several times
        imageSeqLoader.loadPosition(currentPosition,function(){
            loadCounterForIE++;
            if ( loadCounterForIE == 1 ) {
                showImage(currentPosition);
                imageSeqLoader.load();
                imageSeqLoader.load();
                imageSeqLoader.load();
                imageSeqLoader.load();
            }
        });
        var nightSeqLoader = new ProgressiveImageSequence( "making_images/vid-{index}.jpg", 633,  {
            indexSize: 3,
            onProgress: handleLoadProgress,
            onComplete: handleLoadComplete,
            stopAt: isSlowBrowser() ? 4 : 1
        } );
        var currentSrc, currentIndex;
        var highresTimeout;
        function showImage(position) {
            var index = Math.round( currentPosition * (imageSeqLoader.length-1) );
            var img = imageSeqLoader.getNearest( index );
            var nearestIndex = imageSeqLoader.nearestIndex;
            if ( nearestIndex < 0 ) nearestIndex = 0;
            var $img = $(img);
            var src;
            if ( !!img ) {
                src = img.src;
                if ( src != currentSrc ) {
                    $videoImage[0].src = src;
                    currentSrc = src;
                }
            }
            clearTimeout(highresTimeout);
            highresTimeout = setTimeout(function(){
                if ( !!src ) {
                    $('#debug').text( nearestIndex + ' / ' + index + ' / ' + (Math.round( index / imageSeqLoader.length * 10000 ) / 100) );
                    var highSrc = src.split('/xs/').join('/l/');
                    loadHighres(highSrc);
                }
            },isSlowBrowser()?500:150);
        }
        window.switchStreetMode = function() {
            switchToMode( isNight ? 'day' : 'night' );
        };
        window.switchToMode = function( mode ) {
            $videoImage.fadeOut(function(){
                var prevHotspot, nextHotspot;
                var all = [];
                // put all hotspots in array and sort by position
                $.each(hotspots,function(k,v){ all.push(v); });
                all.sort(function(a,b){return a.getPosition()-b.getPosition();});
                $.each(all,function(k,v){
                    if ( v.getPosition() > currentPosition ) {
                        nextHotspot = v;
                        prevHotspot = all[k-1];
                        return false;
                    }
                });
                if ( nextHotspot == null ) {
                    prevHotspot = all[all.length-1];
                }
                var prevPos = prevHotspot ? prevHotspot.getPosition() : 0;
                var nextPos = nextHotspot ? nextHotspot.getPosition() : 1;
                var intermediatePosition = (currentPosition-prevPos) / (nextPos-prevPos);

                // let's make the switch
                isNight = mode == 'night';
                $('.toggle[rel="mode"]')[ isNight ? 'addClass' : 'removeClass' ]('active');

                prevPos = prevHotspot ? prevHotspot.getPosition() : 0;
                nextPos = nextHotspot ? nextHotspot.getPosition() : 1;
                targetPosition = currentPosition = intermediatePosition * (nextPos-prevPos) + prevPos;

                imageSeqLoader.stop(); imageSeqLoader.reset();
                imageSeqLoader = isNight ? nightSeqLoader : daySeqLoader;
                var loadCounterForIE = 0; // there seems to be a problem with ie calling the callback several times
                imageSeqLoader.loadPosition( currentPosition , function() {
                    loadCounterForIE++;
                    if ( loadCounterForIE == 1 ) {
                        setTimeout(function(){
                            imageSeqLoader.load();
                            imageSeqLoader.load();
                            imageSeqLoader.load();
                            imageSeqLoader.load();
                        },10);
                        $(window).scrollTop(targetPosition*scrollHeight);
                        renderNavigation();
                        renderTimeline( currentPosition );
                        showImage( currentPosition );
                        $videoImage.fadeIn();
                    }
                });
            });
        };
        var loadHighresCounter = 0;

        function loadHighres(src) {
            var videoImage = $videoImage[0];
            videoImage.src = src;
        }
        $('body').append('<div id="loading-bar" style="position:fixed; bottom:0; left:0; background-color: #DF0012; background-color: rgba(223,0,18,0.5); height: 1px;"></div>');
        function handleLoadProgress() {
            var progress = imageSeqLoader.getLoadProgress() * 100;
            $('#loading-bar').css({width:progress+'%',opacity:1});
        }

        function handleLoadComplete() {
            $('#loading-bar').css({width:'100%',opacity:0});
        }

        $win.resize( handleResize );
        $win.scroll( handleScroll );

        handleResize();

        // helper classes
        $('.sound .toggle').click(function(event){
            event.preventDefault();
            var $toggle = $(this);
            var isActive = $toggle.hasClass('active');
            if ( isActive ) {
                $toggle.removeClass('active');
            } else {
                $toggle.addClass('active');
            }

        });
        $('.night a').click(function(event){
            event.preventDefault();
            switchStreetMode();
        });
        function TimeElement( view , options ) {
            options = options || {};
            var $view = $(view);
            this.id = $view.attr('id');
            this.view = $view;
            this.anchor = $allNavAnchors.filter('[href="#'+$view.attr('id')+'"]');
            this.anchor = this.anchor.closest('li');
            this.getPosition = function() { return isNight? this.nightPosition : this.dayPosition; };
            this.dayPosition = options.dayPosition || Number( $view.attr('data-day')/100 );
            this.nightPosition = options.nightPosition || Number( $view.attr('data-night')/100 );
            this.speed = options.speed || Number( $view.attr('data-speed') ) || 1;
            this.align = options.align || $view.attr('data-align') || 'left';
        }
        function easeCos(t) {
            return Math.cos( (x*Math.PI+Math.PI)+1 ) / 2;
        }
        function isSlowBrowser() {
            return isTouch || ($.browser.msie && Number($.browser.version) <= 8) ? true : false;
        }

        // sound control

        var soundMuted = false;
        (function(){
            var ambi = document.getElementById('ambi-audio');
            if ( ambi && ambi.play ) {
                $('.mute').show();
                $('.mute > .toggle').click(function(){
                    soundMuted = ambi.muted = !ambi.muted;
                    $(this)[ ambi.muted ? 'addClass' : 'removeClass' ]('active');
                    $(this).parent()[ ambi.muted ? 'addClass' : 'removeClass' ]('active');
                });
            }
        })();
        function playSound( name ) {
            var snd = document.getElementById(name+'-audio');
            if ( !soundMuted && snd && snd.play && Math.random() < 0.3 ) {
                if ( snd.currentTime == 0 || snd.ended ) {
                    snd.volume = 0.4;
                    snd.currentTime = 0;
                    snd.play();
                }
            }
        }       
        function addSounds( sounds ) {
            var $body = $('body');
            $.each( sounds , function(i,name) {
                var $audio = $('<audio id="'+name+'-audio" preload="auto" autobuffer><source src="/img/'+name+'.mp3"><source src="/img/'+name+'.ogg"></audio>').hide();
                $body.append( $audio );
            });
        }

        setTimeout(function(){
            addSounds(['host','zkft','kita','hohl','zapo']);
        },1000);

        // touch override

        if ( isTouch ) {

            (function(){

                $('#main').css('height',1);

                var scrollPos = 0;
                var MAXSCROLL = 10000;

                var oldCalculateDimensions = calculateDimensions;
                calculateDimensions = function() {
                    oldCalculateDimensions();
                    scrollHeight = MAXSCROLL - windowHeight;
                };

                var oldGetScrollTop = getScrollTop;
                getScrollTop = function() {
                    return scrollPos;
                };

                var oldSetScrollTop = setScrollTop;
                setScrollTop = function(value) {
                    scrollPos = value;
                    dispatchScroll();
                };

                function dispatchScroll() {
                    targetPosition = scrollPos / scrollHeight;
                }

                var d = document;
                var touchMoved, touchDown, touchBeginPosition, isLinkTouch;

                function onTouchStart(event) {
                    var isNavigation = $(event.target).filter('a');
                    if ( isNavigation.length ) {
                        isNavigation = isNavigation.parents('.navigation').length >= 1;
                        return;
                    }
                    if ( $(event.target).parents('a').length == 0 ) {
                        event.preventDefault();
                    }
                    touchDown = true;
                    var touch = event.touches[0];
                    touchX = touch.clientX;
                    touchY = touch.clientY;
                    touchBeginPosition = { x: touchX , y: touchY , scroll: scrollPos };
                    d.addEventListener('touchmove', onTouchMove, false);
                    d.addEventListener('touchend', onTouchEnd, false);
                }
                function onTouchMove(event) {
                    event.preventDefault();
                    var touch = event.touches[0];
                    touchX = touch.clientX;
                    touchY = touch.clientY;
                    var dy = (touchY-touchBeginPosition.y);
                    if ( Math.abs(dy) > 3 ) {
                    touchMoved = true;
                    }
                    scrollPos = touchBeginPosition.scroll - dy * 2;
                    scrollPos = Math.min( MAXSCROLL , Math.max( 0 , scrollPos ) );
                    dispatchScroll();
                }
                function onTouchEnd(event) {
                    if ( touchMoved ) {
                        event.preventDefault();
                    }

                    d.removeEventListener('touchmove', onTouchMove, false);
                    d.removeEventListener('touchend', onTouchEnd, false);
                    touchDown = false;
                }

                d.addEventListener('touchstart', onTouchStart, false);
                //d.getElementsByClassName('street-view')[0].addEventListener('touchstart', onTouchStart, false);
            })();

        }

    });

</script> 


</body></html>

1条回答
何必那么认真
2楼-- · 2019-08-08 17:51

So I finally figured it out. There is some jquery that got changed up. but not much. But the big thing is that I changed the size of the images in my jpg sequence. That should be under 500px by whatever. this deff helped the speed and crash issues. the other big thing is to set the overflow to the hotspots to auto. (overflow:auto) not sure why this helps so much but deff does. if anyone wants a full look at the code let me know and ill post it

查看更多
登录 后发表回答