Вход Регистрация
Файл: adultscript-2.0.3-pro/files/mobile/templates/default/js/hammer.js
Строк: 1733
<?php
/*! Hammer.JS - v1.0.5 - 2013-04-07
 * http://eightmedia.github.com/hammer.js
 *
 * Copyright (c) 2013 Jorik Tangelder <j.tangelder@gmail.com>;
 * Licensed under the MIT license */

(function(windowundefined) {
    
'use strict';

/**
 * Hammer
 * use this to create instances
 * @param   {HTMLElement}   element
 * @param   {Object}        options
 * @returns {Hammer.Instance}
 * @constructor
 */
var Hammer = function(elementoptions) {
    return new 
Hammer.Instance(elementoptions || {});
};

// default settings
Hammer.defaults = {
    
// add styles and attributes to the element to prevent the browser from doing
    // its native behavior. this doesnt prevent the scrolling, but cancels
    // the contextmenu, tap highlighting etc
    // set to false to disable this
    
stop_browser_behavior: {
        
// this also triggers onselectstart=false for IE
        
userSelect'none',
        
// this makes the element blocking in IE10 >, you could experiment with the value
        // see for more options this issue; https://github.com/EightMedia/hammer.js/issues/241
        
touchAction'none',
        
touchCallout'none',
        
contentZooming'none',
        
userDrag'none',
        
tapHighlightColor'rgba(0,0,0,0)'
    
}

    
// more settings are defined per gesture at gestures.js
};

// detect touchevents
Hammer.HAS_POINTEREVENTS navigator.pointerEnabled || navigator.msPointerEnabled;
Hammer.HAS_TOUCHEVENTS = ('ontouchstart' in window);

// dont use mouseevents on mobile devices
Hammer.MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
Hammer.NO_MOUSEEVENTS Hammer.HAS_TOUCHEVENTS && navigator.userAgent.match(Hammer.MOBILE_REGEX);

// eventtypes per touchevent (start, move, end)
// are filled by Hammer.event.determineEventTypes on setup
Hammer.EVENT_TYPES = {};

// direction defines
Hammer.DIRECTION_DOWN 'down';
Hammer.DIRECTION_LEFT 'left';
Hammer.DIRECTION_UP 'up';
Hammer.DIRECTION_RIGHT 'right';

// pointer type
Hammer.POINTER_MOUSE 'mouse';
Hammer.POINTER_TOUCH 'touch';
Hammer.POINTER_PEN 'pen';

// touch event defines
Hammer.EVENT_START 'start';
Hammer.EVENT_MOVE 'move';
Hammer.EVENT_END 'end';

// hammer document where the base events are added at
Hammer.DOCUMENT document;

// plugins namespace
Hammer.plugins = {};

// if the window events are set...
Hammer.READY false;

/**
 * setup events to detect gestures on the document
 */
function setup() {
    if(
Hammer.READY) {
        return;
    }

    
// find what eventtypes we add listeners to
    
Hammer.event.determineEventTypes();

    
// Register all gestures inside Hammer.gestures
    
for(var name in Hammer.gestures) {
        if(
Hammer.gestures.hasOwnProperty(name)) {
            
Hammer.detection.register(Hammer.gestures[name]);
        }
    }

    
// Add touch events on the document
    
Hammer.event.onTouch(Hammer.DOCUMENTHammer.EVENT_MOVEHammer.detection.detect);
    
Hammer.event.onTouch(Hammer.DOCUMENTHammer.EVENT_ENDHammer.detection.detect);

    
// Hammer is ready...!
    
Hammer.READY true;
}

/**
 * create new hammer instance
 * all methods should return the instance itself, so it is chainable.
 * @param   {HTMLElement}       element
 * @param   {Object}            [options={}]
 * @returns {Hammer.Instance}
 * @constructor
 */
Hammer.Instance = function(elementoptions) {
    var 
self this;

    
// setup HammerJS window events and register all gestures
    // this also sets up the default options
    
setup();

    
this.element element;

    
// start/stop detection option
    
this.enabled true;

    
// merge options
    
this.options Hammer.utils.extend(
        
Hammer.utils.extend({}, Hammer.defaults),
        
options || {});

    
// add some css to the element to prevent the browser from doing its native behavoir
    
if(this.options.stop_browser_behavior) {
        
Hammer.utils.stopDefaultBrowserBehavior(this.elementthis.options.stop_browser_behavior);
    }

    
// start detection on touchstart
    
Hammer.event.onTouch(elementHammer.EVENT_START, function(ev) {
        if(
self.enabled) {
            
Hammer.detection.startDetect(selfev);
        }
    });

    
// return instance
    
return this;
};


Hammer.Instance.prototype = {
    
/**
     * bind events to the instance
     * @param   {String}      gesture
     * @param   {Function}    handler
     * @returns {Hammer.Instance}
     */
    
on: function onEvent(gesturehandler){
        var 
gestures gesture.split(' ');
        for(var 
t=0t<gestures.lengtht++) {
            
this.element.addEventListener(gestures[t], handlerfalse);
        }
        return 
this;
    },


    
/**
     * unbind events to the instance
     * @param   {String}      gesture
     * @param   {Function}    handler
     * @returns {Hammer.Instance}
     */
    
off: function offEvent(gesturehandler){
        var 
gestures gesture.split(' ');
        for(var 
t=0t<gestures.lengtht++) {
            
this.element.removeEventListener(gestures[t], handlerfalse);
        }
        return 
this;
    },


    
/**
     * trigger gesture event
     * @param   {String}      gesture
     * @param   {Object}      eventData
     * @returns {Hammer.Instance}
     */
    
trigger: function triggerEvent(gestureeventData){
        
// create DOM event
        
var event Hammer.DOCUMENT.createEvent('Event');
        
event.initEvent(gesturetruetrue);
        
event.gesture eventData;

        
// trigger on the target if it is in the instance element,
        // this is for event delegation tricks
        
var element this.element;
        if(
Hammer.utils.hasParent(eventData.targetelement)) {
            
element eventData.target;
        }

        
element.dispatchEvent(event);
        return 
this;
    },


    
/**
     * enable of disable hammer.js detection
     * @param   {Boolean}   state
     * @returns {Hammer.Instance}
     */
    
enable: function enable(state) {
        
this.enabled state;
        return 
this;
    }
};

/**
 * this holds the last move event,
 * used to fix empty touchend issue
 * see the onTouch event for an explanation
 * @type {Object}
 */
var last_move_event null;


/**
 * when the mouse is hold down, this is true
 * @type {Boolean}
 */
var enable_detect false;


/**
 * when touch events have been fired, this is true
 * @type {Boolean}
 */
var touch_triggered false;


Hammer.event = {
    
/**
     * simple addEventListener
     * @param   {HTMLElement}   element
     * @param   {String}        type
     * @param   {Function}      handler
     */
    
bindDom: function(elementtypehandler) {
        var 
types type.split(' ');
        for(var 
t=0t<types.lengtht++) {
            
element.addEventListener(types[t], handlerfalse);
        }
    },


    
/**
     * touch events with mouse fallback
     * @param   {HTMLElement}   element
     * @param   {String}        eventType        like Hammer.EVENT_MOVE
     * @param   {Function}      handler
     */
    
onTouch: function onTouch(elementeventTypehandler) {
        var 
self this;

        
this.bindDom(elementHammer.EVENT_TYPES[eventType], function bindDomOnTouch(ev) {
            var 
sourceEventType ev.type.toLowerCase();

            
// onmouseup, but when touchend has been fired we do nothing.
            // this is for touchdevices which also fire a mouseup on touchend
            
if(sourceEventType.match(/mouse/) && touch_triggered) {
                return;
            }

            
// mousebutton must be down or a touch event
            
else if( sourceEventType.match(/touch/) ||   // touch events are always on screen
                
sourceEventType.match(/pointerdown/) || // pointerevents touch
                
(sourceEventType.match(/mouse/) && ev.which === 1)   // mouse is pressed
            
){
                
enable_detect true;
            }

            
// we are in a touch event, set the touch triggered bool to true,
            // this for the conflicts that may occur on ios and android
            
if(sourceEventType.match(/touch|pointer/)) {
                
touch_triggered true;
            }

            
// count the total touches on the screen
            
var count_touches 0;

            
// when touch has been triggered in this detection session
            // and we are now handling a mouse event, we stop that to prevent conflicts
            
if(enable_detect) {
                
// update pointerevent
                
if(Hammer.HAS_POINTEREVENTS && eventType != Hammer.EVENT_END) {
                    
count_touches Hammer.PointerEvent.updatePointer(eventTypeev);
                }
                
// touch
                
else if(sourceEventType.match(/touch/)) {
                    
count_touches ev.touches.length;
                }
                
// mouse
                
else if(!touch_triggered) {
                    
count_touches sourceEventType.match(/up/) ? 1;
                }

                
// if we are in a end event, but when we remove one touch and
                // we still have enough, set eventType to move
                
if(count_touches && eventType == Hammer.EVENT_END) {
                    
eventType Hammer.EVENT_MOVE;
                }
                
// no touches, force the end event
                
else if(!count_touches) {
                    
eventType Hammer.EVENT_END;
                }

                
// because touchend has no touches, and we often want to use these in our gestures,
                // we send the last move event as our eventData in touchend
                
if(!count_touches && last_move_event !== null) {
                    
ev last_move_event;
                }
                
// store the last move event
                
else {
                    
last_move_event ev;
                }

                
// trigger the handler
                
handler.call(Hammer.detectionself.collectEventData(elementeventTypeev));

                
// remove pointerevent from list
                
if(Hammer.HAS_POINTEREVENTS && eventType == Hammer.EVENT_END) {
                    
count_touches Hammer.PointerEvent.updatePointer(eventTypeev);
                }
            }

            
//debug(sourceEventType +" "+ eventType);

            // on the end we reset everything
            
if(!count_touches) {
                
last_move_event null;
                
enable_detect false;
                
touch_triggered false;
                
Hammer.PointerEvent.reset();
            }
        });
    },


    
/**
     * we have different events for each device/browser
     * determine what we need and set them in the Hammer.EVENT_TYPES constant
     */
    
determineEventTypes: function determineEventTypes() {
        
// determine the eventtype we want to set
        
var types;

        
// pointerEvents magic
        
if(Hammer.HAS_POINTEREVENTS) {
            
types Hammer.PointerEvent.getEvents();
        }
        
// on Android, iOS, blackberry, windows mobile we dont want any mouseevents
        
else if(Hammer.NO_MOUSEEVENTS) {
            
types = [
                
'touchstart',
                
'touchmove',
                
'touchend touchcancel'];
        }
        
// for non pointer events browsers and mixed browsers,
        // like chrome on windows8 touch laptop
        
else {
            
types = [
                
'touchstart mousedown',
                
'touchmove mousemove',
                
'touchend touchcancel mouseup'];
        }

        
Hammer.EVENT_TYPES[Hammer.EVENT_START]  = types[0];
        
Hammer.EVENT_TYPES[Hammer.EVENT_MOVE]   = types[1];
        
Hammer.EVENT_TYPES[Hammer.EVENT_END]    = types[2];
    },


    
/**
     * create touchlist depending on the event
     * @param   {Object}    ev
     * @param   {String}    eventType   used by the fakemultitouch plugin
     */
    
getTouchList: function getTouchList(ev/*, eventType*/) {
        
// get the fake pointerEvent touchlist
        
if(Hammer.HAS_POINTEREVENTS) {
            return 
Hammer.PointerEvent.getTouchList();
        }
        
// get the touchlist
        
else if(ev.touches) {
            return 
ev.touches;
        }
        
// make fake touchlist from mouse position
        
else {
            return [{
                
identifier1,
                
pageXev.pageX,
                
pageYev.pageY,
                
targetev.target
            
}];
        }
    },


    
/**
     * collect event data for Hammer js
     * @param   {HTMLElement}   element
     * @param   {String}        eventType        like Hammer.EVENT_MOVE
     * @param   {Object}        eventData
     */
    
collectEventData: function collectEventData(elementeventTypeev) {
        var 
touches this.getTouchList(eveventType);

        
// find out pointerType
        
var pointerType Hammer.POINTER_TOUCH;
        if(
ev.type.match(/mouse/) || Hammer.PointerEvent.matchType(Hammer.POINTER_MOUSEev)) {
            
pointerType Hammer.POINTER_MOUSE;
        }

        return {
            
center      Hammer.utils.getCenter(touches),
            
timeStamp   : new Date().getTime(),
            
target      ev.target,
            
touches     touches,
            
eventType   eventType,
            
pointerType pointerType,
            
srcEvent    ev,

            
/**
             * prevent the browser default actions
             * mostly used to disable scrolling of the browser
             */
            
preventDefault: function() {
                if(
this.srcEvent.preventManipulation) {
                    
this.srcEvent.preventManipulation();
                }

                if(
this.srcEvent.preventDefault) {
                    
this.srcEvent.preventDefault();
                }
            },

            
/**
             * stop bubbling the event up to its parents
             */
            
stopPropagation: function() {
                
this.srcEvent.stopPropagation();
            },

            
/**
             * immediately stop gesture detection
             * might be useful after a swipe was detected
             * @return {*}
             */
            
stopDetect: function() {
                return 
Hammer.detection.stopDetect();
            }
        };
    }
};

Hammer.PointerEvent = {
    
/**
     * holds all pointers
     * @type {Object}
     */
    
pointers: {},

    
/**
     * get a list of pointers
     * @returns {Array}     touchlist
     */
    
getTouchList: function() {
        var 
self this;
        var 
touchlist = [];

        
// we can use forEach since pointerEvents only is in IE10
        
Object.keys(self.pointers).sort().forEach(function(id) {
            
touchlist.push(self.pointers[id]);
        });
        return 
touchlist;
    },

    
/**
     * update the position of a pointer
     * @param   {String}   type             Hammer.EVENT_END
     * @param   {Object}   pointerEvent
     */
    
updatePointer: function(typepointerEvent) {
        if(
type == Hammer.EVENT_END) {
            
this.pointers = {};
        }
        else {
            
pointerEvent.identifier pointerEvent.pointerId;
            
this.pointers[pointerEvent.pointerId] = pointerEvent;
        }

        return 
Object.keys(this.pointers).length;
    },

    
/**
     * check if ev matches pointertype
     * @param   {String}        pointerType     Hammer.POINTER_MOUSE
     * @param   {PointerEvent}  ev
     */
    
matchType: function(pointerTypeev) {
        if(!
ev.pointerType) {
            return 
false;
        }

        var 
types = {};
        
types[Hammer.POINTER_MOUSE] = (ev.pointerType == ev.MSPOINTER_TYPE_MOUSE || ev.pointerType == Hammer.POINTER_MOUSE);
        
types[Hammer.POINTER_TOUCH] = (ev.pointerType == ev.MSPOINTER_TYPE_TOUCH || ev.pointerType == Hammer.POINTER_TOUCH);
        
types[Hammer.POINTER_PEN] = (ev.pointerType == ev.MSPOINTER_TYPE_PEN || ev.pointerType == Hammer.POINTER_PEN);
        return 
types[pointerType];
    },


    
/**
     * get events
     */
    
getEvents: function() {
        return [
            
'pointerdown MSPointerDown',
            
'pointermove MSPointerMove',
            
'pointerup pointercancel MSPointerUp MSPointerCancel'
        
];
    },

    
/**
     * reset the list
     */
    
reset: function() {
        
this.pointers = {};
    }
};


Hammer.utils = {
    
/**
     * extend method,
     * also used for cloning when dest is an empty object
     * @param   {Object}    dest
     * @param   {Object}    src
     * @parm    {Boolean}    merge        do a merge
     * @returns {Object}    dest
     */
    
extend: function extend(destsrcmerge) {
        for (var 
key in src) {
            if(
dest[key] !== undefined && merge) {
                continue;
            }
            
dest[key] = src[key];
        }
        return 
dest;
    },


    
/**
     * find if a node is in the given parent
     * used for event delegation tricks
     * @param   {HTMLElement}   node
     * @param   {HTMLElement}   parent
     * @returns {boolean}       has_parent
     */
    
hasParent: function(nodeparent) {
        while(
node){
            if(
node == parent) {
                return 
true;
            }
            
node node.parentNode;
        }
        return 
false;
    },


    
/**
     * get the center of all the touches
     * @param   {Array}     touches
     * @returns {Object}    center
     */
    
getCenter: function getCenter(touches) {
        var 
valuesX = [], valuesY = [];

        for(var 
t0,len=touches.lengtht<lent++) {
            
valuesX.push(touches[t].pageX);
            
valuesY.push(touches[t].pageY);
        }

        return {
            
pageX: ((Math.min.apply(MathvaluesX) + Math.max.apply(MathvaluesX)) / 2),
            
pageY: ((Math.min.apply(MathvaluesY) + Math.max.apply(MathvaluesY)) / 2)
        };
    },


    
/**
     * calculate the velocity between two points
     * @param   {Number}    delta_time
     * @param   {Number}    delta_x
     * @param   {Number}    delta_y
     * @returns {Object}    velocity
     */
    
getVelocity: function getVelocity(delta_timedelta_xdelta_y) {
        return {
            
xMath.abs(delta_x delta_time) || 0,
            
yMath.abs(delta_y delta_time) || 0
        
};
    },


    
/**
     * calculate the angle between two coordinates
     * @param   {Touch}     touch1
     * @param   {Touch}     touch2
     * @returns {Number}    angle
     */
    
getAngle: function getAngle(touch1touch2) {
        var 
touch2.pageY touch1.pageY,
            
touch2.pageX touch1.pageX;
        return 
Math.atan2(yx) * 180 Math.PI;
    },


    
/**
     * angle to direction define
     * @param   {Touch}     touch1
     * @param   {Touch}     touch2
     * @returns {String}    direction constant, like Hammer.DIRECTION_LEFT
     */
    
getDirection: function getDirection(touch1touch2) {
        var 
Math.abs(touch1.pageX touch2.pageX),
            
Math.abs(touch1.pageY touch2.pageY);

        if(
>= y) {
            return 
touch1.pageX touch2.pageX Hammer.DIRECTION_LEFT Hammer.DIRECTION_RIGHT;
        }
        else {
            return 
touch1.pageY touch2.pageY Hammer.DIRECTION_UP Hammer.DIRECTION_DOWN;
        }
    },


    
/**
     * calculate the distance between two touches
     * @param   {Touch}     touch1
     * @param   {Touch}     touch2
     * @returns {Number}    distance
     */
    
getDistance: function getDistance(touch1touch2) {
        var 
touch2.pageX touch1.pageX,
            
touch2.pageY touch1.pageY;
        return 
Math.sqrt((x*x) + (y*y));
    },


    
/**
     * calculate the scale factor between two touchLists (fingers)
     * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
     * @param   {Array}     start
     * @param   {Array}     end
     * @returns {Number}    scale
     */
    
getScale: function getScale(startend) {
        
// need two fingers...
        
if(start.length >= && end.length >= 2) {
            return 
this.getDistance(end[0], end[1]) /
                
this.getDistance(start[0], start[1]);
        }
        return 
1;
    },


    
/**
     * calculate the rotation degrees between two touchLists (fingers)
     * @param   {Array}     start
     * @param   {Array}     end
     * @returns {Number}    rotation
     */
    
getRotation: function getRotation(startend) {
        
// need two fingers
        
if(start.length >= && end.length >= 2) {
            return 
this.getAngle(end[1], end[0]) -
                
this.getAngle(start[1], start[0]);
        }
        return 
0;
    },


    
/**
     * boolean if the direction is vertical
     * @param    {String}    direction
     * @returns  {Boolean}   is_vertical
     */
    
isVertical: function isVertical(direction) {
        return (
direction == Hammer.DIRECTION_UP || direction == Hammer.DIRECTION_DOWN);
    },


    
/**
     * stop browser default behavior with css props
     * @param   {HtmlElement}   element
     * @param   {Object}        css_props
     */
    
stopDefaultBrowserBehavior: function stopDefaultBrowserBehavior(elementcss_props) {
        var 
prop,
            
vendors = ['webkit','khtml','moz','ms','o',''];

        if(!
css_props || !element.style) {
            return;
        }

        
// with css properties for modern browsers
        
for(var 0vendors.lengthi++) {
            for(var 
p in css_props) {
                if(
css_props.hasOwnProperty(p)) {
                    
prop p;

                    
// vender prefix at the property
                    
if(vendors[i]) {
                        
prop vendors[i] + prop.substring(01).toUpperCase() + prop.substring(1);
                    }

                    
// set the style
                    
element.style[prop] = css_props[p];
                }
            }
        }

        
// also the disable onselectstart
        
if(css_props.userSelect == 'none') {
            
element.onselectstart = function() {
                return 
false;
            };
        }
    }
};

Hammer.detection = {
    
// contains all registred Hammer.gestures in the correct order
    
gestures: [],

    
// data of the current Hammer.gesture detection session
    
currentnull,

    
// the previous Hammer.gesture session data
    // is a full clone of the previous gesture.current object
    
previousnull,

    
// when this becomes true, no gestures are fired
    
stoppedfalse,


    
/**
     * start Hammer.gesture detection
     * @param   {Hammer.Instance}   inst
     * @param   {Object}            eventData
     */
    
startDetect: function startDetect(insteventData) {
        
// already busy with a Hammer.gesture detection on an element
        
if(this.current) {
            return;
        }

        
this.stopped false;

        
this.current = {
            
inst        inst// reference to HammerInstance we're working for
            
startEvent  Hammer.utils.extend({}, eventData), // start eventData for distances, timing etc
            
lastEvent   false// last eventData
            
name        '' // current gesture we're in/detected, can be 'tap', 'hold' etc
        
};

        
this.detect(eventData);
    },


    
/**
     * Hammer.gesture detection
     * @param   {Object}    eventData
     * @param   {Object}    eventData
     */
    
detect: function detect(eventData) {
        if(!
this.current || this.stopped) {
            return;
        }

        
// extend event data with calculations about scale, distance etc
        
eventData this.extendEventData(eventData);

        
// instance options
        
var inst_options this.current.inst.options;

        
// call Hammer.gesture handlers
        
for(var g=0,len=this.gestures.lengthg<leng++) {
            var 
gesture this.gestures[g];

            
// only when the instance options have enabled this gesture
            
if(!this.stopped && inst_options[gesture.name] !== false) {
                
// if a handler returns false, we stop with the detection
                
if(gesture.handler.call(gestureeventDatathis.current.inst) === false) {
                    
this.stopDetect();
                    break;
                }
            }
        }

        
// store as previous event event
        
if(this.current) {
            
this.current.lastEvent eventData;
        }

        
// endevent, but not the last touch, so dont stop
        
if(eventData.eventType == Hammer.EVENT_END && !eventData.touches.length-1) {
            
this.stopDetect();
        }

        return 
eventData;
    },


    
/**
     * clear the Hammer.gesture vars
     * this is called on endDetect, but can also be used when a final Hammer.gesture has been detected
     * to stop other Hammer.gestures from being fired
     */
    
stopDetect: function stopDetect() {
        
// clone current data to the store as the previous gesture
        // used for the double tap gesture, since this is an other gesture detect session
        
this.previous Hammer.utils.extend({}, this.current);

        
// reset the current
        
this.current null;

        
// stopped!
        
this.stopped true;
    },


    
/**
     * extend eventData for Hammer.gestures
     * @param   {Object}   ev
     * @returns {Object}   ev
     */
    
extendEventData: function extendEventData(ev) {
        var 
startEv this.current.startEvent;

        
// if the touches change, set the new touches over the startEvent touches
        // this because touchevents don't have all the touches on touchstart, or the
        // user must place his fingers at the EXACT same time on the screen, which is not realistic
        // but, sometimes it happens that both fingers are touching at the EXACT same time
        
if(startEv && (ev.touches.length != startEv.touches.length || ev.touches === startEv.touches)) {
            
// extend 1 level deep to get the touchlist with the touch objects
            
startEv.touches = [];
            for(var 
i=0,len=ev.touches.lengthi<leni++) {
                
startEv.touches.push(Hammer.utils.extend({}, ev.touches[i]));
            }
        }

        var 
delta_time ev.timeStamp startEv.timeStamp,
            
delta_x ev.center.pageX startEv.center.pageX,
            
delta_y ev.center.pageY startEv.center.pageY,
            
velocity Hammer.utils.getVelocity(delta_timedelta_xdelta_y);

        
Hammer.utils.extend(ev, {
            
deltaTime   delta_time,

            
deltaX      delta_x,
            
deltaY      delta_y,

            
velocityX   velocity.x,
            
velocityY   velocity.y,

            
distance    Hammer.utils.getDistance(startEv.centerev.center),
            
angle       Hammer.utils.getAngle(startEv.centerev.center),
            
direction   Hammer.utils.getDirection(startEv.centerev.center),

            
scale       Hammer.utils.getScale(startEv.touchesev.touches),
            
rotation    Hammer.utils.getRotation(startEv.touchesev.touches),

            
startEvent  startEv
        
});

        return 
ev;
    },


    
/**
     * register new gesture
     * @param   {Object}    gesture object, see gestures.js for documentation
     * @returns {Array}     gestures
     */
    
register: function register(gesture) {
        
// add an enable gesture options if there is no given
        
var options gesture.defaults || {};
        if(
options[gesture.name] === undefined) {
            
options[gesture.name] = true;
        }

        
// extend Hammer default options with the Hammer.gesture options
        
Hammer.utils.extend(Hammer.defaultsoptionstrue);

        
// set its index
        
gesture.index gesture.index || 1000;

        
// add Hammer.gesture to the list
        
this.gestures.push(gesture);

        
// sort the list by index
        
this.gestures.sort(function(ab) {
            if (
a.index b.index) {
                return -
1;
            }
            if (
a.index b.index) {
                return 
1;
            }
            return 
0;
        });

        return 
this.gestures;
    }
};


Hammer.gestures Hammer.gestures || {};

/**
 * Custom gestures
 * ==============================
 *
 * Gesture object
 * --------------------
 * The object structure of a gesture:
 *
 * { name: 'mygesture',
 *   index: 1337,
 *   defaults: {
 *     mygesture_option: true
 *   }
 *   handler: function(type, ev, inst) {
 *     // trigger gesture event
 *     inst.trigger(this.name, ev);
 *   }
 * }

 * @param   {String}    name
 * this should be the name of the gesture, lowercase
 * it is also being used to disable/enable the gesture per instance config.
 *
 * @param   {Number}    [index=1000]
 * the index of the gesture, where it is going to be in the stack of gestures detection
 * like when you build an gesture that depends on the drag gesture, it is a good
 * idea to place it after the index of the drag gesture.
 *
 * @param   {Object}    [defaults={}]
 * the default settings of the gesture. these are added to the instance settings,
 * and can be overruled per instance. you can also add the name of the gesture,
 * but this is also added by default (and set to true).
 *
 * @param   {Function}  handler
 * this handles the gesture detection of your custom gesture and receives the
 * following arguments:
 *
 *      @param  {Object}    eventData
 *      event data containing the following properties:
 *          timeStamp   {Number}        time the event occurred
 *          target      {HTMLElement}   target element
 *          touches     {Array}         touches (fingers, pointers, mouse) on the screen
 *          pointerType {String}        kind of pointer that was used. matches Hammer.POINTER_MOUSE|TOUCH
 *          center      {Object}        center position of the touches. contains pageX and pageY
 *          deltaTime   {Number}        the total time of the touches in the screen
 *          deltaX      {Number}        the delta on x axis we haved moved
 *          deltaY      {Number}        the delta on y axis we haved moved
 *          velocityX   {Number}        the velocity on the x
 *          velocityY   {Number}        the velocity on y
 *          angle       {Number}        the angle we are moving
 *          direction   {String}        the direction we are moving. matches Hammer.DIRECTION_UP|DOWN|LEFT|RIGHT
 *          distance    {Number}        the distance we haved moved
 *          scale       {Number}        scaling of the touches, needs 2 touches
 *          rotation    {Number}        rotation of the touches, needs 2 touches *
 *          eventType   {String}        matches Hammer.EVENT_START|MOVE|END
 *          srcEvent    {Object}        the source event, like TouchStart or MouseDown *
 *          startEvent  {Object}        contains the same properties as above,
 *                                      but from the first touch. this is used to calculate
 *                                      distances, deltaTime, scaling etc
 *
 *      @param  {Hammer.Instance}    inst
 *      the instance we are doing the detection for. you can get the options from
 *      the inst.options object and trigger the gesture event by calling inst.trigger
 *
 *
 * Handle gestures
 * --------------------
 * inside the handler you can get/set Hammer.detection.current. This is the current
 * detection session. It has the following properties
 *      @param  {String}    name
 *      contains the name of the gesture we have detected. it has not a real function,
 *      only to check in other gestures if something is detected.
 *      like in the drag gesture we set it to 'drag' and in the swipe gesture we can
 *      check if the current gesture is 'drag' by accessing Hammer.detection.current.name
 *
 *      @readonly
 *      @param  {Hammer.Instance}    inst
 *      the instance we do the detection for
 *
 *      @readonly
 *      @param  {Object}    startEvent
 *      contains the properties of the first gesture detection in this session.
 *      Used for calculations about timing, distance, etc.
 *
 *      @readonly
 *      @param  {Object}    lastEvent
 *      contains all the properties of the last gesture detect in this session.
 *
 * after the gesture detection session has been completed (user has released the screen)
 * the Hammer.detection.current object is copied into Hammer.detection.previous,
 * this is usefull for gestures like doubletap, where you need to know if the
 * previous gesture was a tap
 *
 * options that have been set by the instance can be received by calling inst.options
 *
 * You can trigger a gesture event by calling inst.trigger("mygesture", event).
 * The first param is the name of your gesture, the second the event argument
 *
 *
 * Register gestures
 * --------------------
 * When an gesture is added to the Hammer.gestures object, it is auto registered
 * at the setup of the first Hammer instance. You can also call Hammer.detection.register
 * manually and pass your gesture object as a param
 *
 */

/**
 * Hold
 * Touch stays at the same place for x time
 * @events  hold
 */
Hammer.gestures.Hold = {
    
name'hold',
    
index10,
    
defaults: {
        
hold_timeout    500,
        
hold_threshold    1
    
},
    
timernull,
    
handler: function holdGesture(evinst) {
        switch(
ev.eventType) {
            case 
Hammer.EVENT_START:
                
// clear any running timers
                
clearTimeout(this.timer);

                
// set the gesture so we can check in the timeout if it still is
                
Hammer.detection.current.name this.name;

                
// set timer and if after the timeout it still is hold,
                // we trigger the hold event
                
this.timer setTimeout(function() {
                    if(
Hammer.detection.current.name == 'hold') {
                        
inst.trigger('hold'ev);
                    }
                }, 
inst.options.hold_timeout);
                break;

            
// when you move or end we clear the timer
            
case Hammer.EVENT_MOVE:
                if(
ev.distance inst.options.hold_threshold) {
                    
clearTimeout(this.timer);
                }
                break;

            case 
Hammer.EVENT_END:
                
clearTimeout(this.timer);
                break;
        }
    }
};


/**
 * Tap/DoubleTap
 * Quick touch at a place or double at the same place
 * @events  tap, doubletap
 */
Hammer.gestures.Tap = {
    
name'tap',
    
index100,
    
defaults: {
        
tap_max_touchtime    250,
        
tap_max_distance    10,
        
tap_always            true,
        
doubletap_distance    20,
        
doubletap_interval    300
    
},
    
handler: function tapGesture(evinst) {
        if(
ev.eventType == Hammer.EVENT_END) {
            
// previous gesture, for the double tap since these are two different gesture detections
            
var prev Hammer.detection.previous,
                
did_doubletap false;

            
// when the touchtime is higher then the max touch time
            // or when the moving distance is too much
            
if(ev.deltaTime inst.options.tap_max_touchtime ||
                
ev.distance inst.options.tap_max_distance) {
                return;
            }

            
// check if double tap
            
if(prev && prev.name == 'tap' &&
                (
ev.timeStamp prev.lastEvent.timeStamp) < inst.options.doubletap_interval &&
                
ev.distance inst.options.doubletap_distance) {
                
inst.trigger('doubletap'ev);
                
did_doubletap true;
            }

            
// do a single tap
            
if(!did_doubletap || inst.options.tap_always) {
                
Hammer.detection.current.name 'tap';
                
inst.trigger(Hammer.detection.current.nameev);
            }
        }
    }
};


/**
 * Swipe
 * triggers swipe events when the end velocity is above the threshold
 * @events  swipe, swipeleft, swiperight, swipeup, swipedown
 */
Hammer.gestures.Swipe = {
    
name'swipe',
    
index40,
    
defaults: {
        
// set 0 for unlimited, but this can conflict with transform
        
swipe_max_touches  1,
        
swipe_velocity     0.7
    
},
    
handler: function swipeGesture(evinst) {
        if(
ev.eventType == Hammer.EVENT_END) {
            
// max touches
            
if(inst.options.swipe_max_touches &&
                
ev.touches.length inst.options.swipe_max_touches) {
                return;
            }

            
// when the distance we moved is too small we skip this gesture
            // or we can be already in dragging
            
if(ev.velocityX inst.options.swipe_velocity ||
                
ev.velocityY inst.options.swipe_velocity) {
                
// trigger swipe events
                
inst.trigger(this.nameev);
                
inst.trigger(this.name ev.directionev);
            }
        }
    }
};


/**
 * Drag
 * Move with x fingers (default 1) around on the page. Blocking the scrolling when
 * moving left and right is a good practice. When all the drag events are blocking
 * you disable scrolling on that area.
 * @events  drag, drapleft, dragright, dragup, dragdown
 */
Hammer.gestures.Drag = {
    
name'drag',
    
index50,
    
defaults: {
        
drag_min_distance 10,
        
// set 0 for unlimited, but this can conflict with transform
        
drag_max_touches  1,
        
// prevent default browser behavior when dragging occurs
        // be careful with it, it makes the element a blocking element
        // when you are using the drag gesture, it is a good practice to set this true
        
drag_block_horizontal   false,
        
drag_block_vertical     false,
        
// drag_lock_to_axis keeps the drag gesture on the axis that it started on,
        // It disallows vertical directions if the initial direction was horizontal, and vice versa.
        
drag_lock_to_axis       false,
        
// drag lock only kicks in when distance > drag_lock_min_distance
        // This way, locking occurs only when the distance has become large enough to reliably determine the direction
        
drag_lock_min_distance 25
    
},
    
triggeredfalse,
    
handler: function dragGesture(evinst) {
        
// current gesture isnt drag, but dragged is true
        // this means an other gesture is busy. now call dragend
        
if(Hammer.detection.current.name != this.name && this.triggered) {
            
inst.trigger(this.name +'end'ev);
            
this.triggered false;
            return;
        }

        
// max touches
        
if(inst.options.drag_max_touches &&
            
ev.touches.length inst.options.drag_max_touches) {
            return;
        }

        switch(
ev.eventType) {
            case 
Hammer.EVENT_START:
                
this.triggered false;
                break;

            case 
Hammer.EVENT_MOVE:
                
// when the distance we moved is too small we skip this gesture
                // or we can be already in dragging
                
if(ev.distance inst.options.drag_min_distance &&
                    
Hammer.detection.current.name != this.name) {
                    return;
                }

                
// we are dragging!
                
Hammer.detection.current.name this.name;

                
// lock drag to axis?
                
if(Hammer.detection.current.lastEvent.drag_locked_to_axis || (inst.options.drag_lock_to_axis && inst.options.drag_lock_min_distance<=ev.distance)) {
                    
ev.drag_locked_to_axis true;
                }
                var 
last_direction Hammer.detection.current.lastEvent.direction;
                if(
ev.drag_locked_to_axis && last_direction !== ev.direction) {
                    
// keep direction on the axis that the drag gesture started on
                    
if(Hammer.utils.isVertical(last_direction)) {
                        
ev.direction = (ev.deltaY 0) ? Hammer.DIRECTION_UP Hammer.DIRECTION_DOWN;
                    }
                    else {
                        
ev.direction = (ev.deltaX 0) ? Hammer.DIRECTION_LEFT Hammer.DIRECTION_RIGHT;
                    }
                }

                
// first time, trigger dragstart event
                
if(!this.triggered) {
                    
inst.trigger(this.name +'start'ev);
                    
this.triggered true;
                }

                
// trigger normal event
                
inst.trigger(this.nameev);

                
// direction event, like dragdown
                
inst.trigger(this.name ev.directionev);

                
// block the browser events
                
if( (inst.options.drag_block_vertical && Hammer.utils.isVertical(ev.direction)) ||
                    (
inst.options.drag_block_horizontal && !Hammer.utils.isVertical(ev.direction))) {
                    
ev.preventDefault();
                }
                break;

            case 
Hammer.EVENT_END:
                
// trigger dragend
                
if(this.triggered) {
                    
inst.trigger(this.name +'end'ev);
                }

                
this.triggered false;
                break;
        }
    }
};


/**
 * Transform
 * User want to scale or rotate with 2 fingers
 * @events  transform, pinch, pinchin, pinchout, rotate
 */
Hammer.gestures.Transform = {
    
name'transform',
    
index45,
    
defaults: {
        
// factor, no scale is 1, zoomin is to 0 and zoomout until higher then 1
        
transform_min_scale     0.01,
        
// rotation in degrees
        
transform_min_rotation  1,
        
// prevent default browser behavior when two touches are on the screen
        // but it makes the element a blocking element
        // when you are using the transform gesture, it is a good practice to set this true
        
transform_always_block  false
    
},
    
triggeredfalse,
    
handler: function transformGesture(evinst) {
        
// current gesture isnt drag, but dragged is true
        // this means an other gesture is busy. now call dragend
        
if(Hammer.detection.current.name != this.name && this.triggered) {
            
inst.trigger(this.name +'end'ev);
            
this.triggered false;
            return;
        }

        
// atleast multitouch
        
if(ev.touches.length 2) {
            return;
        }

        
// prevent default when two fingers are on the screen
        
if(inst.options.transform_always_block) {
            
ev.preventDefault();
        }

        switch(
ev.eventType) {
            case 
Hammer.EVENT_START:
                
this.triggered false;
                break;

            case 
Hammer.EVENT_MOVE:
                var 
scale_threshold Math.abs(1-ev.scale);
                var 
rotation_threshold Math.abs(ev.rotation);

                
// when the distance we moved is too small we skip this gesture
                // or we can be already in dragging
                
if(scale_threshold inst.options.transform_min_scale &&
                    
rotation_threshold inst.options.transform_min_rotation) {
                    return;
                }

                
// we are transforming!
                
Hammer.detection.current.name this.name;

                
// first time, trigger dragstart event
                
if(!this.triggered) {
                    
inst.trigger(this.name +'start'ev);
                    
this.triggered true;
                }

                
inst.trigger(this.nameev); // basic transform event

                // trigger rotate event
                
if(rotation_threshold inst.options.transform_min_rotation) {
                    
inst.trigger('rotate'ev);
                }

                
// trigger pinch event
                
if(scale_threshold inst.options.transform_min_scale) {
                    
inst.trigger('pinch'ev);
                    
inst.trigger('pinch'+ ((ev.scale 1) ? 'in' 'out'), ev);
                }
                break;

            case 
Hammer.EVENT_END:
                
// trigger dragend
                
if(this.triggered) {
                    
inst.trigger(this.name +'end'ev);
                }

                
this.triggered false;
                break;
        }
    }
};


/**
 * Touch
 * Called as first, tells the user has touched the screen
 * @events  touch
 */
Hammer.gestures.Touch = {
    
name'touch',
    
index: -Infinity,
    
defaults: {
        
// call preventDefault at touchstart, and makes the element blocking by
        // disabling the scrolling of the page, but it improves gestures like
        // transforming and dragging.
        // be careful with using this, it can be very annoying for users to be stuck
        // on the page
        
prevent_defaultfalse,

        
// disable mouse events, so only touch (or pen!) input triggers events
        
prevent_mouseeventsfalse
    
},
    
handler: function touchGesture(evinst) {
        if(
inst.options.prevent_mouseevents && ev.pointerType == Hammer.POINTER_MOUSE) {
            
ev.stopDetect();
            return;
        }

        if(
inst.options.prevent_default) {
            
ev.preventDefault();
        }

        if(
ev.eventType ==  Hammer.EVENT_START) {
            
inst.trigger(this.nameev);
        }
    }
};


/**
 * Release
 * Called as last, tells the user has released the screen
 * @events  release
 */
Hammer.gestures.Release = {
    
name'release',
    
indexInfinity,
    
handler: function releaseGesture(evinst) {
        if(
ev.eventType ==  Hammer.EVENT_END) {
            
inst.trigger(this.nameev);
        }
    }
};

// node export
if(typeof module === 'object' && typeof module.exports === 'object'){
    
module.exports Hammer;
}
// just window export
else {
    
window.Hammer Hammer;

    
// requireJS module definition
    
if(typeof window.define === 'function' && window.define.amd) {
        
window.define('hammer', [], function() {
            return 
Hammer;
        });
    }
}
})(
this);
?>
Онлайн: 1
Реклама