Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: chrome/browser/resources/pdf/gesture_detector.js

Issue 2400743002: Improved Pinch-Zoom for PDF. (Closed)
Patch Set: Small changes. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 'use strict';
6
7 /**
8 * A class that listens for touch events and produces events when these
9 * touches form gestures (e.g. pinching).
10 */
11 class GestureDetector {
12 /**
13 * Constructs a GestureDetector.
14 * @param {!Element} element The element to monitor for touch gestures.
15 */
16 constructor(element) {
17 this.element_ = element;
18
19 this.element_.addEventListener('touchstart', this.onTouchStart_.bind(this));
20 this.element_.addEventListener('touchmove', this.onTouch_.bind(this));
21 this.element_.addEventListener('touchend', this.onTouch_.bind(this));
22 this.element_.addEventListener('touchcancel', this.onTouch_.bind(this));
23
24 this.pinchStartEvent_ = null;
25 this.lastEvent_ = null;
26
27 this.listeners_ = new Map([
28 ['pinchstart', []],
29 ['pinchupdate', []],
30 ['pinchend', []]
31 ]);
32 }
33
34 /**
35 * Add a |listener| to be notified of |type| events.
36 * @param {string} type The event type to be notified for.
37 * @param {Function} listener The callback.
38 */
39 addEventListener(type, listener) {
40 if (this.listeners_.has(type)) {
41 this.listeners_.get(type).push(listener);
42 }
43 }
44
45 /**
46 * Call the relevant listeners with the given |pinchEvent|.
47 * @private
48 * @param {!Object} pinchEvent The event to notify the listeners of.
49 */
50 notify_(pinchEvent) {
51 let listeners = this.listeners_.get(pinchEvent.type);
52
53 for (let l of listeners)
54 l(pinchEvent);
55 }
56
57 /**
58 * The callback for touchstart events on the element.
59 * @private
60 * @param {!TouchEvent} event Touch event on the element.
61 */
62 onTouchStart_(event) {
63 // We must preventDefault if there is a two finger touch. By doing so
64 // native pinch-zoom does not interfere with our way of handling the event.
65 if (event.touches.length == 2) {
66 event.preventDefault();
67 this.pinchStartEvent_ = event;
68 this.lastEvent_ = event;
69 this.notify_({
70 type: 'pinchstart',
71 center: GestureDetector.center_(event)
72 });
73 }
74 }
75
76 /**
77 * The callback for touch move, end, and cancel events on the element.
78 * @private
79 * @param {!TouchEvent} event Touch event on the element.
80 */
81 onTouch_(event) {
82 if (!this.pinchStartEvent_)
83 return;
84
85 // Check if the pinch ends with the current event.
86 if (event.touches.length < 2 ||
87 this.lastEvent_.touches.length !== event.touches.length) {
88 let startScaleRatio = GestureDetector.pinchScaleRatio_(
89 this.lastEvent_, this.pinchStartEvent_);
90 let center = GestureDetector.center_(this.lastEvent_);
91 let endEvent = {
92 type: 'pinchend',
93 startScaleRatio: startScaleRatio,
94 center: center
95 };
96 this.pinchStartEvent_ = null;
97 this.lastEvent_ = null;
98 this.notify_(endEvent);
99 return;
100 }
101
102 let scaleRatio = GestureDetector.pinchScaleRatio_(event, this.lastEvent_);
103 let startScaleRatio = GestureDetector.pinchScaleRatio_(
104 event, this.pinchStartEvent_);
105 let center = GestureDetector.center_(event);
106 this.notify_({
107 type: 'pinchupdate',
108 scaleRatio: scaleRatio,
109 direction: scaleRatio > 1.0 ? 'in' : 'out',
110 startScaleRatio: startScaleRatio,
111 center: center
112 });
113
114 this.lastEvent_ = event;
115 }
116
117 /**
118 * Computes the change in scale between this touch event
119 * and a previous one.
120 * @private
121 * @param {!TouchEvent} event Latest touch event on the element.
122 * @param {!TouchEvent} prevEvent A previous touch event on the element.
123 * @return {?number} The ratio of the scale of this event and the
124 * scale of the previous one.
125 */
126 static pinchScaleRatio_(event, prevEvent) {
127 let distance1 = GestureDetector.distance_(prevEvent);
128 let distance2 = GestureDetector.distance_(event);
129 return distance1 === 0 ? null : distance2 / distance1;
130 }
131
132 /**
133 * Computes the distance between fingers.
134 * @private
135 * @param {!TouchEvent} event Touch event with at least 2 touch points.
136 * @return {number} Distance between touch[0] and touch[1].
137 */
138 static distance_(event) {
139 let touch1 = event.touches[0];
140 let touch2 = event.touches[1];
141 let dx = touch1.clientX - touch2.clientX;
142 let dy = touch1.clientY - touch2.clientY;
143 return Math.sqrt(dx * dx + dy * dy);
144 }
145
146 /**
147 * Computes the midpoint between fingers.
148 * @private
149 * @param {!TouchEvent} event Touch event with at least 2 touch points.
150 * @return {!Object} Midpoint between touch[0] and touch[1].
151 */
152 static center_(event) {
153 let touch1 = event.touches[0];
154 let touch2 = event.touches[1];
155 return {
156 x: (touch1.clientX + touch2.clientX) / 2,
157 y: (touch1.clientY + touch2.clientY) / 2
158 };
159 }
160 };
OLDNEW
« no previous file with comments | « chrome/browser/resources/component_extension_resources.grd ('k') | chrome/browser/resources/pdf/index.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698