最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Get pan direction on panend hammer.js and restrict directions - Stack Overflow

programmeradmin1浏览0评论

I am using a hammer.js library with its jQuery plugin. I started using it as suggested by documentation, so something like this to initiate it on .game-card-mobile divs

/* Create Hammer object for swipable game cards */
var $gameCard = $('.game-card-mobile');
var $gameCardTouch = $gameCard.hammer();

$gameCardTouch.on("panright press panleft", function(ev) {
    console.log(ev.type);
}); 

This allows me to restrict available actions to pan/swipe element to the right, left and press on it, however during one event, lets say panright I would get many entries printed out in console although only one pan was performed. So I then changed initiation to this:

$gameCardTouch.on("panend", function(ev) {
    console.log(ev.type);
});

Now it listens to panend action which occur at the end of the action, thus is only returning one printout in console, however it is always panend now, thus I lost restriction to only 3 previous actions and am unable to detect what specific action was performed.

Is there a way to bine these so I would get a print out of panright if users swiped right, panleft if swiped left and press, all just one time once they finish that action?

I am using a hammer.js library with its jQuery plugin. I started using it as suggested by documentation, so something like this to initiate it on .game-card-mobile divs

/* Create Hammer object for swipable game cards */
var $gameCard = $('.game-card-mobile');
var $gameCardTouch = $gameCard.hammer();

$gameCardTouch.on("panright press panleft", function(ev) {
    console.log(ev.type);
}); 

This allows me to restrict available actions to pan/swipe element to the right, left and press on it, however during one event, lets say panright I would get many entries printed out in console although only one pan was performed. So I then changed initiation to this:

$gameCardTouch.on("panend", function(ev) {
    console.log(ev.type);
});

Now it listens to panend action which occur at the end of the action, thus is only returning one printout in console, however it is always panend now, thus I lost restriction to only 3 previous actions and am unable to detect what specific action was performed.

Is there a way to bine these so I would get a print out of panright if users swiped right, panleft if swiped left and press, all just one time once they finish that action?

Share Improve this question edited Apr 1, 2015 at 3:31 torox 4901 gold badge3 silver badges11 bronze badges asked Mar 29, 2015 at 19:33 IljaIlja 46.5k103 gold badges289 silver badges527 bronze badges 2
  • 1 Any reason you can't just check ev.direction on panend? See "Event Object": hammerjs.github.io/api/#event-object – Jack Commented Mar 31, 2015 at 23:05
  • @Jack I get 'undefined printed out' in console, What is such check supposed to return? ideally I would want a string like 'panright' returned. – Ilja Commented Apr 3, 2015 at 9:58
Add a ment  | 

4 Answers 4

Reset to default 6 +50

Just using a bination of the panright,press, and panleft with the panend could work for you.

(function(){
    var direction;
    var $gameCard = $('.game-card-mobile');
    var $gameCardTouch = $gameCard.hammer();

    $gameCardTouch.on("panright press panleft", function(ev) {
        //Set the direction in here
        direction = ev.type;
    }); 

    $gameCardTouch.on("panend", function(ev) {
        //Use the direction in here
        //You know the pan has ended
        //and you know which action they were taking

        console.log(direction);

        //So do what ever here
        if(direction === "whatever") ...
    }); 


}());

To expand a bit on what Jack was getting at. Perhaps a simpler solution...

ev.eventObject returns integer values https://hammerjs.github.io/api/#event-object

In the case of ev.direction:

  • no movement = 0
  • left = 2
  • right = 4
  • up = 8
  • down = 16
  • horizontal = 6
  • vertical = 24
  • all = 30

Clean

var mc = new Hammer(body);

mc.on("panend", function(ev) {

  if (ev.direction == INT) {
    //do something
  }

});

Verbosely

var mc = new Hammer(body);

mc.on("panend", function(ev) {

  //console.log(ev.direction);

  //for left case
  if (ev.direction == 2) {
    //do something
  }

  //for right case
  if (ev.direction == 4) {
    //do something
  }
});

I'm on my phone, so this is just pseudo code, but can't you do something like this:

