mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-07 06:57:02 +08:00
More scroll work
This commit is contained in:
194
dist/js/ionic.js
vendored
194
dist/js/ionic.js
vendored
@ -2483,6 +2483,9 @@ window.ionic = {
|
|||||||
;
|
;
|
||||||
(function(ionic) {
|
(function(ionic) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
var EASING_FUNCTIONS = {
|
||||||
|
quadratic: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)'
|
||||||
|
};
|
||||||
|
|
||||||
ionic.views.ScrollView = function(opts) {
|
ionic.views.ScrollView = function(opts) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
@ -2493,6 +2496,7 @@ window.ionic = {
|
|||||||
dragThreshold: 10,
|
dragThreshold: 10,
|
||||||
resistance: 2,
|
resistance: 2,
|
||||||
scrollEventName: 'momentumScrolled',
|
scrollEventName: 'momentumScrolled',
|
||||||
|
scrollEndEventName: 'momentumScrollEnd',
|
||||||
intertialEventInterval: 50,
|
intertialEventInterval: 50,
|
||||||
mouseWheelSpeed: 20,
|
mouseWheelSpeed: 20,
|
||||||
invertWheel: false,
|
invertWheel: false,
|
||||||
@ -2521,8 +2525,11 @@ window.ionic = {
|
|||||||
ionic.on('DOMMouseScroll', function(e) {
|
ionic.on('DOMMouseScroll', function(e) {
|
||||||
_this._wheel(e);
|
_this._wheel(e);
|
||||||
}, this.el);
|
}, this.el);
|
||||||
|
ionic.on(this.scrollEndEventName, function(e) {
|
||||||
|
_this._onScrollEnd(e);
|
||||||
|
}, this.el);
|
||||||
ionic.on('webkitTransitionEnd', function(e) {
|
ionic.on('webkitTransitionEnd', function(e) {
|
||||||
_this._endTransition();
|
_this._onTransitionEnd(e);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2531,6 +2538,95 @@ window.ionic = {
|
|||||||
DECEL_RATE_FAST: 0.99,
|
DECEL_RATE_FAST: 0.99,
|
||||||
DECEL_RATE_SLOW: 0.996,
|
DECEL_RATE_SLOW: 0.996,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll to the given X and Y point, taking
|
||||||
|
* the given amount of time, with the given
|
||||||
|
* easing function defined as a CSS3 timing function.
|
||||||
|
*
|
||||||
|
* @param {float} the x position to scroll to (CURRENTLY NOT SUPPORTED!)
|
||||||
|
* @param {float} the y position to scroll to
|
||||||
|
* @param {float} the time to take scrolling to the new position
|
||||||
|
* @param {easing} the animation function to use for easing
|
||||||
|
*/
|
||||||
|
scrollTo: function(x, y, time, easing) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
easing = easing || 'cubic-bezier(0.1, 0.57, 0.1, 1)';
|
||||||
|
|
||||||
|
var el = this.el;
|
||||||
|
|
||||||
|
if(x !== null) {
|
||||||
|
this.x = x;
|
||||||
|
} else {
|
||||||
|
x = this.x;
|
||||||
|
}
|
||||||
|
if(y !== null) {
|
||||||
|
this.y = y;
|
||||||
|
} else {
|
||||||
|
y = this.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
el.style.webkitTransitionTimingFunction = easing;
|
||||||
|
el.style.webkitTransitionDuration = time;
|
||||||
|
el.style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px, 0)';
|
||||||
|
|
||||||
|
// Start triggering events as the element scrolls from inertia.
|
||||||
|
// This is important because we need to receive scroll events
|
||||||
|
// even after a "flick" and adjust, etc.
|
||||||
|
this._momentumStepTimeout = setTimeout(function eventNotify() {
|
||||||
|
var scrollTop = parseFloat(_this.el.style.webkitTransform.replace('translate3d(', '').split(',')[1]) || 0;
|
||||||
|
ionic.trigger(_this.scrollEventName, {
|
||||||
|
target: _this.el,
|
||||||
|
scrollTop: -scrollTop
|
||||||
|
});
|
||||||
|
|
||||||
|
if(_this._isDragging) {
|
||||||
|
_this._momentumStepTimeout = setTimeout(eventNotify, _this.inertialEventInterval);
|
||||||
|
}
|
||||||
|
}, this.inertialEventInterval)
|
||||||
|
|
||||||
|
console.log('TRANSITION ADDED!');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the scroll position is outside the current bounds,
|
||||||
|
* animate it back.
|
||||||
|
*/
|
||||||
|
wrapScrollPosition: function(transitionTime) {
|
||||||
|
var totalWidth = this.el.scrollWidth;
|
||||||
|
var totalHeight = this.el.offsetHeight;
|
||||||
|
var parentWidth = this.el.parentNode.offsetWidth;
|
||||||
|
var parentHeight = this.el.parentNode.offsetHeight;
|
||||||
|
|
||||||
|
var maxX = (-totalWidth + parentWidth);
|
||||||
|
var maxY = (-totalHeight + parentHeight);
|
||||||
|
|
||||||
|
//this._execEvent('scrollEnd');
|
||||||
|
var x = this.x, y = this.y;
|
||||||
|
|
||||||
|
var time = time || 0;
|
||||||
|
|
||||||
|
if ( !this.isHorizontalEnabled || this.x > 0 ) {
|
||||||
|
x = 0;
|
||||||
|
} else if ( this.x < maxX) {
|
||||||
|
x = maxX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !this.isVerticalEnabled || this.y > 0 ) {
|
||||||
|
y = 0;
|
||||||
|
} else if ( this.y < maxY) {
|
||||||
|
y = maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No change
|
||||||
|
if (x == this.x || y == this.y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.scrollTo(x, y, time, this.bounceTime);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
_wheel: function(e) {
|
_wheel: function(e) {
|
||||||
var wheelDeltaX, wheelDeltaY,
|
var wheelDeltaX, wheelDeltaY,
|
||||||
newX, newY,
|
newX, newY,
|
||||||
@ -2599,7 +2695,6 @@ window.ionic = {
|
|||||||
destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
|
destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
|
||||||
duration = speed / deceleration;
|
duration = speed / deceleration;
|
||||||
|
|
||||||
/*
|
|
||||||
// Check if the final destination needs to be rubber banded
|
// Check if the final destination needs to be rubber banded
|
||||||
if ( destination < lowerMargin ) {
|
if ( destination < lowerMargin ) {
|
||||||
// We have dragged too far down, snap back to the maximum
|
// We have dragged too far down, snap back to the maximum
|
||||||
@ -2608,11 +2703,10 @@ window.ionic = {
|
|||||||
duration = distance / speed;
|
duration = distance / speed;
|
||||||
} else if ( destination > 0 ) {
|
} else if ( destination > 0 ) {
|
||||||
// We have dragged too far up, snap back to 0
|
// We have dragged too far up, snap back to 0
|
||||||
destination = 0;//wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
|
destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
|
||||||
distance = Math.abs(current) + destination;
|
distance = Math.abs(current) + destination;
|
||||||
duration = distance / speed;
|
duration = distance / speed;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
console.log('Momentum: time:', time, 'speed:',speed, 'dest:',destination, 'dur:',duration);
|
console.log('Momentum: time:', time, 'speed:',speed, 'dest:',destination, 'dur:',duration);
|
||||||
return {
|
return {
|
||||||
@ -2621,59 +2715,23 @@ window.ionic = {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
_onTransitionEnd: function(e) {
|
||||||
* Scroll to the given X and Y point, taking
|
if (e.target != this.el) {
|
||||||
* the given amount of time, with the given
|
return;
|
||||||
* easing function defined as a CSS3 timing function.
|
|
||||||
*
|
|
||||||
* @param {float} the x position to scroll to (CURRENTLY NOT SUPPORTED!)
|
|
||||||
* @param {float} the y position to scroll to
|
|
||||||
* @param {float} the time to take scrolling to the new position
|
|
||||||
* @param {easing} the animation function to use for easing
|
|
||||||
*/
|
|
||||||
scrollTo: function(x, y, time, easing) {
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
easing = easing || 'cubic-bezier(0.1, 0.57, 0.1, 1)';
|
|
||||||
|
|
||||||
var el = this.el;
|
|
||||||
|
|
||||||
if(x !== null) {
|
|
||||||
this.x = x;
|
|
||||||
} else {
|
|
||||||
x = this.x;
|
|
||||||
}
|
|
||||||
if(y !== null) {
|
|
||||||
this.y = y;
|
|
||||||
} else {
|
|
||||||
y = this.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
el.style.webkitTransitionTimingFunction = easing;
|
this.el.style.webkitTransitionDuration = '0';
|
||||||
el.style.webkitTransitionDuration = time;
|
|
||||||
el.style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px, 0)';
|
|
||||||
|
|
||||||
// Start triggering events as the element scrolls from inertia.
|
if(this.wrapScrollPosition(this.bounceTime)) {
|
||||||
// This is important because we need to receive scroll events
|
ionic.trigger(_this.scrollEndEventName, {
|
||||||
// even after a "flick" and adjust, etc.
|
target: this.el,
|
||||||
this._momentumStepTimeout = setTimeout(function eventNotify() {
|
scrollLeft: this.x,
|
||||||
var scrollTop = parseFloat(_this.el.style.webkitTransform.replace('translate3d(', '').split(',')[1]) || 0;
|
scrollTop: this.y
|
||||||
ionic.trigger(_this.scrollEventName, {
|
|
||||||
target: _this.el,
|
|
||||||
scrollTop: -scrollTop
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if(_this._isDragging) {
|
|
||||||
_this._momentumStepTimeout = setTimeout(eventNotify, _this.inertialEventInterval);
|
|
||||||
}
|
}
|
||||||
}, this.inertialEventInterval)
|
|
||||||
|
|
||||||
console.log('TRANSITION ADDED!');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onScrollEnd: function() {
|
||||||
|
|
||||||
_endTransition: function() {
|
|
||||||
this._isDragging = false;
|
this._isDragging = false;
|
||||||
this._drag = null;
|
this._drag = null;
|
||||||
this.el.classList.remove('scroll-scrolling');
|
this.el.classList.remove('scroll-scrolling');
|
||||||
@ -2686,7 +2744,7 @@ window.ionic = {
|
|||||||
|
|
||||||
|
|
||||||
_initDrag: function() {
|
_initDrag: function() {
|
||||||
this._endTransition();
|
this._onScrollEnd();
|
||||||
this._isStopped = false;
|
this._isStopped = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2864,19 +2922,19 @@ window.ionic = {
|
|||||||
|
|
||||||
// Calculate how long we've been dragging for, with a max of 300ms
|
// Calculate how long we've been dragging for, with a max of 300ms
|
||||||
var duration = Date.now() - _this._drag.startTime;
|
var duration = Date.now() - _this._drag.startTime;
|
||||||
|
var time = 0;
|
||||||
|
var easing = '';
|
||||||
|
|
||||||
var newX = Math.round(_this.x);
|
var newX = Math.round(_this.x);
|
||||||
var newY = Math.round(_this.y);
|
var newY = Math.round(_this.y);
|
||||||
|
|
||||||
this.scrollTo(newX, newY);
|
_this.scrollTo(newX, newY);
|
||||||
|
|
||||||
var distanceX = Math.abs(newX - _this.startX);
|
|
||||||
var distanceY = Math.abs(newY - _this.startY);
|
|
||||||
this.endTime = Date.now();
|
|
||||||
|
|
||||||
//distanceX = Math.abs(newX - this.startX),
|
// Check if we just snap back to bounds
|
||||||
//var distanceY = Math.abs(newY - drag.startY);
|
if(_this.wrapScrollPosition(_this.bounceTime)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If the duration is within reasonable bounds, enable momentum scrolling
|
// If the duration is within reasonable bounds, enable momentum scrolling
|
||||||
if(duration < 300) {
|
if(duration < 300) {
|
||||||
@ -2886,8 +2944,9 @@ window.ionic = {
|
|||||||
newX = momentumX.destination;
|
newX = momentumX.destination;
|
||||||
newY = momentumY.destination;
|
newY = momentumY.destination;
|
||||||
|
|
||||||
var timeX = momentumX.duration;
|
// Calcualte the longest required time for the momentum animation and
|
||||||
var timeY = momentumY.duration;
|
// use that.
|
||||||
|
time = Math.max(momentumX.duration, momentumY.duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2908,11 +2967,17 @@ window.ionic = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var el = _this.el;
|
// If we've moved, we will need to scroll
|
||||||
|
if(newX != _this.x || newY != _this.y) {
|
||||||
|
|
||||||
// Turn on animation
|
// If the end position is out of bounds, change the function we use for easing
|
||||||
_this.scrollTo(newX, null, timeX);
|
// to get a different animation for the rubber banding
|
||||||
_this.scrollTo(null, newY, timeX);
|
if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) {
|
||||||
|
easing = EASING_FUNCTIONS.quadratic;
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.scrollTo(newX, newY, time, easing);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -3503,6 +3568,7 @@ ionic.views.Scroll.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If they enabled snapping (for page stuff), scroll to the next snap
|
||||||
if ( this.options.snap ) {
|
if ( this.options.snap ) {
|
||||||
var snap = this._nearestSnap(newX, newY);
|
var snap = this._nearestSnap(newX, newY);
|
||||||
this.currentPage = snap;
|
this.currentPage = snap;
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
(function(ionic) {
|
(function(ionic) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
var EASING_FUNCTIONS = {
|
||||||
|
quadratic: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)'
|
||||||
|
};
|
||||||
|
|
||||||
ionic.views.ScrollView = function(opts) {
|
ionic.views.ScrollView = function(opts) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
@ -10,6 +13,7 @@
|
|||||||
dragThreshold: 10,
|
dragThreshold: 10,
|
||||||
resistance: 2,
|
resistance: 2,
|
||||||
scrollEventName: 'momentumScrolled',
|
scrollEventName: 'momentumScrolled',
|
||||||
|
scrollEndEventName: 'momentumScrollEnd',
|
||||||
intertialEventInterval: 50,
|
intertialEventInterval: 50,
|
||||||
mouseWheelSpeed: 20,
|
mouseWheelSpeed: 20,
|
||||||
invertWheel: false,
|
invertWheel: false,
|
||||||
@ -38,8 +42,11 @@
|
|||||||
ionic.on('DOMMouseScroll', function(e) {
|
ionic.on('DOMMouseScroll', function(e) {
|
||||||
_this._wheel(e);
|
_this._wheel(e);
|
||||||
}, this.el);
|
}, this.el);
|
||||||
|
ionic.on(this.scrollEndEventName, function(e) {
|
||||||
|
_this._onScrollEnd(e);
|
||||||
|
}, this.el);
|
||||||
ionic.on('webkitTransitionEnd', function(e) {
|
ionic.on('webkitTransitionEnd', function(e) {
|
||||||
_this._endTransition();
|
_this._onTransitionEnd(e);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -48,6 +55,95 @@
|
|||||||
DECEL_RATE_FAST: 0.99,
|
DECEL_RATE_FAST: 0.99,
|
||||||
DECEL_RATE_SLOW: 0.996,
|
DECEL_RATE_SLOW: 0.996,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll to the given X and Y point, taking
|
||||||
|
* the given amount of time, with the given
|
||||||
|
* easing function defined as a CSS3 timing function.
|
||||||
|
*
|
||||||
|
* @param {float} the x position to scroll to (CURRENTLY NOT SUPPORTED!)
|
||||||
|
* @param {float} the y position to scroll to
|
||||||
|
* @param {float} the time to take scrolling to the new position
|
||||||
|
* @param {easing} the animation function to use for easing
|
||||||
|
*/
|
||||||
|
scrollTo: function(x, y, time, easing) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
easing = easing || 'cubic-bezier(0.1, 0.57, 0.1, 1)';
|
||||||
|
|
||||||
|
var el = this.el;
|
||||||
|
|
||||||
|
if(x !== null) {
|
||||||
|
this.x = x;
|
||||||
|
} else {
|
||||||
|
x = this.x;
|
||||||
|
}
|
||||||
|
if(y !== null) {
|
||||||
|
this.y = y;
|
||||||
|
} else {
|
||||||
|
y = this.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
el.style.webkitTransitionTimingFunction = easing;
|
||||||
|
el.style.webkitTransitionDuration = time;
|
||||||
|
el.style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px, 0)';
|
||||||
|
|
||||||
|
// Start triggering events as the element scrolls from inertia.
|
||||||
|
// This is important because we need to receive scroll events
|
||||||
|
// even after a "flick" and adjust, etc.
|
||||||
|
this._momentumStepTimeout = setTimeout(function eventNotify() {
|
||||||
|
var scrollTop = parseFloat(_this.el.style.webkitTransform.replace('translate3d(', '').split(',')[1]) || 0;
|
||||||
|
ionic.trigger(_this.scrollEventName, {
|
||||||
|
target: _this.el,
|
||||||
|
scrollTop: -scrollTop
|
||||||
|
});
|
||||||
|
|
||||||
|
if(_this._isDragging) {
|
||||||
|
_this._momentumStepTimeout = setTimeout(eventNotify, _this.inertialEventInterval);
|
||||||
|
}
|
||||||
|
}, this.inertialEventInterval)
|
||||||
|
|
||||||
|
console.log('TRANSITION ADDED!');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the scroll position is outside the current bounds,
|
||||||
|
* animate it back.
|
||||||
|
*/
|
||||||
|
wrapScrollPosition: function(transitionTime) {
|
||||||
|
var totalWidth = this.el.scrollWidth;
|
||||||
|
var totalHeight = this.el.offsetHeight;
|
||||||
|
var parentWidth = this.el.parentNode.offsetWidth;
|
||||||
|
var parentHeight = this.el.parentNode.offsetHeight;
|
||||||
|
|
||||||
|
var maxX = (-totalWidth + parentWidth);
|
||||||
|
var maxY = (-totalHeight + parentHeight);
|
||||||
|
|
||||||
|
//this._execEvent('scrollEnd');
|
||||||
|
var x = this.x, y = this.y;
|
||||||
|
|
||||||
|
var time = time || 0;
|
||||||
|
|
||||||
|
if ( !this.isHorizontalEnabled || this.x > 0 ) {
|
||||||
|
x = 0;
|
||||||
|
} else if ( this.x < maxX) {
|
||||||
|
x = maxX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !this.isVerticalEnabled || this.y > 0 ) {
|
||||||
|
y = 0;
|
||||||
|
} else if ( this.y < maxY) {
|
||||||
|
y = maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No change
|
||||||
|
if (x == this.x || y == this.y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.scrollTo(x, y, time, this.bounceTime);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
_wheel: function(e) {
|
_wheel: function(e) {
|
||||||
var wheelDeltaX, wheelDeltaY,
|
var wheelDeltaX, wheelDeltaY,
|
||||||
newX, newY,
|
newX, newY,
|
||||||
@ -116,7 +212,6 @@
|
|||||||
destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
|
destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
|
||||||
duration = speed / deceleration;
|
duration = speed / deceleration;
|
||||||
|
|
||||||
/*
|
|
||||||
// Check if the final destination needs to be rubber banded
|
// Check if the final destination needs to be rubber banded
|
||||||
if ( destination < lowerMargin ) {
|
if ( destination < lowerMargin ) {
|
||||||
// We have dragged too far down, snap back to the maximum
|
// We have dragged too far down, snap back to the maximum
|
||||||
@ -125,11 +220,10 @@
|
|||||||
duration = distance / speed;
|
duration = distance / speed;
|
||||||
} else if ( destination > 0 ) {
|
} else if ( destination > 0 ) {
|
||||||
// We have dragged too far up, snap back to 0
|
// We have dragged too far up, snap back to 0
|
||||||
destination = 0;//wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
|
destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
|
||||||
distance = Math.abs(current) + destination;
|
distance = Math.abs(current) + destination;
|
||||||
duration = distance / speed;
|
duration = distance / speed;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
console.log('Momentum: time:', time, 'speed:',speed, 'dest:',destination, 'dur:',duration);
|
console.log('Momentum: time:', time, 'speed:',speed, 'dest:',destination, 'dur:',duration);
|
||||||
return {
|
return {
|
||||||
@ -138,59 +232,23 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
_onTransitionEnd: function(e) {
|
||||||
* Scroll to the given X and Y point, taking
|
if (e.target != this.el) {
|
||||||
* the given amount of time, with the given
|
return;
|
||||||
* easing function defined as a CSS3 timing function.
|
|
||||||
*
|
|
||||||
* @param {float} the x position to scroll to (CURRENTLY NOT SUPPORTED!)
|
|
||||||
* @param {float} the y position to scroll to
|
|
||||||
* @param {float} the time to take scrolling to the new position
|
|
||||||
* @param {easing} the animation function to use for easing
|
|
||||||
*/
|
|
||||||
scrollTo: function(x, y, time, easing) {
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
easing = easing || 'cubic-bezier(0.1, 0.57, 0.1, 1)';
|
|
||||||
|
|
||||||
var el = this.el;
|
|
||||||
|
|
||||||
if(x !== null) {
|
|
||||||
this.x = x;
|
|
||||||
} else {
|
|
||||||
x = this.x;
|
|
||||||
}
|
|
||||||
if(y !== null) {
|
|
||||||
this.y = y;
|
|
||||||
} else {
|
|
||||||
y = this.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
el.style.webkitTransitionTimingFunction = easing;
|
this.el.style.webkitTransitionDuration = '0';
|
||||||
el.style.webkitTransitionDuration = time;
|
|
||||||
el.style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px, 0)';
|
|
||||||
|
|
||||||
// Start triggering events as the element scrolls from inertia.
|
if(this.wrapScrollPosition(this.bounceTime)) {
|
||||||
// This is important because we need to receive scroll events
|
ionic.trigger(_this.scrollEndEventName, {
|
||||||
// even after a "flick" and adjust, etc.
|
target: this.el,
|
||||||
this._momentumStepTimeout = setTimeout(function eventNotify() {
|
scrollLeft: this.x,
|
||||||
var scrollTop = parseFloat(_this.el.style.webkitTransform.replace('translate3d(', '').split(',')[1]) || 0;
|
scrollTop: this.y
|
||||||
ionic.trigger(_this.scrollEventName, {
|
|
||||||
target: _this.el,
|
|
||||||
scrollTop: -scrollTop
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if(_this._isDragging) {
|
|
||||||
_this._momentumStepTimeout = setTimeout(eventNotify, _this.inertialEventInterval);
|
|
||||||
}
|
}
|
||||||
}, this.inertialEventInterval)
|
|
||||||
|
|
||||||
console.log('TRANSITION ADDED!');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onScrollEnd: function() {
|
||||||
|
|
||||||
_endTransition: function() {
|
|
||||||
this._isDragging = false;
|
this._isDragging = false;
|
||||||
this._drag = null;
|
this._drag = null;
|
||||||
this.el.classList.remove('scroll-scrolling');
|
this.el.classList.remove('scroll-scrolling');
|
||||||
@ -203,7 +261,7 @@
|
|||||||
|
|
||||||
|
|
||||||
_initDrag: function() {
|
_initDrag: function() {
|
||||||
this._endTransition();
|
this._onScrollEnd();
|
||||||
this._isStopped = false;
|
this._isStopped = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -381,19 +439,19 @@
|
|||||||
|
|
||||||
// Calculate how long we've been dragging for, with a max of 300ms
|
// Calculate how long we've been dragging for, with a max of 300ms
|
||||||
var duration = Date.now() - _this._drag.startTime;
|
var duration = Date.now() - _this._drag.startTime;
|
||||||
|
var time = 0;
|
||||||
|
var easing = '';
|
||||||
|
|
||||||
var newX = Math.round(_this.x);
|
var newX = Math.round(_this.x);
|
||||||
var newY = Math.round(_this.y);
|
var newY = Math.round(_this.y);
|
||||||
|
|
||||||
this.scrollTo(newX, newY);
|
_this.scrollTo(newX, newY);
|
||||||
|
|
||||||
var distanceX = Math.abs(newX - _this.startX);
|
|
||||||
var distanceY = Math.abs(newY - _this.startY);
|
|
||||||
this.endTime = Date.now();
|
|
||||||
|
|
||||||
//distanceX = Math.abs(newX - this.startX),
|
// Check if we just snap back to bounds
|
||||||
//var distanceY = Math.abs(newY - drag.startY);
|
if(_this.wrapScrollPosition(_this.bounceTime)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If the duration is within reasonable bounds, enable momentum scrolling
|
// If the duration is within reasonable bounds, enable momentum scrolling
|
||||||
if(duration < 300) {
|
if(duration < 300) {
|
||||||
@ -403,8 +461,9 @@
|
|||||||
newX = momentumX.destination;
|
newX = momentumX.destination;
|
||||||
newY = momentumY.destination;
|
newY = momentumY.destination;
|
||||||
|
|
||||||
var timeX = momentumX.duration;
|
// Calcualte the longest required time for the momentum animation and
|
||||||
var timeY = momentumY.duration;
|
// use that.
|
||||||
|
time = Math.max(momentumX.duration, momentumY.duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -425,11 +484,17 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var el = _this.el;
|
// If we've moved, we will need to scroll
|
||||||
|
if(newX != _this.x || newY != _this.y) {
|
||||||
|
|
||||||
// Turn on animation
|
// If the end position is out of bounds, change the function we use for easing
|
||||||
_this.scrollTo(newX, null, timeX);
|
// to get a different animation for the rubber banding
|
||||||
_this.scrollTo(null, newY, timeX);
|
if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) {
|
||||||
|
easing = EASING_FUNCTIONS.quadratic;
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.scrollTo(newX, newY, time, easing);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -582,6 +582,7 @@ ionic.views.Scroll.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If they enabled snapping (for page stuff), scroll to the next snap
|
||||||
if ( this.options.snap ) {
|
if ( this.options.snap ) {
|
||||||
var snap = this._nearestSnap(newX, newY);
|
var snap = this._nearestSnap(newX, newY);
|
||||||
this.currentPage = snap;
|
this.currentPage = snap;
|
||||||
|
|||||||
Reference in New Issue
Block a user