From 74e28c61c56b3fb22059fc7a3f0aba5002cd2815 Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Fri, 8 Nov 2013 11:22:49 -0600 Subject: [PATCH] Much faster pull to refresh --- dist/css/ionic.css | 4 +-- dist/js/ionic.js | 56 +++++++++++++++++++++----------- js/ext/angular/test/content.html | 8 ++--- js/utils/poly.js | 15 +++++++++ js/views/scrollView.js | 41 ++++++++++++----------- scss/_scaffolding.scss | 4 +-- 6 files changed, 82 insertions(+), 46 deletions(-) diff --git a/dist/css/ionic.css b/dist/css/ionic.css index 7d7312c645..f9620a36b0 100644 --- a/dist/css/ionic.css +++ b/dist/css/ionic.css @@ -2290,8 +2290,8 @@ body, .ionic-body { .scroll-refresher { overflow: hidden; - height: 0; - background-color: white; } + height: 100px; + margin-top: -100px; } .scroll-refreshing { -webkit-transition: height 0.1s ease-in-out; } diff --git a/dist/js/ionic.js b/dist/js/ionic.js index e11fecf2df..23eef8e732 100644 --- a/dist/js/ionic.js +++ b/dist/js/ionic.js @@ -1757,7 +1757,22 @@ window.ionic = { window.setTimeout(callback, 1000 / 60); }; })(); + + // Ionic CSS polyfills + ionic.CSS = {}; + (function() { + var d = document.createElement('div'); + var keys = ['webkitTransform', 'transform', '-webkit-transform', 'webkit-transform', + '-moz-transform', 'moz-transform', 'MozTransform', 'mozTransform']; + + for(var i = 0; i < keys.length; i++) { + if(d.style[keys[i]] !== undefined) { + ionic.CSS.TRANSFORM = keys[i]; + break; + } + } + })(); })(window.ionic); ; @@ -1980,6 +1995,9 @@ window.ionic = { onRefreshOpening: function() {}, // Called when let go and is refreshing onRefresh: function() {}, + refreshEasing: EASING_FUNCTIONS.bounce, + // ms transition time + refreshEasingTime: 400, // How frequently to fire scroll events in the case of // a flick or momentum scroll where the finger is no longer @@ -2087,17 +2105,13 @@ window.ionic = { time = 0; } - if(time == Infinity) { - debugger; - } - var dx = ox - x; var dy = oy - y; el.offsetHeight; el.style.webkitTransitionTimingFunction = easing; el.style.webkitTransitionDuration = time; - el.style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px, 0)'; + el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + x + 'px,' + y + 'px, 0)'; // Stop any other momentum event callbacks clearTimeout(this._momentumStepTimeout); @@ -2311,6 +2325,10 @@ window.ionic = { return; } + if(this._isHoldingRefresh) { + return; + } + var needsWrapping = this.needsWrapping(); // Triggered to end scroll, once the final animation has ended @@ -2376,6 +2394,7 @@ window.ionic = { // Grab the refresher element if using Pull to Refresh if(this.hasPullToRefresh) { this._refresher = document.querySelector('.scroll-refresher'); + this._refresherHeight = parseFloat(this._refresher.firstElementChild.offsetHeight) || 100; if(this._refresher) { this._refresher.classList.remove('scroll-refreshing'); } @@ -2461,10 +2480,7 @@ window.ionic = { var newY = _this.y + deltaY; // Check if the dragging is beyond the bottom or top - if(newY > 0) { - newY = _this.y + deltaY / _this.rubberBandResistance; - } else if ((-newY + parentHeight) > totalHeight) { - // Rubber band + if(newY > 0 || (-newY + parentHeight) > totalHeight) { newY = _this.y + deltaY / _this.rubberBandResistance; } @@ -2477,19 +2493,19 @@ window.ionic = { if(_this._refresher && newY > 0) { // We are pulling to refresh, so update the refresher - _this._refresher.style.height = newY + 'px'; - - var firstChildHeight = parseFloat(_this._refresher.firstElementChild.offsetHeight); - if(newY > firstChildHeight && !_this._isHoldingRefresh) { + //_this._refresher.style[ionic.CSS.TRANSFORM] = 'translate3d(0, ' + newY + 'px, 0)'; + if(newY > _this._refresherHeight && !_this._isHoldingRefresh) { _this._isHoldingRefresh = true; // Trigger refresh holding event here + } else { // Trigger refresh open amount - var ratio = Math.min(1, newY / firstChildHeight); + var ratio = Math.min(1, newY / _this._refresherHeight); + _this.onRefreshOpening && _this.onRefreshOpening(ratio); } // Update the new translated Y point of the container - _this.el.style.webkitTransform = 'translate3d(' + newX + 'px,0, 0)'; + _this.el.style.webkitTransform = 'translate3d(' + newX + 'px,' + newY + 'px, 0)'; } else { // Update the new translated Y point of the container _this.el.style.webkitTransform = 'translate3d(' + newX + 'px,' + newY + 'px, 0)'; @@ -2566,15 +2582,17 @@ window.ionic = { if(_this._refresher && _this.y > 0) { // Pull to refresh - var firstChildHeight = parseFloat(_this._refresher.firstElementChild.offsetHeight); - if(Math.ceil(_this.y) >= firstChildHeight) { + + if(Math.ceil(_this.y) >= _this._refresherHeight) { // REFRESH _this._refresher.classList.add('scroll-refreshing'); - _this._refresher.style.height = firstChildHeight + 'px'; + //_this._refresher.style.height = firstChildHeight + 'px'; + _this._scrollTo(0, _this._refresherHeight, 100, _this.refreshEasing); _this.onRefresh && _this.onRefresh(); } else { _this._refresher.classList.add('scroll-refreshing'); - _this._refresher.style.height = 0 + 'px'; + //_this._refresher.style.height = 0 + 'px'; + _this._scrollTo(0, 0, _this.refreshEasingTime, _this.refreshEasing); _this.onRefresh && _this.onRefresh(); } return; diff --git a/js/ext/angular/test/content.html b/js/ext/angular/test/content.html index 1601c0245a..7814827a4e 100644 --- a/js/ext/angular/test/content.html +++ b/js/ext/angular/test/content.html @@ -1,7 +1,7 @@ - Nav Bars + Content @@ -37,13 +37,13 @@ } .scroll-refresher { - background-color: #222; + border-bottom: 1px solid #eee; } #refresh-content { - color: #fff; + color: #999; padding: 60px 0px; text-align: center; - font-size: 30px; + font-size: 20px; } diff --git a/js/utils/poly.js b/js/utils/poly.js index d359db58ea..82a598b2b3 100644 --- a/js/utils/poly.js +++ b/js/utils/poly.js @@ -11,6 +11,21 @@ window.setTimeout(callback, 1000 / 60); }; })(); + + // Ionic CSS polyfills + ionic.CSS = {}; + (function() { + var d = document.createElement('div'); + var keys = ['webkitTransform', 'transform', '-webkit-transform', 'webkit-transform', + '-moz-transform', 'moz-transform', 'MozTransform', 'mozTransform']; + + for(var i = 0; i < keys.length; i++) { + if(d.style[keys[i]] !== undefined) { + ionic.CSS.TRANSFORM = keys[i]; + break; + } + } + })(); })(window.ionic); diff --git a/js/views/scrollView.js b/js/views/scrollView.js index 819a7b80c6..325d90d495 100644 --- a/js/views/scrollView.js +++ b/js/views/scrollView.js @@ -86,6 +86,9 @@ onRefreshOpening: function() {}, // Called when let go and is refreshing onRefresh: function() {}, + refreshEasing: EASING_FUNCTIONS.bounce, + // ms transition time + refreshEasingTime: 400, // How frequently to fire scroll events in the case of // a flick or momentum scroll where the finger is no longer @@ -193,17 +196,13 @@ time = 0; } - if(time == Infinity) { - debugger; - } - var dx = ox - x; var dy = oy - y; el.offsetHeight; el.style.webkitTransitionTimingFunction = easing; el.style.webkitTransitionDuration = time; - el.style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px, 0)'; + el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + x + 'px,' + y + 'px, 0)'; // Stop any other momentum event callbacks clearTimeout(this._momentumStepTimeout); @@ -417,6 +416,10 @@ return; } + if(this._isHoldingRefresh) { + return; + } + var needsWrapping = this.needsWrapping(); // Triggered to end scroll, once the final animation has ended @@ -482,6 +485,7 @@ // Grab the refresher element if using Pull to Refresh if(this.hasPullToRefresh) { this._refresher = document.querySelector('.scroll-refresher'); + this._refresherHeight = parseFloat(this._refresher.firstElementChild.offsetHeight) || 100; if(this._refresher) { this._refresher.classList.remove('scroll-refreshing'); } @@ -567,10 +571,7 @@ var newY = _this.y + deltaY; // Check if the dragging is beyond the bottom or top - if(newY > 0) { - newY = _this.y + deltaY / _this.rubberBandResistance; - } else if ((-newY + parentHeight) > totalHeight) { - // Rubber band + if(newY > 0 || (-newY + parentHeight) > totalHeight) { newY = _this.y + deltaY / _this.rubberBandResistance; } @@ -583,19 +584,19 @@ if(_this._refresher && newY > 0) { // We are pulling to refresh, so update the refresher - _this._refresher.style.height = newY + 'px'; - - var firstChildHeight = parseFloat(_this._refresher.firstElementChild.offsetHeight); - if(newY > firstChildHeight && !_this._isHoldingRefresh) { + //_this._refresher.style[ionic.CSS.TRANSFORM] = 'translate3d(0, ' + newY + 'px, 0)'; + if(newY > _this._refresherHeight && !_this._isHoldingRefresh) { _this._isHoldingRefresh = true; // Trigger refresh holding event here + } else { // Trigger refresh open amount - var ratio = Math.min(1, newY / firstChildHeight); + var ratio = Math.min(1, newY / _this._refresherHeight); + _this.onRefreshOpening && _this.onRefreshOpening(ratio); } // Update the new translated Y point of the container - _this.el.style.webkitTransform = 'translate3d(' + newX + 'px,0, 0)'; + _this.el.style.webkitTransform = 'translate3d(' + newX + 'px,' + newY + 'px, 0)'; } else { // Update the new translated Y point of the container _this.el.style.webkitTransform = 'translate3d(' + newX + 'px,' + newY + 'px, 0)'; @@ -672,15 +673,17 @@ if(_this._refresher && _this.y > 0) { // Pull to refresh - var firstChildHeight = parseFloat(_this._refresher.firstElementChild.offsetHeight); - if(Math.ceil(_this.y) >= firstChildHeight) { + + if(Math.ceil(_this.y) >= _this._refresherHeight) { // REFRESH _this._refresher.classList.add('scroll-refreshing'); - _this._refresher.style.height = firstChildHeight + 'px'; + //_this._refresher.style.height = firstChildHeight + 'px'; + _this._scrollTo(0, _this._refresherHeight, 100, _this.refreshEasing); _this.onRefresh && _this.onRefresh(); } else { _this._refresher.classList.add('scroll-refreshing'); - _this._refresher.style.height = 0 + 'px'; + //_this._refresher.style.height = 0 + 'px'; + _this._scrollTo(0, 0, _this.refreshEasingTime, _this.refreshEasing); _this.onRefresh && _this.onRefresh(); } return; diff --git a/scss/_scaffolding.scss b/scss/_scaffolding.scss index 82c2c2b9f2..42cfb7d5a2 100644 --- a/scss/_scaffolding.scss +++ b/scss/_scaffolding.scss @@ -110,8 +110,8 @@ body, .ionic-body { // Scroll refresher (for pull to refresh) .scroll-refresher { overflow: hidden; - height: 0; - background-color: white; + height: 100px; + margin-top: -100px; } .scroll-refreshing { -webkit-transition: height 0.1s ease-in-out;