var eventHandlers =  {
    panright: function(){},
    press: function(){},
    panleft:function(){}
}

 $gameCardTouch.on("panright press panleft", function(ev) {
      if(ev.type === 'panright') {
         eventHandlers.panright();
      } else if((ev.type === 'panleft'){
         eventHandlers.panright();
      } else {
       eventHandlers.press();
      }

This example from the website is similar: http://codepen.io/jtangelder/pen/ABFnd

Was working on a similar problem using Backbone, jQuery, and Hammer. Here's how I solved it (only posting relevant bits). Hopefully someone finds this useful.

var Slideshow = Backbone.View.extend( {

    events: {
        "pan .slideshow-slide" : "handlePan",
        "panstart .slideshow-slide" : "handlePanStart",
        "panend .slideshow-slide" : "handlePanEnd",
    },

    state: {
        panHistory: [],
    },

    handlePanStart: function( evt ) {
        // attempt to get the pan x coord
        var startX = this.getPanXFromEvent( evt );

        // if an x coord couldn't be retrieved, get out
        if ( !startX ) {
            this.logger.warn( "Pan Start: Unable to find x", evt );
            return;
        }

        this.logger.log( "Pan Start", evt );

        // set the pan x array so this is its first and only element
        this.state.panHistory = [ startX ];
    },

    handlePan: function( evt ) {
        // cache the pan history
        var pans = this.state.panHistory,
        // get the x coord from this pan event
        lastX = this.getPanXFromEvent( evt );

        // track deltas on the x axis during the pan, so we know if the user
        // is switching directions between pan start and pan end
        if ( lastX ) {
            pans.push( lastX );
        }
    },

    handlePanEnd: function( evt ) {
        // get the direction of the pan
        switch ( this.getDirectionFromPanEvent( evt ) ) {
            case Hammer.DIRECTION_LEFT:
                // if we panned left and the next slide isn't out of
                // range, go to the next slide.. otherwise fall back
                // on the switch statement's default
                if ( !this.isOutOfRange( this.state.current + 1 ) ) {
                    this.logger.log( "Pan End: Moving Left", evt );
                    this.gotoNextSlide();
                    return;
                }

            case Hammer.DIRECTION_RIGHT:
                // if we panned right and the previous slide isn't out
                // of range, go to the previous slide.. otherwise fall
                // back on the switch statement's default
                if ( !this.isOutOfRange( this.state.current - 1 ) ) {
                    this.logger.log( "Pan End: Moving Right", evt );
                    this.gotoPrevSlide();
                    return;
                }

            // Snap back to the current slide by default by calling
            // gotoSlide on the current index to reset the transform
            default:
                this.logger.log( "Pan End: Snapping Back", evt );
                this.gotoSlide( this.state.current );
        }
    },

    getPanXFromEvent: function( evt ) {
        return Utils.getValue( "originalEvent.gesture.center.x", evt );
    },

    getDirectionFromPanHistory: function( evt ) {
        // placeholders for start, end, and last pan x coords
        var i, start, last, end,
        // cache the pan x array so we don't have to type it 50 times
        pans = this.state.panHistory;

        // if there aren't enough pans to calculate a delta, return 0
        if ( pans.length < 2 ) {
            return 0;
        }

        // get the starting pan x
        start = pans[ 0 ];
        // set last and end to the last pan x
        last = end = pans[ pans.length - 1 ];

        // loop backwards through the pans to find a pan x coord different from the ending one
        // since there's a chance that identical pan x coords will be stacked in the array
        for ( i = pans.length - 2; last === end && i >= 0; i-- ) {
            last = pans[ i ];
        }

        // if the last pan was to the right, and we're farther right
        // than we started, move right
        return end > last && end > start ? Hammer.DIRECTION_RIGHT
            // if the last pan was to the left, and we're farther left
            // than we started, move left
            : end < last && end < start ? Hammer.DIRECTION_LEFT
            // otherwise move nowhere
            : 0;
    },
} );
发布评论

评论列表(0)

  1. 暂无评论