jQuery Multi-TouchWipe / Multi-TouchZoom

jQuery Multi-TouchWipe / Multi-TouchZoom是小弟参照WipeTouch扩展出来的针对多点触屏划动而改写出来的Jquery插件,可以为dom上的两手指触屏划动拨入(zoomin)或者拨开(zoomout)操作而绑定自己的事件。

// jQuery multitouchzoom 1.0.0
// ------------------------------------------------------------------------
//
// Developed and maintained by Nelson
// Inspired by and referenced from Igor Ramadas's WipeTouch.

//
// USAGE
// ------------------------------------------------------------------------
//
// $(selector).multitouchzoom(config);
//
// The multitouchzoom events should expect 2 fingers(a finger and b finger) touch on the screen at the same time;
//
//
// EXAMPLE
//        $(document).multitouchzoom({
//            zoomIn: function(result) { alert("zoomIn "); },
//            zoomOut: function(result) { alert("zoomOut "); }
//        });
//
//
// More details at https://github.com/nelsonkuang/MultiTouchZoom
//
//
// The minified version of WipeTouch can be generated using Jasc: http://

(function ($) {
    $.fn.multitouchzoom = function (settings) {
        // ------------------------------------------------------------------------
        // PLUGIN SETTINGS
        // ------------------------------------------------------------------------

        var config = {

            // Variables and options
            moveX: 40,     // minimum amount of horizontal pixels to trigger a wipe event
            moveY: 40,     // minimum amount of vertical pixels to trigger a wipe event
            preventDefault: true, // if true, prevents default events (click for example)

            // Multi Touch Zoom events
            zoomIn: false, // called on zoom in gesture
            zoomOut: false, // called on zoom out gesture
            multiTouchMove: false, // triggered whenever touchMove acts

        };

        if (settings) {
            $.extend(config, settings);
        }

        this.each(function () {
            // ------------------------------------------------------------------------
            // INTERNAL VARIABLES
            // ------------------------------------------------------------------------
            var startDate = false;             // used to calculate timing and aprox. acceleration
            var touchedElement = false;     // element which user has touched
            var clickEvent = false;         // holds the click event of the target, when used hasn't clicked

            var aStartX;                     // where finger "a" touch has started, left
            var aStartY;                     // where finger "a" touch has started, top
            var aCurX;                         // keeps finger "a" touch X position while moving on the screen
            var aCurY;                         // keeps finger "a" touch Y position while moving on the screen
            var aIsMoving = false;             // is user's finger "a" touching and moving?

            var bStartX;                     // where finger "b" touch has started, left
            var bStartY;                     // where finger "b" touch has started, top
            var bCurX;                         // keeps finger "b" touch X position while moving on the screen
            var bCurY;                         // keeps finger "b" touch Y position while moving on the screen
            var bIsMoving = false;             // is user's finger "b" touching and moving?


            // ------------------------------------------------------------------------
            // Multi Touch Eevents
            // ------------------------------------------------------------------------

            // Called when user multi-touches the screen.
            function onMultiTouchStart(e) {
                var aStart = e.originalEvent.touches[0] && e.originalEvent.touches.length > 1;
                var bStart = e.originalEvent.touches[1];
                if (!aIsMoving && !bIsMoving && aStart && bStart) {
                    if (config.preventDefault) {
                        e.preventDefault();
                    }

                    aStartX = e.originalEvent.touches[0].pageX;
                    aStartY = e.originalEvent.touches[0].pageY;
                    bStartX = e.originalEvent.touches[1].pageX;
                    bStartY = e.originalEvent.touches[1].pageY;

                    $(this).bind("touchmove", onMultiTouchMove);

                    // Set the start date and current X/Y for finger "a" & finger "b".
                    startDate = new Date().getTime();
                    aCurX = aStartX;
                    aCurY = aStartY;
                    bCurX = bStartX;
                    bCurY = bStartY;
                    aIsMoving = true;
                    bIsMoving = true;

                    touchedElement = $(e.target);
                }
            }

            // Called when user untouches the screen.
            function onTouchEnd(e) {
                if (config.preventDefault) {
                    e.preventDefault();
                }

                // When touch events are not present, use mouse events.
                $(this).unbind("touchmove", onMultiTouchMove);


                // If is moving then calculate the touch results, otherwise reset it.
                if (aIsMoving || bIsMoving) {
                    touchCalculate(e);
                }
                else {
                    resetTouch();
                }
            }

            // Called when user is touching and moving on the screen.
            function onMultiTouchMove(e) {
                if (config.preventDefault) {
                    e.preventDefault();
                }

                if (aIsMoving || bIsMoving) {
                    aCurX = e.originalEvent.touches[0].pageX;
                    aCurY = e.originalEvent.touches[0].pageY;
                    bCurX = e.originalEvent.touches[1].pageX;
                    bCurY = e.originalEvent.touches[1].pageY;
                    // If there's a MultiTouchMove event, call it passing
                    // current X and Y position (curX and curY).
                    if (config.multiTouchMove) {
                        triggerEvent(config.multiTouchMove, {
                            aCurX: aCurX,
                            aCurY: aCurY,
                            bCurX: bCurX,
                            bCurY: bCurY
                        });
                    }
                }
            }

            // ------------------------------------------------------------------------
            // CALCULATE TOUCH AND TRIGGER
            // ------------------------------------------------------------------------

            function touchCalculate(e) {
                var endDate = new Date().getTime();     // current date to calculate timing
                var ms = startDate - endDate;             // duration of touch in milliseconds

                var ax = aCurX;                             // current left position of finger 'a'
                var ay = aCurY;                             // current top position of finger 'a'
                var bx = bCurX;                             // current left position of finger 'b'
                var by = bCurY;                             // current top position of finger 'b'
                var dax = ax - aStartX;                     // diff of current left to starting left of finger 'a'
                var day = ay - aStartY;                     // diff of current top to starting top of finger 'a'
                var dbx = bx - bStartX;                     // diff of current left to starting left of finger 'b'
                var dby = by - bStartY;                     // diff of current top to starting top of finger 'b'
                var aax = Math.abs(dax);                     // amount of horizontal movement of finger 'a'
                var aay = Math.abs(day);                     // amount of vertical movement of finger 'a'
                var abx = Math.abs(dbx);                     // amount of horizontal movement of finger 'b'
                var aby = Math.abs(dby);                     // amount of vertical movement of finger 'b'

                //diff of current distance to starting distance between the 2 points
                var diff = Math.sqrt((aStartX - bStartX) * (aStartX - bStartX) + (aStartY - bStartY) * (aStartY - bStartY)) - Math.sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by));
                
                // If moved less than 15 pixels, touch duration is less than 100ms,
                // then trigger a click event and stop processing.
                if (aax < 15 && aay < 15 && abx < 15 && aby < 15 && ms < 100) {
                    clickEvent = false;

                    if (config.preventDefault) {
                        resetTouch();

                        touchedElement.trigger("click");
                        return;
                    }
                }

                // Is it zooming in or out?
                var isZoomIn = diff > 0;
                var isZoomOut = diff < 0;

                // Calculate speed from 1 to 5, 1 being slower and 5 faster.
                var as = ((aax + aay) * 60) / ((ms) / 6 * (ms));
                var bs = ((abx + aby) * 60) / ((ms) / 6 * (ms));

                if (as < 1) as = 1;
                if (as > 5) as = 5;

                if (bs < 1) bs = 1;
                if (bs > 5) bs = 5;

                var result = {
                    aSpeed: parseInt(as),
                    bSpeed: parseInt(bs),
                    aX: aax,
                    aY: aay,
                    bX: abx,
                    bY: aby,
                    source: touchedElement
                };

                if (aax >= config.moveX || abx >= config.moveX||aay>= config.moveY||aby>=config.moveY) {
                    // If it is zooming in, trigger zoomIn events.
                    if (isZoomIn) {
                        triggerEvent(config.zoomIn, result);
                    }
                        // Otherwise trigger zoomOut events.
                    else if (isZoomOut) {
                        triggerEvent(config.zoomOut, result);
                    }
                }
                resetTouch();
            }

            // Resets the cached variables.
            function resetTouch() {
                aStartX = false;
                aStartY = false;
                bStartX = false;
                bStartY = false;
                startDate = false;
                aIsMoving = false;
                bIsMoving = false;

                // If there's a click event, bind after a few miliseconds.
                if (clickEvent) {
                    window.setTimeout(function () {
                        touchedElement.bind("click", clickEvent);
                        clickEvent = false;
                    }, 50);
                }
            }

            // Trigger a event passing a result object with
            // aSpeed & bSpeed from 1 to 5, aX / aY & bX / bY movement amount in pixels,
            // and the source element.
            function triggerEvent(zoomEvent, result) {
                if (zoomEvent) {
                    zoomEvent(result);
                }
            }

            // ------------------------------------------------------------------------
            // ADD MULTITOUCHSTART AND TOUCHEND EVENT LISTENERS
            // ------------------------------------------------------------------------

            if ("ontouchstart" in document.documentElement) {

                $(this).bind("touchstart", onMultiTouchStart);
                $(this).bind("touchend", onTouchEnd);
            }
        });

        return this;
    };
})(jQuery);
原文地址:https://www.cnblogs.com/fastmover/p/3955423.html