0

I am trying to implement a panning effect on an image, by following this tutorial. However, it's not working and I think it may be due to the way the javascript is being referenced. The image that I would like to receive the panning effect stays static and does not pan like the demo.

This is what I have tried so far:

I have the following javascript (entirely copied from the mentioned tutorial, except for a modification in class name) in: moesia-child-01/scripts/pan.js

<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

<!-- JS -->
<script>
  (function($){

    $(document).ready(function(){
      //call imagePanning fn when DOM is ready
      $(".pan img").imagePanning();
    });

    //imagePanning fn
    $.fn.imagePanning=function(){
      var init="center",
        speed=800, //animation/tween speed
        //custom js tween
        _tweenTo=function(el,prop,to,duration,easing,overwrite){
          if(!el._mTween){el._mTween={top:{},left:{}};}
          var startTime=_getTime(),_delay,progress=0,from=el.offsetTop,elStyle=el.style,_request,tobj=el._mTween[prop];
          if(prop==="left"){from=el.offsetLeft;}
          var diff=to-from;
          if(overwrite!=="none"){_cancelTween();}
          _startTween();
          function _step(){
            progress=_getTime()-startTime;
            _tween();
            if(progress>=tobj.time){
              tobj.time=(progress>tobj.time) ? progress+_delay-(progress-tobj.time) : progress+_delay-1;
              if(tobj.time<progress+1){tobj.time=progress+1;}
            }
            if(tobj.time<duration){tobj.id=_request(_step);}
          }
          function _tween(){
            if(duration>0){
              tobj.currVal=_ease(tobj.time,from,diff,duration,easing);
              elStyle[prop]=Math.round(tobj.currVal)+"px";
            }else{
              elStyle[prop]=to+"px";
            }
          }
          function _startTween(){
            _delay=1000/60;
            tobj.time=progress+_delay;
            _request=(!window.requestAnimationFrame) ? function(f){_tween(); return setTimeout(f,0.01);} : window.requestAnimationFrame;
            tobj.id=_request(_step);
          }
          function _cancelTween(){
            if(tobj.id==null){return;}
            if(!window.requestAnimationFrame){clearTimeout(tobj.id);
            }else{window.cancelAnimationFrame(tobj.id);}
            tobj.id=null;
          }
          function _ease(t,b,c,d,type){
            var ts=(t/=d)*t,tc=ts*t;
            return b+c*(0.499999999999997*tc*ts + -2.5*ts*ts + 5.5*tc + -6.5*ts + 4*t);
          }
          function _getTime(){
            if(window.performance && window.performance.now){
              return window.performance.now();
            }else{
              if(window.performance && window.performance.webkitNow){
                return window.performance.webkitNow();
              }else{
                if(Date.now){return Date.now();}else{return new Date().getTime();}
              }
            }
          }
        };
      return this.each(function(){
        var $this=$(this),timer,dest;
        if($this.data("imagePanning")) return;
        $this.data("imagePanning",1)
          //create markup
          .wrap("<div class='img-pan-container' />")
          .after("<div class='resize' style='position:absolute; width:auto; height:auto; top:0; right:0; bottom:0; left:0; margin:0; padding:0; overflow:hidden; visibility:hidden; z-index:-1'><iframe style='width:100%; height:0; border:0; visibility:visible; margin:0' /><iframe style='width:0; height:100%; border:0; visibility:visible; margin:0' /></div>")
          //image loaded fn
          .one("load",function(){
            setTimeout(function(){ $this.addClass("loaded").trigger("mousemove",1); },1);
          }).each(function(){ //run load fn even if cached
            if(this.complete) $(this).load();
          })
          //panning fn
          .parent().on("mousemove touchmove MSPointerMove pointermove",function(e,p){
            var cont=$(this);
            e.preventDefault();
            var contH=cont.height(),contW=cont.width(),
              isTouch=e.type.indexOf("touch")!==-1,isPointer=e.type.indexOf("pointer")!==-1,
              evt=isPointer ? e.originalEvent : isTouch ? e.originalEvent.touches[0] || e.originalEvent.changedTouches[0] : e,
              coords=[
                !p ? evt.pageY-cont.offset().top : init==="center" ? contH/2 : 0,
                !p ? evt.pageX-cont.offset().left : init==="center" ? contW/2 : 0
              ];
            dest=[Math.round(($this.outerHeight(true)-contH)*(coords[0]/contH)),Math.round(($this.outerWidth(true)-contW)*(coords[1]/contW))];
          })
          //resize fn
          .find(".resize iframe").each(function(){
            $(this.contentWindow || this).on("resize",function(){
              $this.trigger("mousemove",1);
            });
          });
        //panning animation 60FPS
        if(timer) clearInterval(timer);
        timer=setInterval(function(){
          _tweenTo($this[0],"top",-dest[0],speed);
          _tweenTo($this[0],"left",-dest[1],speed);
        },16.6);
      });
    }

  })(jQuery);
