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

Side by Side Diff: components/dom_distiller/core/javascript/dom_distiller_viewer.js

Issue 1009703002: Changing font size with pinch gesture in Reader Mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months 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
« no previous file with comments | « components/dom_distiller/core/css/distilledpage.css ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 function addToPage(html) { 5 function addToPage(html) {
6 var div = document.createElement('div'); 6 var div = document.createElement('div');
7 div.innerHTML = html; 7 div.innerHTML = html;
8 document.getElementById('content').appendChild(div); 8 document.getElementById('content').appendChild(div);
9 } 9 }
10 10
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 }(); 67 }();
68 68
69 // Add a listener to the "View Original" link to report opt-outs. 69 // Add a listener to the "View Original" link to report opt-outs.
70 document.getElementById('showOriginal').addEventListener('click', function(e) { 70 document.getElementById('showOriginal').addEventListener('click', function(e) {
71 var img = document.createElement('img'); 71 var img = document.createElement('img');
72 img.src = "/vieworiginal"; 72 img.src = "/vieworiginal";
73 img.style.display = "none"; 73 img.style.display = "none";
74 document.body.appendChild(img); 74 document.body.appendChild(img);
75 }, true); 75 }, true);
76 76
77 window.addEventListener('load', function() {
78 // When users pinch in Reader Mode, the page would zoom in or out as if it
79 // is a normal web page allowing user-zoom. At the end of pinch gesture, the
80 // page would do text reflow. These pinch-to-zoom and text reflow effects
81 // are not native, but are emulated using CSS and JavaScript.
82 //
83 // In order to achieve near-native zooming and panning frame rate, fake 3D
84 // transform is used so that the layer doesn't repaint for each frame.
85 //
86 // After the text reflow, the web content shown in viewport should roughly be
87 // the same paragraph before zooming.
88 //
89 // The control point of font size is the html element, so that both "em" and
90 // "rem" are adjusted.
91 //
92 // TODO(wychen): Improve scroll position when elementFromPoint is body.
93
94 var pinching = false;
95 var pinchDistAnchor = 0;
96 var fontSizeAnchor = 1.0;
97 var focusElement = null;
98 var focusPos = 0;
99 var pinchOrigin = {x: 0, y: 0};
100 var scaleFactor = 1;
101 var lastClientMidY = 0;
102
103 // The zooming speed relative to pinching speed.
104 // @const
105 var FONT_SCALE_MULTIPLIER = 0.3;
106
107 // The font size is guaranteed to be in px.
108 var baseSize =
109 parseFloat(getComputedStyle(document.documentElement).fontSize);
110
111 var handleTouchStart = function(e) {
112 if (e.touches.length < 2) return;
113 e.preventDefault();
114 if (e.touches.length != 2) return;
jdduke (slow) 2015/03/16 20:27:52 How much more complicated is supporting >2 touches
wychen 2015/03/17 17:36:11 Good suggestion! I've never used more than two fin
115
116 pinchDistAnchor = touchDist(e);
117 pinching = pinchDistAnchor > 0;
118 fontSizeAnchor =
119 parseFloat(getComputedStyle(document.documentElement).fontSize)
120 / baseSize;
121
122 pinchOrigin = touchPageMid(e);
123 var clientMid = touchClientMid(e);
124 var pinchMidY = clientMid.y;
125 // Try to preserve the pinching center after text reflow.
126 // This is accurate to the HTML element level.
127 focusElement = document.elementFromPoint(clientMid.x, clientMid.y);
128 var rect = focusElement.getBoundingClientRect();
129 focusPos = (pinchMidY - rect.top) / (rect.bottom - rect.top);
130
131 lastClientMidY = clientMid.y;
132 };
133
134 var handleTouchMove = function(e) {
135 if (!pinching) return;
136 e.preventDefault();
137
138 var pinchScale = touchDist(e) / pinchDistAnchor;
139 var fontScale = 1 + ((pinchScale - 1) * FONT_SCALE_MULTIPLIER);
jdduke (slow) 2015/03/16 20:27:52 We might want to be more careful about the min fon
wychen 2015/03/17 17:36:11 0.4 might be in the unreadable range, and 0.4~2.5
140 scaleFactor = Math.max(0.4, Math.min(2.5, fontSizeAnchor * fontScale));
141 var mid = touchPageMid(e);
142
143 document.body.style.transformOrigin =
144 pinchOrigin.x + 'px ' + pinchOrigin.y + 'px';
145 // Use "fake" 3D transform so that the layer is not repainted.
146 // With 2D transform, the frame rate would be much lower.
jdduke (slow) 2015/03/16 20:27:53 I can't speak to this logic.
wychen 2015/03/17 17:36:12 The frame rate was enhanced from <30fps to 60fps t
147 document.body.style.transform =
148 'translate3d(' + (mid.x - pinchOrigin.x) + 'px,' +
149 (mid.y - pinchOrigin.y) + 'px, 0px)' +
150 'scale(' + scaleFactor/fontSizeAnchor + ')';
151
152 lastClientMidY = touchClientMid(e).y;
153 };
154
155 var handleTouchEnd = function(e) {
156 if (!pinching) return;
jdduke (slow) 2015/03/16 20:27:53 We'll need to be careful here as well, as we proba
wychen 2015/03/17 17:36:11 Indeed.
157 e.preventDefault();
158 pinching = false;
159
160 document.body.style.transformOrigin = '';
161 document.body.style.transform = '';
162 document.documentElement.style.fontSize = scaleFactor * baseSize + "px";
jdduke (slow) 2015/03/16 20:27:52 I'm an HTML newb so we'll want somebody else to re
wychen 2015/03/17 17:36:11 Why would this line in particular concern you? Th
jdduke (slow) 2015/03/17 17:49:51 Oh it's not that particular line that concerns me,
163
164 var rect = focusElement.getBoundingClientRect();
165 var targetTop = focusPos * (rect.bottom - rect.top) + rect.top +
166 document.body.scrollTop - lastClientMidY;
167 document.body.scrollTop = targetTop;
168 };
169
170 var handleTouchCancel = function(e) {
171 pinching = false;
172 };
173
174 function touchDist(e) {
175 var dx = (e.touches[0].screenX-e.touches[1].screenX);
176 var dy = (e.touches[0].screenY-e.touches[1].screenY);
177 return Math.sqrt(dx * dx + dy * dy);
178 }
179
180 function touchClientMid(e) {
181 var mx = (e.touches[0].clientX+e.touches[1].clientX)/2;
182 var my = (e.touches[0].clientY+e.touches[1].clientY)/2;
183 return {x: mx, y: my};
184 }
185
186 function touchPageMid(e) {
187 var mx = (e.touches[0].pageX+e.touches[1].pageX)/2;
188 var my = (e.touches[0].pageY+e.touches[1].pageY)/2;
189 return {x: mx, y: my};
190 }
191
192 window.addEventListener('touchstart', handleTouchStart, false);
193 window.addEventListener('touchmove', handleTouchMove, false);
194 window.addEventListener('touchend', handleTouchEnd, false);
195 window.addEventListener('touchcancel', handleTouchCancel, false);
196 });
OLDNEW
« no previous file with comments | « components/dom_distiller/core/css/distilledpage.css ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698