UNPKG

hammerjs

Version:

A javascript library for multi-touch gestures

255 lines (224 loc) 6.64 kB
var Utils = 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(dest, src, merge) { for(var key in src) { if(dest[key] !== undefined && merge) { continue; } dest[key] = src[key]; } return dest; }, /** * for each * @param obj * @param iterator */ each: function each(obj, iterator, context) { var i, o; // native forEach on arrays if ('forEach' in obj) { obj.forEach(iterator, context); } // arrays else if(obj.length !== undefined) { for(i=-1; (o=obj[++i]);) { if (iterator.call(context, o, i, obj) === false) { return; } } } // objects else { for(i in obj) { if(obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj) === false) { return; } } } }, /** * find if a string contains the needle * @param {String} src * @param {String} needle * @returns {Boolean} found */ inStr: function inStr(src, needle) { return src.indexOf(needle) > -1; }, /** * 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 hasParent(node, parent) { 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 pageXY clientXY */ getCenter: function getCenter(touches) { var pageX = [] , pageY = [] , clientX = [] , clientY = [] , min = Math.min , max = Math.max; // no need to loop when only one touch if(touches.length === 1) { return { pageX: touches[0].pageX, pageY: touches[0].pageY, clientX: touches[0].clientX, clientY: touches[0].clientY }; } Utils.each(touches, function(touch) { pageX.push(touch.pageX); pageY.push(touch.pageY); clientX.push(touch.clientX); clientY.push(touch.clientY); }); return { pageX: (min.apply(Math, pageX) + max.apply(Math, pageX)) / 2, pageY: (min.apply(Math, pageY) + max.apply(Math, pageY)) / 2, clientX: (min.apply(Math, clientX) + max.apply(Math, clientX)) / 2, clientY: (min.apply(Math, clientY) + max.apply(Math, clientY)) / 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_time, delta_x, delta_y) { return { x: Math.abs(delta_x / delta_time) || 0, y: Math.abs(delta_y / delta_time) || 0 }; }, /** * calculate the angle between two coordinates * @param {Touch} touch1 * @param {Touch} touch2 * @returns {Number} angle */ getAngle: function getAngle(touch1, touch2) { var x = touch2.clientX - touch1.clientX , y = touch2.clientY - touch1.clientY; return Math.atan2(y, x) * 180 / Math.PI; }, /** * angle to direction define * @param {Touch} touch1 * @param {Touch} touch2 * @returns {String} direction constant, like DIRECTION_LEFT */ getDirection: function getDirection(touch1, touch2) { var x = Math.abs(touch1.clientX - touch2.clientX) , y = Math.abs(touch1.clientY - touch2.clientY); if(x >= y) { return touch1.clientX - touch2.clientX > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; } return touch1.clientY - touch2.clientY > 0 ? DIRECTION_UP : DIRECTION_DOWN; }, /** * calculate the distance between two touches * @param {Touch} touch1 * @param {Touch} touch2 * @returns {Number} distance */ getDistance: function getDistance(touch1, touch2) { var x = touch2.clientX - touch1.clientX , y = touch2.clientY - touch1.clientY; 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(start, end) { // need two fingers... if(start.length >= 2 && 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(start, end) { // need two fingers if(start.length >= 2 && 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 == DIRECTION_UP || direction == DIRECTION_DOWN; }, /** * toggle browser default behavior with css props * @param {HtmlElement} element * @param {Object} css_props * @param {Boolean} toggle */ toggleDefaultBehavior: function toggleDefaultBehavior(element, css_props, toggle) { if(!css_props || !element || !element.style) { return; } // with css properties for modern browsers Utils.each(['webkit', 'moz', 'Moz', 'ms', 'o', ''], function setStyle(vendor) { Utils.each(css_props, function(value, prop) { // vender prefix at the property if(vendor) { prop = vendor + prop.substring(0, 1).toUpperCase() + prop.substring(1); } // set the style if(prop in element.style) { element.style[prop] = !toggle && value; } }); }); var false_fn = function(){ return false; }; // also the disable onselectstart if(css_props.userSelect == 'none') { element.onselectstart = !toggle && false_fn; } // and disable ondragstart if(css_props.userDrag == 'none') { element.ondragstart = !toggle && false_fn; } } };