OLD | NEW |
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 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * Viewport class controls the way the image is displayed (scale, offset etc). | 8 * Viewport class controls the way the image is displayed (scale, offset etc). |
9 * @constructor | 9 * @constructor |
10 */ | 10 */ |
(...skipping 17 matching lines...) Expand all Loading... |
28 * not zoom operated by users. | 28 * not zoom operated by users. |
29 * @type {number} | 29 * @type {number} |
30 * @private | 30 * @private |
31 */ | 31 */ |
32 this.scale_ = 1; | 32 this.scale_ = 1; |
33 this.offsetX_ = 0; | 33 this.offsetX_ = 0; |
34 this.offsetY_ = 0; | 34 this.offsetY_ = 0; |
35 | 35 |
36 this.generation_ = 0; | 36 this.generation_ = 0; |
37 | 37 |
38 this.repaintCallbacks_ = []; | |
39 this.update(); | 38 this.update(); |
40 } | 39 } |
41 | 40 |
42 /** | 41 /** |
43 * @param {number} width Image width. | 42 * @param {number} width Image width. |
44 * @param {number} height Image height. | 43 * @param {number} height Image height. |
45 */ | 44 */ |
46 Viewport.prototype.setImageSize = function(width, height) { | 45 Viewport.prototype.setImageSize = function(width, height) { |
47 this.imageBounds_ = new Rect(width, height); | 46 this.imageBounds_ = new Rect(width, height); |
48 this.invalidateCaches(); | 47 this.invalidateCaches(); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 x = this.clampOffsetX_(x); | 147 x = this.clampOffsetX_(x); |
149 y = this.clampOffsetY_(y); | 148 y = this.clampOffsetY_(y); |
150 } | 149 } |
151 if (this.offsetX_ == x && this.offsetY_ == y) return; | 150 if (this.offsetX_ == x && this.offsetY_ == y) return; |
152 this.offsetX_ = x; | 151 this.offsetX_ = x; |
153 this.offsetY_ = y; | 152 this.offsetY_ = y; |
154 this.invalidateCaches(); | 153 this.invalidateCaches(); |
155 }; | 154 }; |
156 | 155 |
157 /** | 156 /** |
158 * Return a closure that can be called to pan the image. | |
159 * Useful for implementing non-trivial variants of panning (overview etc). | |
160 * @param {number} originalX The x coordinate on the screen canvas that | |
161 * corresponds to zero change to offsetX. | |
162 * @param {number} originalY The y coordinate on the screen canvas that | |
163 * corresponds to zero change to offsetY. | |
164 * @param {function():number} scaleFunc returns the image to screen scale. | |
165 * @param {function(number,number):boolean} hitFunc returns true if (x,y) is | |
166 * in the valid region. | |
167 * @return {function} The closure to pan the image. | |
168 */ | |
169 Viewport.prototype.createOffsetSetter = function( | |
170 originalX, originalY, scaleFunc, hitFunc) { | |
171 var originalOffsetX = this.offsetX_; | |
172 var originalOffsetY = this.offsetY_; | |
173 if (!hitFunc) hitFunc = function() { return true; }; | |
174 if (!scaleFunc) scaleFunc = this.getScale.bind(this); | |
175 | |
176 var self = this; | |
177 return function(x, y) { | |
178 if (hitFunc(x, y)) { | |
179 var scale = scaleFunc(); | |
180 self.setOffset( | |
181 originalOffsetX + (x - originalX) / scale, | |
182 originalOffsetY + (y - originalY) / scale); | |
183 self.repaint(); | |
184 } | |
185 }; | |
186 }; | |
187 | |
188 /* | |
189 * Access to the current viewport state. | |
190 */ | |
191 | |
192 /** | |
193 * @return {Rect} The image bounds in image coordinates. | 157 * @return {Rect} The image bounds in image coordinates. |
194 */ | 158 */ |
195 Viewport.prototype.getImageBounds = function() { return this.imageBounds_; }; | 159 Viewport.prototype.getImageBounds = function() { return this.imageBounds_; }; |
196 | 160 |
197 /** | 161 /** |
198 * @return {Rect} The screen bounds in screen coordinates. | 162 * @return {Rect} The screen bounds in screen coordinates. |
199 */ | 163 */ |
200 Viewport.prototype.getScreenBounds = function() { return this.screenBounds_; }; | 164 Viewport.prototype.getScreenBounds = function() { return this.screenBounds_; }; |
201 | 165 |
202 /** | 166 /** |
(...skipping 10 matching lines...) Expand all Loading... |
213 | 177 |
214 /** | 178 /** |
215 * A counter that is incremented with each viewport state change. | 179 * A counter that is incremented with each viewport state change. |
216 * Clients that cache anything that depends on the viewport state should keep | 180 * Clients that cache anything that depends on the viewport state should keep |
217 * track of this counter. | 181 * track of this counter. |
218 * @return {number} counter. | 182 * @return {number} counter. |
219 */ | 183 */ |
220 Viewport.prototype.getCacheGeneration = function() { return this.generation_; }; | 184 Viewport.prototype.getCacheGeneration = function() { return this.generation_; }; |
221 | 185 |
222 /** | 186 /** |
223 * Called on event view port state change (even if repaint has not been called). | 187 * Called on event view port state change. |
224 */ | 188 */ |
225 Viewport.prototype.invalidateCaches = function() { this.generation_++; }; | 189 Viewport.prototype.invalidateCaches = function() { this.generation_++; }; |
226 | 190 |
227 /** | 191 /** |
228 * @return {Rect} The image bounds in screen coordinates. | 192 * @return {Rect} The image bounds in screen coordinates. |
229 */ | 193 */ |
230 Viewport.prototype.getImageBoundsOnScreen = function() { | 194 Viewport.prototype.getImageBoundsOnScreen = function() { |
231 return this.imageOnScreen_; | 195 return this.imageOnScreen_; |
232 }; | 196 }; |
233 | 197 |
234 /* | |
235 * Conversion between the screen and image coordinate spaces. | |
236 */ | |
237 | |
238 /** | 198 /** |
239 * @param {number} size Size in screen coordinates. | 199 * @param {number} size Size in screen coordinates. |
240 * @return {number} Size in image coordinates. | 200 * @return {number} Size in image coordinates. |
241 */ | 201 */ |
242 Viewport.prototype.screenToImageSize = function(size) { | 202 Viewport.prototype.screenToImageSize = function(size) { |
243 return size / this.getScale(); | 203 return size / this.getScale(); |
244 }; | 204 }; |
245 | 205 |
246 /** | 206 /** |
247 * @param {number} x X in screen coordinates. | 207 * @param {number} x X in screen coordinates. |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 Math.round(this.clampOffsetY_(this.offsetY_) * scale); | 377 Math.round(this.clampOffsetY_(this.offsetY_) * scale); |
418 this.imageClipped_.top = Math.round(-this.imageOnScreen_.top / scale); | 378 this.imageClipped_.top = Math.round(-this.imageOnScreen_.top / scale); |
419 this.imageClipped_.height = Math.round(this.screenBounds_.height / scale); | 379 this.imageClipped_.height = Math.round(this.screenBounds_.height / scale); |
420 } else { | 380 } else { |
421 this.screenClipped_.top = this.imageOnScreen_.top; | 381 this.screenClipped_.top = this.imageOnScreen_.top; |
422 this.screenClipped_.height = this.imageOnScreen_.height; | 382 this.screenClipped_.height = this.imageOnScreen_.height; |
423 } | 383 } |
424 }; | 384 }; |
425 | 385 |
426 /** | 386 /** |
427 * @param {function} callback Repaint callback. | |
428 */ | |
429 Viewport.prototype.addRepaintCallback = function(callback) { | |
430 this.repaintCallbacks_.push(callback); | |
431 }; | |
432 | |
433 /** | |
434 * Repaint all clients. | |
435 */ | |
436 Viewport.prototype.repaint = function() { | |
437 this.update(); | |
438 for (var i = 0; i != this.repaintCallbacks_.length; i++) | |
439 this.repaintCallbacks_[i](); | |
440 }; | |
441 | |
442 /** | |
443 * Obtains CSS transformation for the screen image. | 387 * Obtains CSS transformation for the screen image. |
444 * @return {string} Transformation description. | 388 * @return {string} Transformation description. |
445 */ | 389 */ |
446 Viewport.prototype.getTransformation = function() { | 390 Viewport.prototype.getTransformation = function() { |
447 return 'scale(' + (1 / window.devicePixelRatio) + ')'; | 391 return 'scale(' + (1 / window.devicePixelRatio) + ')'; |
448 }; | 392 }; |
449 | 393 |
450 /** | 394 /** |
451 * Obtains shift CSS transformation for the screen image. | 395 * Obtains shift CSS transformation for the screen image. |
452 * @param {number} dx Amount of shift. | 396 * @param {number} dx Amount of shift. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 var screenWidth = this.screenBounds_.width; | 467 var screenWidth = this.screenBounds_.width; |
524 var screenHeight = this.screenBounds_.height; | 468 var screenHeight = this.screenBounds_.height; |
525 var dx = screenRect.left + screenRect.width / 2 - screenWidth / 2; | 469 var dx = screenRect.left + screenRect.width / 2 - screenWidth / 2; |
526 var dy = screenRect.top + screenRect.height / 2 - screenHeight / 2; | 470 var dy = screenRect.top + screenRect.height / 2 - screenHeight / 2; |
527 return [ | 471 return [ |
528 'translate(' + dx + 'px,' + dy + 'px)', | 472 'translate(' + dx + 'px,' + dy + 'px)', |
529 'scale(' + scaleX + ',' + scaleY + ')', | 473 'scale(' + scaleX + ',' + scaleY + ')', |
530 this.getTransformation() | 474 this.getTransformation() |
531 ].join(' '); | 475 ].join(' '); |
532 }; | 476 }; |
OLD | NEW |