|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- /*
- * TouchController.js
- * Keynote HTML Player
- *
- * Responsibility: Tungwei Cheng
- * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
- */
-
- // iPhone Event Name Constants:
- // -----------------------------
- var kTouchStartEventName = "touchstart";
- var kTouchMoveEventName = "touchmove";
- var kTouchEndEventName = "touchend";
- var kTouchCancelEventName = "touchcancel";
- var kGestureStartEventName = "gesturestart";
- var kGestureEndEventName = "gestureend";
-
- // Class: TouchController
- // ===============================================================
- var kSwipeEvent = "TouchController:SwipeEvent";
- var kTapEvent = "TouchController:TapeEvent";
-
- var TouchController = Class.create({
- initialize: function() {
- // observe touch events
- document.observe(kTouchStartEventName, this.handleTouchStartEvent.bind(this));
- document.observe(kTouchMoveEventName, this.handleTouchMoveEvent.bind(this));
- document.observe(kTouchEndEventName, this.handleTouchEndEvent.bind(this));
- document.observe(kTouchCancelEventName, this.handleTouchCancelEvent.bind(this));
-
- // observe gesture events
- document.observe(kGestureStartEventName, this.handleGestureStartEvent.bind(this));
- document.observe(kGestureEndEventName, this.handleGestureEndEvent.bind(this));
-
- this.swipeInProgress = false;
- this.swipeFingerCount = 0;
-
- this.swipeStartTime = 0;
- this.swipeStartX = 0;
- this.swipeStartY = 0;
-
- this.preventDefault = true;
-
- this.tapEventCallback = null;
-
- this.setTrackArea(0, 0, 0, 0);
-
- this.enableTouchTracking = true;
- },
-
- setTouchTrackingEnabled: function(isEnabled) {
- this.enableTouchTracking = isEnabled;
- },
-
- setTrackArea: function(left, top, width, height) {
- debugMessage(kDebugTouchController_SetTrackArea, "left: " + left + " top: " + top + " width: " + width + " height: " + height);
-
- this.trackAreaLeft = left;
- this.trackAreaTop = top;
- this.trackAreaRight = left + width;
- this.trackAreaBottom = top + height;
- },
-
- registerTapEventCallback: function(tapEventCallback) {
- this.tapEventCallback = tapEventCallback;
- },
-
- isTouchWithinTrackArea: function(touch) {
- debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "checking...");
-
- if (this.enableTouchTracking === false) {
- debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- nope, tracking is disabled");
- return false;
- }
-
- if (touch.clientX < this.trackAreaLeft) {
- debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- nope, x < left");
- return false;
- }
-
- if (touch.clientX > this.trackAreaRight) {
- debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- nope, x > right");
- return false;
- }
-
- if (touch.clientY < this.trackAreaTop) {
- debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- nope, y < top");
- return false;
- }
-
- if (touch.clientY > this.trackAreaBottom) {
- debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- nope, y > bottom");
- return false;
- }
-
- debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- yes it is!");
- return true;
- },
-
- handleTouchStartEvent: function(event) {
- debugMessage(kDebugTouchController_HandleTouchStartEvent, "touch event has " + event.touches.length + " fingers...");
-
- if (this.swipeInProgress === false) {
- debugMessage(kDebugTouchController_HandleTouchStartEvent, "- this is the first finger down event...");
-
- var startTouch = event.touches[0];
-
- if (this.isTouchWithinTrackArea(startTouch)) {
- debugMessage(kDebugTouchController_HandleTouchStartEvent, "- start tracking a swipt event...");
-
- if (this.preventDefault) {
- event.preventDefault();
- }
-
- this.swipeInProgress = true;
- this.swipeFingerCount = event.touches.length;
-
- this.swipeStartTime = new Date();
- this.swipeStartX = startTouch.clientX;
- this.swipeStartY = startTouch.clientY;
-
- } else {
- debugMessage(kDebugTouchController_HandleTouchStartEvent, "- but it is outside of the track area");
- }
- } else {
- debugMessage(kDebugTouchController_HandleTouchStartEvent, "- this is a subsequent finger down event. update finger count...");
- if (event.touches.length > this.swipeFingerCount) {
- this.swipeFingerCount = event.touches.length;
- debugMessage(kDebugTouchController_HandleTouchStartEvent, "- this.swipeFingerCount:" + this.swipeFingerCount);
- }
- }
- },
-
- handleTouchMoveEvent: function(event) {
- if (this.preventDefault) {
- event.preventDefault();
- }
-
- debugMessage(kDebugTouchController_HandleTouchCancelEvent, "");
- },
-
- handleTouchEndEvent: function(event) {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "touch event has " + event.touches.length + " fingers...");
-
- if (this.swipeInProgress) {
- if (this.preventDefault) {
- event.preventDefault();
- }
-
- if (event.touches.length === 0) {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- " + this.swipeFingerCount + " finger swipe is complete.");
-
- var endTouch = event.changedTouches[0];
-
- var viewport = document.viewport.getDimensions();
- var minSwipeDistance = viewport.width / 3.0;
- var maxVerticalMagnitude = viewport.height / 3.0;
- var maxHorizontalMagnitude = viewport.width / 3.0;
-
- var deltaX = endTouch.clientX - this.swipeStartX;
- var deltaY = endTouch.clientY - this.swipeStartY;
-
- var magnitudeX = Math.abs(deltaX);
- var magnitudeY = Math.abs(deltaY);
-
- var touchEndTime = new Date();
-
- var elapsedTime = touchEndTime - this.swipeStartTime;
- var tapIsGood = false;
- var swipeIsGood = false;
-
- // First Check for a "tap"
-
- var kMaxTapTime = 400;
- var kMaxTapMagnitude = 20;
-
- if (elapsedTime < kMaxTapTime) {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- elapsed time was short enough to be a tap, check its magnitude...");
-
- if ((magnitudeX < kMaxTapMagnitude) && (magnitudeY < kMaxTapMagnitude)) {
- tapIsGood = true;
- } else {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- magnitude time too big to be a tap, check if it's a swipe...");
- }
- } else {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- elapsed time too long to be a tap, check if it's a swipe...");
- }
-
- if (elapsedTime > 800) {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- elapsed time too long to be a swipe, ignoring...");
- } else {
- if (magnitudeX > magnitudeY) {
- if (magnitudeY > maxVerticalMagnitude) {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- vertical magnitude too high, ignoring...");
- } else {
- swipeIsGood = true;
- }
- } else {
- if (magnitudeX > maxHorizontalMagnitude) {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- horizontal magnitude too high, ignoring...");
- } else {
- swipeIsGood = true;
- }
- }
- }
-
- if (tapIsGood) {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- it's a " + this.swipeFingerCount + " finger tap");
-
- if (this.tapEventCallback) {
- var tapEvent = {};
-
- tapEvent.memo = {};
- tapEvent.memo.fingers = this.swipeFingerCount;
- tapEvent.memo.pointX = endTouch.clientX;
- tapEvent.memo.pointY = endTouch.clientY;
- tapEvent.memo.target = event.target;
-
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- invoking callback with pointX: " + endTouch.clientX + " pointY: " + endTouch.clientY + "...");
-
- this.tapEventCallback(tapEvent);
-
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- back from callback");
- } else {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- firing TapEvent...");
-
- document.fire(kTapEvent, {
- fingers: this.swipeFingerCount,
- pointX: endTouch.clientX,
- pointY: endTouch.clientY
- });
- }
- } else if (swipeIsGood) {
- var direction;
-
- if (magnitudeX > magnitudeY) {
- direction = (deltaX < 0 ? "left" : "right");
- } else {
- direction = (deltaY < 0 ? "up" : "down");
- }
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- it's a " + this.swipeFingerCount + " finger swipe in the " + direction + " direction");
- document.fire(kSwipeEvent, {
- direction: direction,
- fingers: this.swipeFingerCount,
- swipeStartX: this.swipeStartX
- });
- }
-
- this.swipeInProgress = false;
- this.swipeFingerCount = 0;
- }
- } else {
- debugMessage(kDebugTouchController_HandleTouchEndEvent, "- false alarm. swipe has already ended.");
- }
- },
-
- handleTouchCancelEvent: function(event) {
- debugMessage(kDebugTouchController_HandleTouchCancelEvent, "");
-
- this.swipeInProgress = false;
- },
-
- handleGestureStartEvent: function(event) {
- debugMessage(kDebugTouchController_HandleGestureStartEvent, "");
-
- if (this.preventDefault) {
- event.preventDefault();
- }
- },
-
- handleGestureEndEvent: function(event) {
- debugMessage(kDebugTouchController_HandleGestureEndEvent, "");
-
- if (this.preventDefault) {
- event.preventDefault();
- }
- }
- });
|