Scroll view kind of supports mouse wheel

This commit is contained in:
Max Lynch
2013-10-24 22:02:25 -05:00
parent 11af531010
commit e77f041391
2 changed files with 162 additions and 18 deletions

90
dist/js/ionic.js vendored
View File

@ -2494,7 +2494,10 @@ window.ionic = {
resistance: 2, resistance: 2,
scrollEventName: 'momentumScrolled', scrollEventName: 'momentumScrolled',
intertialEventInterval: 50, intertialEventInterval: 50,
mouseWheelSpeed: 20,
invertWheel: false,
isVerticalEnabled: true,
isHorizontalEnabled: false,
bounceTime: 600 //how long to take when bouncing back in a rubber band bounceTime: 600 //how long to take when bouncing back in a rubber band
}); });
@ -2502,6 +2505,9 @@ window.ionic = {
this.el = opts.el; this.el = opts.el;
this.y = 0;
this.x = 0;
// Listen for drag and release events // Listen for drag and release events
ionic.onGesture('drag', function(e) { ionic.onGesture('drag', function(e) {
_this._handleDrag(e); _this._handleDrag(e);
@ -2509,6 +2515,12 @@ window.ionic = {
ionic.onGesture('release', function(e) { ionic.onGesture('release', function(e) {
_this._handleEndDrag(e); _this._handleEndDrag(e);
}, this.el); }, this.el);
ionic.on('mousewheel', function(e) {
_this._wheel(e);
}, this.el);
ionic.on('DOMMouseScroll', function(e) {
_this._wheel(e);
}, this.el);
ionic.on('webkitTransitionEnd', function(e) { ionic.on('webkitTransitionEnd', function(e) {
_this._endTransition(); _this._endTransition();
}); });
@ -2519,6 +2531,63 @@ window.ionic = {
DECEL_RATE_FAST: 0.99, DECEL_RATE_FAST: 0.99,
DECEL_RATE_SLOW: 0.996, DECEL_RATE_SLOW: 0.996,
_wheel: function(e) {
var wheelDeltaX, wheelDeltaY,
newX, newY,
that = this;
var totalHeight = this.el.offsetHeight;
var parentHeight = this.el.parentNode.offsetHeight;
var maxY = totalHeight - parentHeight;
var maxX = 0;
// Execute the scrollEnd event after 400ms the wheel stopped scrolling
clearTimeout(this.wheelTimeout);
this.wheelTimeout = setTimeout(function () {
//that._execEvent('scrollEnd');
}, 400);
e.preventDefault();
if('wheelDeltaX' in e) {
wheelDeltaX = e.wheelDeltaX / 120;
wheelDeltaY = e.wheelDeltaY / 120;
} else if ('wheelDelta' in e) {
wheelDeltaX = wheelDeltaY = e.wheelDelta / 120;
} else if ('detail' in e) {
wheelDeltaX = wheelDeltaY = -e.detail / 3;
} else {
return;
}
wheelDeltaX *= this.mouseWheelSpeed;
wheelDeltaY *= this.mouseWheelSpeed;
if(!this.isVerticalEnabled) {
wheelDeltaX = wheelDeltaY;
wheelDeltaY = 0;
}
newX = this.x + (this.isHorizontalEnabled ? wheelDeltaX * (this.invertWheel ? -1 : 1) : 0);
newY = this.y + (this.isVerticalEnabled ? wheelDeltaY * (this.invertWheel ? -1 : 1) : 0);
/*
if(newX > 0) {
newX = 0;
} else if (newX < this.maxScrollX) {
newX = this.maxScrollX;
}
*/
if(newY > 0) {
newY = 0;
} else if (newY < -maxY) {
newY = maxY;
}
this.scrollTo(0, newY, 0);
},
_getMomentum: function (current, start, time, lowerMargin, wrapperSize) { _getMomentum: function (current, start, time, lowerMargin, wrapperSize) {
var distance = current - start, var distance = current - start,
speed = Math.abs(distance) / time, speed = Math.abs(distance) / time,
@ -2567,6 +2636,9 @@ window.ionic = {
var el = this.el; var el = this.el;
this.x = x;
this.y = y;
el.style.webkitTransitionTimingFunction = easing; el.style.webkitTransitionTimingFunction = easing;
el.style.webkitTransitionDuration = time; el.style.webkitTransitionDuration = time;
el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)'; el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)';
@ -2676,24 +2748,24 @@ window.ionic = {
var timestamp = Date.now(); var timestamp = Date.now();
// Calculate the new Y point for the container // Calculate the new Y point for the container
var newY = drag.y + deltaY; var newY = _this.y + deltaY;
// Check if the dragging is beyond the bottom or top // Check if the dragging is beyond the bottom or top
if(newY > 0 || (-newY + parentHeight) > totalHeight) { if(newY > 0 || (-newY + parentHeight) > totalHeight) {
// Rubber band // Rubber band
newY = drag.y + deltaY / 3;//(-_this.resistance); newY = _this.y + deltaY / 3;//(-_this.resistance);
} }
// Update the new translated Y point of the container // Update the new translated Y point of the container
_this.el.style.webkitTransform = 'translate3d(0,' + newY + 'px, 0)'; _this.el.style.webkitTransform = 'translate3d(0,' + newY + 'px, 0)';
drag.y = newY; _this.y = newY;
// Check if we need to reset the drag initial states if we've // Check if we need to reset the drag initial states if we've
// been dragging for a bit // been dragging for a bit
if(timestamp - drag.startTime > 300) { if(timestamp - drag.startTime > 300) {
console.log('Resetting timer'); console.log('Resetting timer');
drag.startTime = timestamp; drag.startTime = timestamp;
drag.startY = drag.y; drag.startY = _this.y;
} }
ionic.trigger(_this.scrollEventName, { ionic.trigger(_this.scrollEventName, {
@ -2753,20 +2825,20 @@ window.ionic = {
//var newX = Math.round(this.x), //var newX = Math.round(this.x),
var newY = Math.round(drag.y); var newY = Math.round(_this.y);
//distanceX = Math.abs(newX - this.startX), //distanceX = Math.abs(newX - this.startX),
//var distanceY = Math.abs(newY - drag.startY); //var distanceY = Math.abs(newY - drag.startY);
var momentum = _this._getMomentum(drag.y, drag.startY, duration, parentHeight - totalHeight, parentHeight); var momentum = _this._getMomentum(_this.y, drag.startY, duration, parentHeight - totalHeight, parentHeight);
//var newX = momentumX.destination; //var newX = momentumX.destination;
newY = momentum.destination; newY = momentum.destination;
var time = momentum.duration; var time = momentum.duration;
if(drag.y > 0) { if(_this.y > 0) {
_this.scrollTo(0, 0, _this.bounceTime); _this.scrollTo(0, 0, _this.bounceTime);
return; return;
} else if ((-drag.y + parentHeight) > totalHeight) { } else if ((-_this.y + parentHeight) > totalHeight) {
_this.scrollTo(0, totalHeight - parentHeight, _this.bounceTime); _this.scrollTo(0, totalHeight - parentHeight, _this.bounceTime);
return; return;
} }

View File

@ -11,7 +11,10 @@
resistance: 2, resistance: 2,
scrollEventName: 'momentumScrolled', scrollEventName: 'momentumScrolled',
intertialEventInterval: 50, intertialEventInterval: 50,
mouseWheelSpeed: 20,
invertWheel: false,
isVerticalEnabled: true,
isHorizontalEnabled: false,
bounceTime: 600 //how long to take when bouncing back in a rubber band bounceTime: 600 //how long to take when bouncing back in a rubber band
}); });
@ -19,6 +22,9 @@
this.el = opts.el; this.el = opts.el;
this.y = 0;
this.x = 0;
// Listen for drag and release events // Listen for drag and release events
ionic.onGesture('drag', function(e) { ionic.onGesture('drag', function(e) {
_this._handleDrag(e); _this._handleDrag(e);
@ -26,6 +32,12 @@
ionic.onGesture('release', function(e) { ionic.onGesture('release', function(e) {
_this._handleEndDrag(e); _this._handleEndDrag(e);
}, this.el); }, this.el);
ionic.on('mousewheel', function(e) {
_this._wheel(e);
}, this.el);
ionic.on('DOMMouseScroll', function(e) {
_this._wheel(e);
}, this.el);
ionic.on('webkitTransitionEnd', function(e) { ionic.on('webkitTransitionEnd', function(e) {
_this._endTransition(); _this._endTransition();
}); });
@ -36,6 +48,63 @@
DECEL_RATE_FAST: 0.99, DECEL_RATE_FAST: 0.99,
DECEL_RATE_SLOW: 0.996, DECEL_RATE_SLOW: 0.996,
_wheel: function(e) {
var wheelDeltaX, wheelDeltaY,
newX, newY,
that = this;
var totalHeight = this.el.offsetHeight;
var parentHeight = this.el.parentNode.offsetHeight;
var maxY = totalHeight - parentHeight;
var maxX = 0;
// Execute the scrollEnd event after 400ms the wheel stopped scrolling
clearTimeout(this.wheelTimeout);
this.wheelTimeout = setTimeout(function () {
//that._execEvent('scrollEnd');
}, 400);
e.preventDefault();
if('wheelDeltaX' in e) {
wheelDeltaX = e.wheelDeltaX / 120;
wheelDeltaY = e.wheelDeltaY / 120;
} else if ('wheelDelta' in e) {
wheelDeltaX = wheelDeltaY = e.wheelDelta / 120;
} else if ('detail' in e) {
wheelDeltaX = wheelDeltaY = -e.detail / 3;
} else {
return;
}
wheelDeltaX *= this.mouseWheelSpeed;
wheelDeltaY *= this.mouseWheelSpeed;
if(!this.isVerticalEnabled) {
wheelDeltaX = wheelDeltaY;
wheelDeltaY = 0;
}
newX = this.x + (this.isHorizontalEnabled ? wheelDeltaX * (this.invertWheel ? -1 : 1) : 0);
newY = this.y + (this.isVerticalEnabled ? wheelDeltaY * (this.invertWheel ? -1 : 1) : 0);
/*
if(newX > 0) {
newX = 0;
} else if (newX < this.maxScrollX) {
newX = this.maxScrollX;
}
*/
if(newY > 0) {
newY = 0;
} else if (newY < -maxY) {
newY = maxY;
}
this.scrollTo(0, newY, 0);
},
_getMomentum: function (current, start, time, lowerMargin, wrapperSize) { _getMomentum: function (current, start, time, lowerMargin, wrapperSize) {
var distance = current - start, var distance = current - start,
speed = Math.abs(distance) / time, speed = Math.abs(distance) / time,
@ -84,6 +153,9 @@
var el = this.el; var el = this.el;
this.x = x;
this.y = y;
el.style.webkitTransitionTimingFunction = easing; el.style.webkitTransitionTimingFunction = easing;
el.style.webkitTransitionDuration = time; el.style.webkitTransitionDuration = time;
el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)'; el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)';
@ -193,24 +265,24 @@
var timestamp = Date.now(); var timestamp = Date.now();
// Calculate the new Y point for the container // Calculate the new Y point for the container
var newY = drag.y + deltaY; var newY = _this.y + deltaY;
// Check if the dragging is beyond the bottom or top // Check if the dragging is beyond the bottom or top
if(newY > 0 || (-newY + parentHeight) > totalHeight) { if(newY > 0 || (-newY + parentHeight) > totalHeight) {
// Rubber band // Rubber band
newY = drag.y + deltaY / 3;//(-_this.resistance); newY = _this.y + deltaY / 3;//(-_this.resistance);
} }
// Update the new translated Y point of the container // Update the new translated Y point of the container
_this.el.style.webkitTransform = 'translate3d(0,' + newY + 'px, 0)'; _this.el.style.webkitTransform = 'translate3d(0,' + newY + 'px, 0)';
drag.y = newY; _this.y = newY;
// Check if we need to reset the drag initial states if we've // Check if we need to reset the drag initial states if we've
// been dragging for a bit // been dragging for a bit
if(timestamp - drag.startTime > 300) { if(timestamp - drag.startTime > 300) {
console.log('Resetting timer'); console.log('Resetting timer');
drag.startTime = timestamp; drag.startTime = timestamp;
drag.startY = drag.y; drag.startY = _this.y;
} }
ionic.trigger(_this.scrollEventName, { ionic.trigger(_this.scrollEventName, {
@ -270,20 +342,20 @@
//var newX = Math.round(this.x), //var newX = Math.round(this.x),
var newY = Math.round(drag.y); var newY = Math.round(_this.y);
//distanceX = Math.abs(newX - this.startX), //distanceX = Math.abs(newX - this.startX),
//var distanceY = Math.abs(newY - drag.startY); //var distanceY = Math.abs(newY - drag.startY);
var momentum = _this._getMomentum(drag.y, drag.startY, duration, parentHeight - totalHeight, parentHeight); var momentum = _this._getMomentum(_this.y, drag.startY, duration, parentHeight - totalHeight, parentHeight);
//var newX = momentumX.destination; //var newX = momentumX.destination;
newY = momentum.destination; newY = momentum.destination;
var time = momentum.duration; var time = momentum.duration;
if(drag.y > 0) { if(_this.y > 0) {
_this.scrollTo(0, 0, _this.bounceTime); _this.scrollTo(0, 0, _this.bounceTime);
return; return;
} else if ((-drag.y + parentHeight) > totalHeight) { } else if ((-_this.y + parentHeight) > totalHeight) {
_this.scrollTo(0, totalHeight - parentHeight, _this.bounceTime); _this.scrollTo(0, totalHeight - parentHeight, _this.bounceTime);
return; return;
} }