0

I'm creating a jquery script to vertically pan an image inside its container according to the cursor position.

This is what I've done :

        $(window).load(function(){
            var lastcalc = 0;
            $(".tn3a-image").mousemove(function(e){
              //var y = e.pageY-$(".tn3a-image").offset().top;
              //var Cnt_h = $(".tn3a-image").height();
              //var Cy = ($(".pan-view").height()-Cnt_h)/Cnt_h;
              var calc = -(($(".pan-view").height()/$(".tn3a-image").height())-1)*(e.pageY-$(".tn3a-image").offset().top)
              if (Math.abs(lastcalc-calc)<=1) return; 
              lastcalc = calc;
              $(".tn3a-full-image").stop(true,true)
                   .animate({ top : calc }, 500, 'linear');
            });
        });

It works as expected but the performances are really bad. It looks really sluggish, although I have a good GPU/CPU. I came up with two solutions - get the calculations made in a single variable (named 'calc'), and use '.stop(true,true)'. Yet I'm still not really satisfied with it. It looks really bad compared to Flash-based solutions.

Any ideas on how to optimize this ?

Thanks for your help.

GunMan
  • 35
  • 4
  • 1
    throttle the mousemove, move the `$(".pan-view")` and other DOM lookups to variables so you are not constantly looking them up. – epascarello Nov 01 '13 at 14:22
  • Could you put this into a fiddle so it's easier to see the effect you're creating, so we can see how to optimise it. – Rory McCrossan Nov 01 '13 at 14:22
  • mousemove is a very CPU intensive event .. check out http://stackoverflow.com/questions/4648444/jquery-fire-mousemove-events-less-often – Jonathan Marzullo Nov 01 '13 at 14:24
  • mousemove event is resource consuming because it fires rapidly when your mouse moves, and in your code every time when it's fired you are adding a new animation in the queue. I'd suggest throttling the event or try something else. there's a plugin for throttling events: http://benalman.com/projects/jquery-throttle-debounce-plugin/ And you may wanna use css transitions instead of jquery animation for smoother animation. – Yurui Zhang Nov 01 '13 at 14:27
  • Thank you guys ! Indeed I throttled the mousemove and although it wasn't spectacular, it helped reducing that sluggish effect. I could not use CSS transitions with the javascript image gallery I'm using, otherwise that's the best thing to do of course. Also moving DOM lookups outside of that loop helped a lot. I needed these variable to be refreshed regularly as the image dimensions change for each image. In the end I came up with a solution like this : - Put DOM lookup after each transition between images - Throttle the mousemove event. Thanks guys :) ! – GunMan Nov 02 '13 at 14:14

1 Answers1

0

Here is a simple way to throttle your handler:

var IsPanning = false;
$(window).load(function(){
            var lastcalc = 0;
            $(".tn3a-image").mousemove(function(e){
              if(IsPanning == false){

                  IsPanning= true;
                  var calc = -(($(".pan-view").height()/$(".tn3a-image").height())-1)*(e.pageY-$(".tn3a-image").offset().top)
                  if (Math.abs(lastcalc-calc)<=1) return; 
                  lastcalc = calc;
                  $(".tn3a-full-image").stop(true,true)
                     .animate({ top : calc }, 500, 'linear');
                  });
                  IsPanning = false;
               }
           });

Sorry, I can't check to see if there are any syntax errors at the moment, hopefully it gives you the idea.

Mister Epic
  • 16,295
  • 13
  • 76
  • 147
  • Thanks for this ! The "IsPanning = false" must be out of the "if" condition in order to be sure the value is reset with each execution of the code. Otherwise the script might get not correctly executed and then completely stuck because of that variable that would never be reset. (That was happening and after 3-4 seconds of use this would happen). Thanks for this answer :) ! – GunMan Nov 02 '13 at 14:12