</script>

In functions.php, I have added these functions to register the script for a theme and enqueue the script:

function my_js_scripts()
{
    // Register the script like this for a theme:
    wp_register_script( 'pan-script', get_template_directory_uri() . '/scripts/pan.js' );

    // For either a plugin or a theme, you can then enqueue the script:
    wp_enqueue_script( 'pan-script' );
}
add_action( 'wp_enqueue_scripts', 'my_js_scripts' );

In my theme header.php, I added this line just before wp_head():

<?php wp_enqueue_script("jquery"); ?>

And this line just after wp_head():

<script type="text/javascript" src="/scripts/pan.js"></script>

UPDATE

I have added the jquery parameter to my script registry, but it still does not work.

function my_js_scripts()
    {
        // Register the script like this for a theme:
        wp_register_script( 'pan-script', get_template_directory_uri() . '/scripts/pan.js', ['jquery'] );

        // For either a plugin or a theme, you can then enqueue the script:
        wp_enqueue_script( 'pan-script' );
    }
    add_action( 'wp_enqueue_scripts', 'my_js_scripts' );

UPDATE 2

I have these Chrome developer console errors:

GET http://localhost:8888/mysite/wp-content/themes/moesia/scripts/pan.js?ver=4.4.2  ?page_id=15:143
GET http://localhost:8888/scripts/pan.js  ?page_id=15:193

I figured out from these 404 errors on the pan.js file, that it was looking in the parent theme folder (moesia) instead of the child theme folder (moesia-child-01) for the javascript file.

I would prefer to be able to keep my scripts in the child theme folder--how to do this?

To test this out, however, I have now copied the scripts folder to the parent theme folder (there is now a copy in moesia/scripts/pan.js).

I now see that I have a syntax error on pan.js, but cannot see where it is coming from:

pan.js?ver=4.4.2:2 Uncaught SyntaxError: Unexpected token <
7
  • Do you get any error messages from the developer console?
    – david_nash
    Commented Feb 16, 2016 at 23:49
  • @david_nash Yes, and this may be my problem but I still don't see why. See updates.
    – user25976
    Commented Feb 16, 2016 at 23:58
  • Are you getting 404s for those files? The first GET has two ?s which won't work, the second seems to be missing the path - and I think ['jquery'] should be array('jquery')
    – david_nash
    Commented Feb 17, 2016 at 0:05
  • @david_nash How can I know if I am getting 404s for those files? There isn't a 404 error next to the GET, if that is what you mean.
    – user25976
    Commented Feb 17, 2016 at 0:06
  • 1
    I've seen the Uncaught SyntaxError: Unexpected token < error when someone included <script> at the beginning of a .js file. Yeah, really.
    – BillK
    Commented Feb 17, 2016 at 2:41

1 Answer 1

0

I had to overcome two issues to resolve this.

The 404 error was due to the way I registered the script. It pointed to the parent theme folder, while I had saved the .js file to the child theme folder. For the moment, I've put a copy in the parent theme folder, and am looking for the proper way to get it registered to the child theme.

Once the browser was able to find the .js file, I got the syntax error mentioned above because I included at the beginning of the .js file. After removing all the tags and keeping only javascript code, and referencing wordpress' jquery, the code works like a charm.

Not the answer you're looking for? Browse other questions tagged or ask your own question.