Animation flickers with Firefox 18.0.1 (due to RequestAnimationFrame?)

I used this http://www.netmagazine.com/tutorials/create-interactive-street-view-jquery tutorial to create an intro for one of our clients:

http://f-bilandia.de/kunstmann/bronski/

It worked very well in all browsers. However, when I upgrade to the latest stable version of Firefox (FF 18.0.1), a lot of flicker occurs when changing images.

When reading the release notes for the latest version, I saw that ff has a new Javascript engine and improved image quality with the new HTML scaling algorithm. Maybe because of this? Other possible solutions?

Below you can see the code that I used:

$(document).ready(function(){ var $doc = $(document); var $win = $(window); // dimensions - we want to cache them on window resize var windowHeight, windowWidth; var fullHeight, scrollHeight; var streetImgWidth = 1024, streetImgHeight = 640; calculateDimensions(); var currentPosition = -1, targetPosition = 0; var $videoContainer = $('.street-view'); var video = $('.street-view > img')[0]; var $hotspotElements = $('[data-position]'); // handling resize and scroll events function calculateDimensions() { windowWidth = $win.width(); windowHeight = $win.height(); fullHeight = $('#main').height(); scrollHeight = fullHeight - windowHeight; } function handleResize() { calculateDimensions(); resizeBackgroundImage(); handleScroll(); } function handleScroll() { targetPosition = $win.scrollTop() / scrollHeight; } // 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(){ if ( Math.floor(currentPosition*5000) != Math.floor(targetPosition*5000) ) { currentPosition += (targetPosition - currentPosition) / 5; render(currentPosition); } requestAnimFrame(animloop); } // rendering function render( position ) { // position the elements var minY = -windowHeight, maxY = windowHeight; $.each($hotspotElements,function(index,element){ var $hotspot = $(element); var elemPosition = Number( $hotspot.attr('data-position') ); var elemSpeed = Number( $hotspot.attr('data-speed') ); var elemY = windowHeight/2 + elemSpeed * (elemPosition-position) * scrollHeight; if ( elemY < minY || elemY > maxY ) { $hotspot.css({'visiblity':'none', top: '-1000px','webkitTransform':'none'}); } else { $hotspot.css({'visiblity':'visible', top: elemY, position: 'fixed'}); } }); renderVideo( position ); } function resizeBackgroundImage(){ // get image container size var scale = Math.max( windowHeight/streetImgHeight , windowWidth/streetImgWidth ); var width = scale * streetImgWidth , height = scale * streetImgHeight; var left = (windowWidth-width)/2, top = (windowHeight-height)/2; $videoContainer .width(width).height(height) .css('position','fixed') .css('left',left+'px') .css('top',top+'px'); } // video handling var imageSeqLoader = new ProgressiveImageSequence( "street/vid-{index}.jpg" , 387 , { indexSize: 4, initialStep: 16, onProgress: handleLoadProgress, onComplete: handleLoadComplete, stopAt: 1 } ); // there seems to be a problem with ie // calling the callback several times var loadCounterForIE = 0; imageSeqLoader.loadPosition(currentPosition,function(){ loadCounterForIE++; if ( loadCounterForIE == 1 ) { renderVideo(currentPosition); imageSeqLoader.load(); imageSeqLoader.load(); imageSeqLoader.load(); imageSeqLoader.load(); } }); var currentSrc, currentIndex; function renderVideo(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 ) { video.src = src; currentSrc = src; } } } $('body').append('<div id="loading-bar" style="">Loading...</div>'); function handleLoadProgress() { var progress = imageSeqLoader.getLoadProgress() * 100; $('#loading-bar').css({width:progress+'%',opacity:1}); } function handleLoadComplete() { $('#loading-bar').css({width:'100%',opacity:0,display: "none"}); $("html, body").css("overflow", "auto"); $("html, body").css("overflow-x", "hidden"); $("nav").css("display", "block"); $("#preloader").fadeOut("slow"); $("#scroll-hint").css("display", "block"); } $win.resize( handleResize ); $win.scroll( handleScroll ); handleResize(); animloop(); }); 
+4
source share
1 answer

Inside your render (position) function, the following lines look as if they should be reorganized.

  if ( elemY < minY || elemY > maxY ) { $hotspot.css({'visiblity':'none', top: '-1000px','webkitTransform':'none'}); } else { $hotspot.css({'visiblity':'visible', top: elemY, position: 'fixed'}); } 
  • For one appearance, it is written incorrectly, and for it there is no "no" value (it will be "hidden"). Just use "display" with the values ​​"none" and "".
  • The keys "top", "webkitTransform" and "position" seem unnecessary. If the element is not visible, there is no need to set the top one and why the element will not always be fixed?
+1
source

All Articles