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

Side by Side Diff: chrome/browser/resources/file_manager/js/image_editor/viewport.js

Issue 10391183: [Photo Editor] Javascript style fixes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/resources/file_manager/js/image_editor/image_view.js ('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 (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 /** 5 /**
6 * Viewport class controls the way the image is displayed (scale, offset etc). 6 * Viewport class controls the way the image is displayed (scale, offset etc).
7 * @constructor
7 */ 8 */
8 function Viewport() { 9 function Viewport() {
9 this.imageBounds_ = new Rect(); 10 this.imageBounds_ = new Rect();
10 this.screenBounds_ = new Rect(); 11 this.screenBounds_ = new Rect();
11 12
12 this.scale_ = 1; 13 this.scale_ = 1;
13 this.offsetX_ = 0; 14 this.offsetX_ = 0;
14 this.offsetY_ = 0; 15 this.offsetY_ = 0;
15 16
16 this.generation_ = 0; 17 this.generation_ = 0;
17 18
18 this.scaleControl_ = null; 19 this.scaleControl_ = null;
19 this.repaintCallbacks_ = []; 20 this.repaintCallbacks_ = [];
20 this.update(); 21 this.update();
21 } 22 }
22 23
23 /* 24 /*
24 * Viewport modification. 25 * Viewport modification.
25 */ 26 */
26 27
28 /**
29 * @param {object} scaleControl The UI object responsible for scaling.
30 */
27 Viewport.prototype.setScaleControl = function(scaleControl) { 31 Viewport.prototype.setScaleControl = function(scaleControl) {
28 this.scaleControl_ = scaleControl; 32 this.scaleControl_ = scaleControl;
29 }; 33 };
30 34
35 /**
36 * @param {number} width Image width.
37 * @param {number} height Image height.
38 */
31 Viewport.prototype.setImageSize = function(width, height) { 39 Viewport.prototype.setImageSize = function(width, height) {
32 this.imageBounds_ = new Rect(width, height); 40 this.imageBounds_ = new Rect(width, height);
33 if (this.scaleControl_) this.scaleControl_.displayImageSize(width, height); 41 if (this.scaleControl_) this.scaleControl_.displayImageSize(width, height);
34 this.invalidateCaches(); 42 this.invalidateCaches();
35 }; 43 };
36 44
45 /**
46 * @param {number} width Screen width.
47 * @param {number} height Screen height.
48 */
37 Viewport.prototype.setScreenSize = function(width, height) { 49 Viewport.prototype.setScreenSize = function(width, height) {
38 this.screenBounds_ = new Rect(width, height); 50 this.screenBounds_ = new Rect(width, height);
39 if (this.scaleControl_) 51 if (this.scaleControl_)
40 this.scaleControl_.setMinScale(this.getFittingScale()); 52 this.scaleControl_.setMinScale(this.getFittingScale());
41 this.invalidateCaches(); 53 this.invalidateCaches();
42 }; 54 };
43 55
56 /**
57 * Set the size by an HTML element.
58 *
59 * @param {HTMLElement} frame The element acting as the "screen".
60 */
44 Viewport.prototype.sizeByFrame = function(frame) { 61 Viewport.prototype.sizeByFrame = function(frame) {
45 this.setScreenSize(frame.clientWidth, frame.clientHeight); 62 this.setScreenSize(frame.clientWidth, frame.clientHeight);
46 }; 63 };
47 64
65 /**
66 * Set the size and scale to fit an HTML element.
67 *
68 * @param {HTMLElement} frame The element acting as the "screen".
69 */
48 Viewport.prototype.sizeByFrameAndFit = function(frame) { 70 Viewport.prototype.sizeByFrameAndFit = function(frame) {
49 var wasFitting = this.getScale() == this.getFittingScale(); 71 var wasFitting = this.getScale() == this.getFittingScale();
50 this.sizeByFrame(frame); 72 this.sizeByFrame(frame);
51 var minScale = this.getFittingScale(); 73 var minScale = this.getFittingScale();
52 if (wasFitting || (this.getScale() < minScale)) { 74 if (wasFitting || (this.getScale() < minScale)) {
53 this.setScale(minScale, true); 75 this.setScale(minScale, true);
54 } 76 }
55 }; 77 };
56 78
79 /**
80 * @return {number} Scale
81 */
57 Viewport.prototype.getScale = function() { return this.scale_ }; 82 Viewport.prototype.getScale = function() { return this.scale_ };
58 83
84 /**
85 * @param {number} scale The new scale.
86 * @param {boolean} notify True if the change should be reflected in the UI.
87 */
59 Viewport.prototype.setScale = function(scale, notify) { 88 Viewport.prototype.setScale = function(scale, notify) {
60 if (this.scale_ == scale) return; 89 if (this.scale_ == scale) return;
61 this.scale_ = scale; 90 this.scale_ = scale;
62 if (notify && this.scaleControl_) this.scaleControl_.displayScale(scale); 91 if (notify && this.scaleControl_) this.scaleControl_.displayScale(scale);
63 this.invalidateCaches(); 92 this.invalidateCaches();
64 }; 93 };
65 94
95 /**
96 * @return {number} Best scale to fit the current image into the current screen.
97 */
66 Viewport.prototype.getFittingScale = function() { 98 Viewport.prototype.getFittingScale = function() {
67 var scaleX = this.screenBounds_.width / this.imageBounds_.width; 99 var scaleX = this.screenBounds_.width / this.imageBounds_.width;
68 var scaleY = this.screenBounds_.height / this.imageBounds_.height; 100 var scaleY = this.screenBounds_.height / this.imageBounds_.height;
69 // Scales > (1 / this.getDevicePixelRatio()) do not look good. Also they are 101 // Scales > (1 / this.getDevicePixelRatio()) do not look good. Also they are
70 // not really useful as we do not have any pixel-level operations. 102 // not really useful as we do not have any pixel-level operations.
71 return Math.min(1 / this.getDevicePixelRatio(), scaleX, scaleY); 103 return Math.min(1 / this.getDevicePixelRatio(), scaleX, scaleY);
72 }; 104 };
73 105
106 /**
107 * Set the scale to fit the image into the screen.
108 */
74 Viewport.prototype.fitImage = function() { 109 Viewport.prototype.fitImage = function() {
75 var scale = this.getFittingScale(); 110 var scale = this.getFittingScale();
76 if (this.scaleControl_) this.scaleControl_.setMinScale(scale); 111 if (this.scaleControl_) this.scaleControl_.setMinScale(scale);
77 this.setScale(scale, true); 112 this.setScale(scale, true);
78 }; 113 };
79 114
80 Viewport.prototype.getOffsetX = function () { return this.offsetX_ }; 115 /**
116 * @return {number} X-offset of the viewport.
117 */
118 Viewport.prototype.getOffsetX = function() { return this.offsetX_ };
81 119
82 Viewport.prototype.getOffsetY = function () { return this.offsetY_ }; 120 /**
121 * @return {number} Y-offset of the viewport.
122 */
123 Viewport.prototype.getOffsetY = function() { return this.offsetY_ };
83 124
125 /**
126 * Set the image offset in the viewport.
127 * @param {number} x X-offset.
128 * @param {number} y Y-offset.
129 * @param {boolean} ignoreClipping True if no clipping should be applied.
130 */
84 Viewport.prototype.setOffset = function(x, y, ignoreClipping) { 131 Viewport.prototype.setOffset = function(x, y, ignoreClipping) {
85 if (!ignoreClipping) { 132 if (!ignoreClipping) {
86 x = this.clampOffsetX_(x); 133 x = this.clampOffsetX_(x);
87 y = this.clampOffsetY_(y); 134 y = this.clampOffsetY_(y);
88 } 135 }
89 if (this.offsetX_ == x && this.offsetY_ == y) return; 136 if (this.offsetX_ == x && this.offsetY_ == y) return;
90 this.offsetX_ = x; 137 this.offsetX_ = x;
91 this.offsetY_ = y; 138 this.offsetY_ = y;
92 this.invalidateCaches(); 139 this.invalidateCaches();
93 }; 140 };
94 141
95 Viewport.prototype.setCenter = function(x, y, ignoreClipping) {
96 this.setOffset(
97 this.imageBounds_.width / 2 - x,
98 this.imageBounds_.height / 2 - y,
99 ignoreClipping);
100 };
101
102 /** 142 /**
103 * Return a closure that can be called to pan the image. 143 * Return a closure that can be called to pan the image.
104 * Useful for implementing non-trivial variants of panning (overview etc). 144 * Useful for implementing non-trivial variants of panning (overview etc).
105 * @param {number} originalX The x coordinate on the screen canvas that 145 * @param {number} originalX The x coordinate on the screen canvas that
106 * corresponds to zero change to offsetX. 146 * corresponds to zero change to offsetX.
107 * @param {number} originalY The y coordinate on the screen canvas that 147 * @param {number} originalY The y coordinate on the screen canvas that
108 * corresponds to zero change to offsetY. 148 * corresponds to zero change to offsetY.
109 * @param {function():number} scaleFunc returns the image to screen scale. 149 * @param {function():number} scaleFunc returns the image to screen scale.
110 * @param {function(number,number):boolean} hitFunc returns true if (x,y) is 150 * @param {function(number,number):boolean} hitFunc returns true if (x,y) is
111 * in the valid region. 151 * in the valid region.
152 * @return {function} The closure to pan the image.
112 */ 153 */
113 Viewport.prototype.createOffsetSetter = function ( 154 Viewport.prototype.createOffsetSetter = function(
114 originalX, originalY, scaleFunc, hitFunc) { 155 originalX, originalY, scaleFunc, hitFunc) {
115 var originalOffsetX = this.offsetX_; 156 var originalOffsetX = this.offsetX_;
116 var originalOffsetY = this.offsetY_; 157 var originalOffsetY = this.offsetY_;
117 if (!hitFunc) hitFunc = function() { return true }; 158 if (!hitFunc) hitFunc = function() { return true };
118 if (!scaleFunc) scaleFunc = this.getScale.bind(this); 159 if (!scaleFunc) scaleFunc = this.getScale.bind(this);
119 160
120 var self = this; 161 var self = this;
121 return function(x, y) { 162 return function(x, y) {
122 if (hitFunc(x, y)) { 163 if (hitFunc(x, y)) {
123 var scale = scaleFunc(); 164 var scale = scaleFunc();
(...skipping 26 matching lines...) Expand all
150 191
151 /** 192 /**
152 * @return {Rect} The visible part of the image, in screen coordinates. 193 * @return {Rect} The visible part of the image, in screen coordinates.
153 */ 194 */
154 Viewport.prototype.getScreenClipped = function() { return this.screenClipped_ }; 195 Viewport.prototype.getScreenClipped = function() { return this.screenClipped_ };
155 196
156 /** 197 /**
157 * A counter that is incremented with each viewport state change. 198 * A counter that is incremented with each viewport state change.
158 * Clients that cache anything that depends on the viewport state should keep 199 * Clients that cache anything that depends on the viewport state should keep
159 * track of this counter. 200 * track of this counter.
201 * @return {number} counter
160 */ 202 */
161 Viewport.prototype.getCacheGeneration = function() { return this.generation_ }; 203 Viewport.prototype.getCacheGeneration = function() { return this.generation_ };
162 204
163 /** 205 /**
164 * Called on evert view port state change (even if repaint has not been called). 206 * Called on evert view port state change (even if repaint has not been called).
165 */ 207 */
166 Viewport.prototype.invalidateCaches = function() { this.generation_++ }; 208 Viewport.prototype.invalidateCaches = function() { this.generation_++ };
167 209
168 /** 210 /**
169 * @return {Rect} The image bounds in screen coordinates. 211 * @return {Rect} The image bounds in screen coordinates.
170 */ 212 */
171 Viewport.prototype.getImageBoundsOnScreen = function() { 213 Viewport.prototype.getImageBoundsOnScreen = function() {
172 return this.imageOnScreen_; 214 return this.imageOnScreen_;
173 }; 215 };
174 216
175 /* 217 /*
176 * Conversion between the screen and image coordinate spaces. 218 * Conversion between the screen and image coordinate spaces.
177 */ 219 */
178 220
221 /**
222 * @param {number} size Size in screen coordinates.
223 * @return {number} Size in image coordinates.
224 */
179 Viewport.prototype.screenToImageSize = function(size) { 225 Viewport.prototype.screenToImageSize = function(size) {
180 return size / this.getScale(); 226 return size / this.getScale();
181 }; 227 };
182 228
229 /**
230 * @param {number} x X in screen coordinates.
231 * @return {number} X in image coordinates.
232 */
183 Viewport.prototype.screenToImageX = function(x) { 233 Viewport.prototype.screenToImageX = function(x) {
184 return Math.round((x - this.imageOnScreen_.left) / this.getScale()); 234 return Math.round((x - this.imageOnScreen_.left) / this.getScale());
185 }; 235 };
186 236
237 /**
238 * @param {number} y Y in screen coordinates.
239 * @return {number} Y in image coordinates.
240 */
187 Viewport.prototype.screenToImageY = function(y) { 241 Viewport.prototype.screenToImageY = function(y) {
188 return Math.round((y - this.imageOnScreen_.top) / this.getScale()); 242 return Math.round((y - this.imageOnScreen_.top) / this.getScale());
189 }; 243 };
190 244
245 /**
246 * @param {Rect} rect Rectange in screen coordinates.
247 * @return {Rect} Rectange in image coordinates.
248 */
191 Viewport.prototype.screenToImageRect = function(rect) { 249 Viewport.prototype.screenToImageRect = function(rect) {
192 return new Rect( 250 return new Rect(
193 this.screenToImageX(rect.left), 251 this.screenToImageX(rect.left),
194 this.screenToImageY(rect.top), 252 this.screenToImageY(rect.top),
195 this.screenToImageSize(rect.width), 253 this.screenToImageSize(rect.width),
196 this.screenToImageSize(rect.height)); 254 this.screenToImageSize(rect.height));
197 }; 255 };
198 256
257 /**
258 * @param {number} size Size in image coordinates.
259 * @return {number} Size in screen coordinates.
260 */
199 Viewport.prototype.imageToScreenSize = function(size) { 261 Viewport.prototype.imageToScreenSize = function(size) {
200 return size * this.getScale(); 262 return size * this.getScale();
201 }; 263 };
202 264
265 /**
266 * @param {number} x X in image coordinates.
267 * @return {number} X in screen coordinates.
268 */
203 Viewport.prototype.imageToScreenX = function(x) { 269 Viewport.prototype.imageToScreenX = function(x) {
204 return Math.round(this.imageOnScreen_.left + x * this.getScale()); 270 return Math.round(this.imageOnScreen_.left + x * this.getScale());
205 }; 271 };
206 272
273 /**
274 * @param {number} y Y in image coordinates.
275 * @return {number} Y in screen coordinates.
276 */
207 Viewport.prototype.imageToScreenY = function(y) { 277 Viewport.prototype.imageToScreenY = function(y) {
208 return Math.round(this.imageOnScreen_.top + y * this.getScale()); 278 return Math.round(this.imageOnScreen_.top + y * this.getScale());
209 }; 279 };
210 280
281 /**
282 * @param {Rect} rect Rectange in image coordinates.
283 * @return {Rect} Rectange in screen coordinates.
284 */
211 Viewport.prototype.imageToScreenRect = function(rect) { 285 Viewport.prototype.imageToScreenRect = function(rect) {
212 return new Rect( 286 return new Rect(
213 this.imageToScreenX(rect.left), 287 this.imageToScreenX(rect.left),
214 this.imageToScreenY(rect.top), 288 this.imageToScreenY(rect.top),
215 Math.round(this.imageToScreenSize(rect.width)), 289 Math.round(this.imageToScreenSize(rect.width)),
216 Math.round(this.imageToScreenSize(rect.height))); 290 Math.round(this.imageToScreenSize(rect.height)));
217 }; 291 };
218 292
219 /** 293 /**
220 * @return {number} The number of physical pixels in one CSS pixel. 294 * @return {number} The number of physical pixels in one CSS pixel.
(...skipping 24 matching lines...) Expand all
245 }; 319 };
246 320
247 /** 321 /**
248 * @return {Rect} The visible part of the image, in device coordinates. 322 * @return {Rect} The visible part of the image, in device coordinates.
249 */ 323 */
250 Viewport.prototype.getDeviceClipped = function() { 324 Viewport.prototype.getDeviceClipped = function() {
251 return this.screenToDeviceRect(this.getScreenClipped()); 325 return this.screenToDeviceRect(this.getScreenClipped());
252 }; 326 };
253 327
254 /** 328 /**
255 * @return {Boolean} True if some part of the image is clipped by the screen. 329 * @return {boolean} True if some part of the image is clipped by the screen.
256 */ 330 */
257 Viewport.prototype.isClipped = function () { 331 Viewport.prototype.isClipped = function() {
258 return this.getMarginX_() < 0 || this.getMarginY_() < 0; 332 return this.getMarginX_() < 0 || this.getMarginY_() < 0;
259 }; 333 };
260 334
261 /** 335 /**
262 * Horizontal margin. Negative if the image is clipped horizontally. 336 * @return {number} Horizontal margin.
337 * Negative if the image is clipped horizontally.
338 * @private
263 */ 339 */
264 Viewport.prototype.getMarginX_ = function() { 340 Viewport.prototype.getMarginX_ = function() {
265 return Math.round( 341 return Math.round(
266 (this.screenBounds_.width - this.imageBounds_.width * this.scale_) / 2); 342 (this.screenBounds_.width - this.imageBounds_.width * this.scale_) / 2);
267 }; 343 };
268 344
269 /** 345 /**
270 * Vertical margin. Negative if the image is clipped vertically. 346 * @return {number} Vertical margin.
347 * Negative if the image is clipped vertically.
348 * @private
271 */ 349 */
272 Viewport.prototype.getMarginY_ = function() { 350 Viewport.prototype.getMarginY_ = function() {
273 return Math.round( 351 return Math.round(
274 (this.screenBounds_.height - this.imageBounds_.height * this.scale_) / 2); 352 (this.screenBounds_.height - this.imageBounds_.height * this.scale_) / 2);
275 }; 353 };
276 354
355 /**
356 * @param {number} x X-offset.
357 * @return {number} X-offset clamped to the valid range.
358 * @private
359 */
277 Viewport.prototype.clampOffsetX_ = function(x) { 360 Viewport.prototype.clampOffsetX_ = function(x) {
278 var limit = Math.round(Math.max(0, -this.getMarginX_() / this.getScale())); 361 var limit = Math.round(Math.max(0, -this.getMarginX_() / this.getScale()));
279 return ImageUtil.clamp(-limit, x, limit); 362 return ImageUtil.clamp(-limit, x, limit);
280 }; 363 };
281 364
365 /**
366 * @param {number} y Y-offset.
367 * @return {number} Y-offset clamped to the valid range.
368 * @private
369 */
282 Viewport.prototype.clampOffsetY_ = function(y) { 370 Viewport.prototype.clampOffsetY_ = function(y) {
283 var limit = Math.round(Math.max(0, -this.getMarginY_() / this.getScale())); 371 var limit = Math.round(Math.max(0, -this.getMarginY_() / this.getScale()));
284 return ImageUtil.clamp(-limit, y, limit); 372 return ImageUtil.clamp(-limit, y, limit);
285 }; 373 };
286 374
287 /** 375 /**
288 * Recalculate the viewport parameters. 376 * Recalculate the viewport parameters.
289 */ 377 */
290 Viewport.prototype.update = function() { 378 Viewport.prototype.update = function() {
291 var scale = this.getScale(); 379 var scale = this.getScale();
(...skipping 26 matching lines...) Expand all
318 this.imageOnScreen_.top += 406 this.imageOnScreen_.top +=
319 Math.round(this.clampOffsetY_(this.offsetY_) * scale); 407 Math.round(this.clampOffsetY_(this.offsetY_) * scale);
320 this.imageClipped_.top = Math.round(-this.imageOnScreen_.top / scale); 408 this.imageClipped_.top = Math.round(-this.imageOnScreen_.top / scale);
321 this.imageClipped_.height = Math.round(this.screenBounds_.height / scale); 409 this.imageClipped_.height = Math.round(this.screenBounds_.height / scale);
322 } else { 410 } else {
323 this.screenClipped_.top = this.imageOnScreen_.top; 411 this.screenClipped_.top = this.imageOnScreen_.top;
324 this.screenClipped_.height = this.imageOnScreen_.height; 412 this.screenClipped_.height = this.imageOnScreen_.height;
325 } 413 }
326 }; 414 };
327 415
328 Viewport.prototype.addRepaintCallback = function (callback) { 416 /**
417 * @param {function} callback Repaint callback.
418 */
419 Viewport.prototype.addRepaintCallback = function(callback) {
329 this.repaintCallbacks_.push(callback); 420 this.repaintCallbacks_.push(callback);
330 }; 421 };
331 422
332 Viewport.prototype.repaint = function () { 423 /**
424 * Repaint all clients.
425 */
426 Viewport.prototype.repaint = function() {
333 this.update(); 427 this.update();
334 for (var i = 0; i != this.repaintCallbacks_.length; i++) 428 for (var i = 0; i != this.repaintCallbacks_.length; i++)
335 this.repaintCallbacks_[i](); 429 this.repaintCallbacks_[i]();
336 }; 430 };
OLDNEW
« no previous file with comments | « chrome/browser/resources/file_manager/js/image_editor/image_view.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698