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

Unified Diff: chrome/browser/resources/file_manager/js/photo/mosaic_mode.js

Issue 12208042: Smooth scrolling effect to mosaic view. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleaned up. Created 7 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/file_manager/js/photo/mosaic_mode.js
diff --git a/chrome/browser/resources/file_manager/js/photo/mosaic_mode.js b/chrome/browser/resources/file_manager/js/photo/mosaic_mode.js
index 0bfac6b53ce1da337ba586049703ba08e3443f2a..dd359a53daf77edf4c537b43d0724b48d5cb90e8 100644
--- a/chrome/browser/resources/file_manager/js/photo/mosaic_mode.js
+++ b/chrome/browser/resources/file_manager/js/photo/mosaic_mode.js
@@ -89,6 +89,12 @@ Mosaic.prototype.__proto__ = HTMLDivElement.prototype;
Mosaic.LAYOUT_DELAY = 200;
/**
+ * Smooth scroll animation duration when scrolling using keyboard or
+ * clicking on a partly visible tile. In ms.
+ */
+Mosaic.ANIMATED_SCROLL_DURATION = 500;
+
+/**
* Decorate a Mosaic instance.
*
* @param {Mosaic} self Self pointer.
@@ -170,6 +176,56 @@ Mosaic.prototype.initListeners_ = function() {
};
/**
+ * Smoothly scrolls the container to the specified position using
+ * f(x) = sqrt(x) speed function normalized to animation duration.
+ * @param {number} targetPosition Horizontal scroll position in pixels.
+ */
+Mosaic.prototype.animatedScrollTo = function(targetPosition) {
+ if (this.scrollTimer_)
+ clearInterval(this.scrollTimer_);
yoshiki 2013/02/12 01:30:52 Assign null or undefined after clearing the interv
mtomasz 2013/02/12 04:19:21 Done.
+
+ // Mouse move events are fired without touching the mouse because of scrolling
+ // the container. Therefore, these events have to be suppressed.
+ this.suppressHovering_ = true;
+
+ // Calculates integral area from t1 to t2 of f(x) = sqrt(x) dx.
+ var integral = function(t1, t2) {
+ return 2.0 / 3.0 * Math.pow(t2, 3.0 / 2.0) -
+ 2.0 / 3.0 * Math.pow(t1, 3.0 / 2.0);
+ };
+
+ var delta = targetPosition - this.scrollLeft;
+ var factor = delta / integral(0, Mosaic.ANIMATED_SCROLL_DURATION);
+ var startTime = Date.now();
+ var lastPosition = 0;
+
+ this.scrollTimer_ = setInterval(function() {
yoshiki 2013/02/12 01:30:52 It is better to use "requestAnimationFrame" on ani
mtomasz 2013/02/12 04:19:21 This is great, I didn't know about it! Done.
+ var position = Date.now() - startTime;
+ var step = factor *
+ integral(Math.max(0, Mosaic.ANIMATED_SCROLL_DURATION - position),
+ Math.max(0, Mosaic.ANIMATED_SCROLL_DURATION - lastPosition));
+
+ var lastScrollLeft = this.scrollLeft;
+ console.log(step);
yoshiki 2013/02/12 01:30:52 Remove?
mtomasz 2013/02/12 04:19:21 Done.
+ this.scrollLeft += step;
+
+ if (lastScrollLeft == this.scrollLeft) {
yoshiki 2013/02/12 01:30:52 We can replace this condition with just "step == 0
mtomasz 2013/02/12 04:19:21 Nope, this didn't work when reaching edges, eg. wh
+ clearInterval(this.scrollTimer_);
+ this.scrollTimer_ = null;
+
+ // Release the hovering lock after a safe delay to avoid hovering
+ // a tile because of altering |this.scrollLeft|.
+ setTimeout(function() {
+ if (!this.scrollTimer_)
+ this.suppressHovering_ = false;
+ }.bind(this), 100);
+ }
+
+ lastPosition = position;
+ }.bind(this), 10);
+};
+
+/**
* @return {Mosaic.Tile} Selected tile or undefined if no selection.
*/
Mosaic.prototype.getSelectedTile = function() {
@@ -312,7 +368,8 @@ Mosaic.prototype.onResize_ = function() {
*/
Mosaic.prototype.onMouseEvent_ = function(event) {
// Navigating with mouse, enable hover state.
- this.classList.add('hover-visible');
+ if (!this.suppressHovering_)
+ this.classList.add('hover-visible');
if (event.type == 'mousemove')
return;
@@ -570,6 +627,12 @@ Mosaic.Layout.PADDING_BOTTOM = 70;
Mosaic.Layout.SPACING = 10;
/**
+ * Margin for scrolling using keyboard. Distance between a selected tile
+ * and window border.
+ */
+Mosaic.Layout.SCROLL_MARGIN = 30;
+
+/**
* Layout mode: commit to DOM immediately.
*/
Mosaic.Layout.MODE_FINAL = 'final';
@@ -1603,7 +1666,7 @@ Mosaic.Tile.prototype.layout = function(left, top, width, height) {
this.wrapper_ = util.createChild(border, 'img-wrapper');
}
if (this.hasAttribute('selected'))
- this.scrollIntoView();
+ this.scrollIntoView(false);
this.thumbnailLoader_.attachImage(this.wrapper_,
ThumbnailLoader.FillMode.FILL);
@@ -1611,18 +1674,29 @@ Mosaic.Tile.prototype.layout = function(left, top, width, height) {
/**
* If the tile is not fully visible scroll the parent to make it fully visible.
+ * @param {boolean} opt_animated True, if scroll should be animated,
+ * default: true.
*/
-Mosaic.Tile.prototype.scrollIntoView = function() {
+Mosaic.Tile.prototype.scrollIntoView = function(opt_animated) {
if (this.left_ == null) // Not laid out.
return;
- if (this.left_ < this.container_.scrollLeft) {
- this.container_.scrollLeft = this.left_;
+ var targetPosition;
+ var tileLeft = this.left_ - Mosaic.Layout.SCROLL_MARGIN;
+ if (tileLeft < this.container_.scrollLeft) {
+ targetPosition = tileLeft;
} else {
- var tileRight = this.left_ + this.width_;
+ var tileRight = this.left_ + this.width_ + Mosaic.Layout.SCROLL_MARGIN;
var scrollRight = this.container_.scrollLeft + this.container_.clientWidth;
if (tileRight > scrollRight)
- this.container_.scrollLeft = tileRight - this.container_.clientWidth;
+ targetPosition = tileRight - this.container_.clientWidth;
+ }
+
+ if (targetPosition) {
+ if (opt_animated === false)
+ this.container_.scrollLeft = targetPosition;
+ else
+ this.container_.animatedScrollTo(targetPosition);
}
};
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698