mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-08 15:51:16 +08:00
Working scroll view, a little buggy still
This commit is contained in:
135
dist/js/ionic.js
vendored
135
dist/js/ionic.js
vendored
@ -2490,11 +2490,15 @@ window.ionic = {
|
|||||||
|
|
||||||
// Extend the options with our defaults
|
// Extend the options with our defaults
|
||||||
ionic.Utils.extend(opts, {
|
ionic.Utils.extend(opts, {
|
||||||
decelerationRate: ionic.views.Scroll.prototype.DECEL_RATE_NORMAL
|
decelerationRate: ionic.views.Scroll.prototype.DECEL_RATE_NORMAL,
|
||||||
|
dragThresholdY: 10,
|
||||||
|
resistance: 2
|
||||||
});
|
});
|
||||||
|
|
||||||
this.el = opts.el;
|
this.el = opts.el;
|
||||||
this.decelerationRate = opts.decelerationRate
|
this.decelerationRate = opts.decelerationRate;
|
||||||
|
this.dragThresholdY = opts.dragThresholdY;
|
||||||
|
this.resistance = opts.resistance;
|
||||||
|
|
||||||
// Listen for drag and release events
|
// Listen for drag and release events
|
||||||
window.ionic.onGesture('drag', function(e) {
|
window.ionic.onGesture('drag', function(e) {
|
||||||
@ -2509,9 +2513,33 @@ window.ionic = {
|
|||||||
DECEL_RATE_NORMAL: 0.998,
|
DECEL_RATE_NORMAL: 0.998,
|
||||||
DECEL_RATE_FAST: 0.99,
|
DECEL_RATE_FAST: 0.99,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
easing = easing || 'cubic-bezier(0.1, 0.57, 0.1, 1)';
|
||||||
|
|
||||||
|
var el = this.el;
|
||||||
|
|
||||||
|
el.style.webkitTransitionTimingFunction = easing;
|
||||||
|
el.style.webkitTransitionDuration = time;
|
||||||
|
el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)';
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
_initDrag: function() {
|
_initDrag: function() {
|
||||||
this._isDragging = false;
|
this._isDragging = false;
|
||||||
this._drag = null;
|
this._drag = null;
|
||||||
|
this.el.classList.remove('scroll-scrolling');
|
||||||
|
this.el.style.webkitTransitionDuration = '0';
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2523,12 +2551,12 @@ window.ionic = {
|
|||||||
|
|
||||||
this._initDrag();
|
this._initDrag();
|
||||||
|
|
||||||
this.el.classList.remove('scroll-scrolling');
|
var scrollTop = parseFloat(this.el.style.webkitTransform.replace('translate3d(', '').split(',')[1]) || 0;
|
||||||
|
|
||||||
var scrollTop = parseFloat(this.el.scrollTop);
|
|
||||||
|
|
||||||
this._drag = {
|
this._drag = {
|
||||||
startY: scrollTop
|
startY: scrollTop,
|
||||||
|
resist: 1,
|
||||||
|
startTime: +(new Date)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2545,24 +2573,99 @@ window.ionic = {
|
|||||||
if(!_this._drag) {
|
if(!_this._drag) {
|
||||||
_this._startDrag(e);
|
_this._startDrag(e);
|
||||||
}
|
}
|
||||||
console.log('At scroll top', _this.el.scrollTop, e.gesture.deltaY);
|
|
||||||
|
|
||||||
_this.el.style.webkitTransform = 'translate3d(0,' + e.gesture.deltaY + 'px, 0)';
|
// Stop any default events during the drag
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Check if we should start dragging. Check if we've dragged past the threshold.
|
||||||
|
if(!_this._isDragging && (Math.abs(e.gesture.deltaY) > _this.dragThresholdY)) {
|
||||||
|
_this._isDragging = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_this._isDragging) {
|
||||||
|
var totalHeight = _this.el.offsetHeight;
|
||||||
|
var parentHeight = _this.el.parentNode.offsetHeight;
|
||||||
|
|
||||||
|
var newY = _this._drag.startY + e.gesture.deltaY;
|
||||||
|
|
||||||
|
// Check if the dragging is beyond the bottom or top
|
||||||
|
if(newY > 0 || (-newY + parentHeight) > totalHeight) {
|
||||||
|
// Rubber band
|
||||||
|
newY = newY + e.gesture.deltaY / (-_this.resistance);
|
||||||
|
}
|
||||||
|
// Update the new translated Y point of the container
|
||||||
|
_this.el.style.webkitTransform = 'translate3d(0,' + newY + 'px, 0)';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleEndDrag: function(e) {
|
_handleEndDrag: function(e) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
window.requestAnimationFrame(function() {
|
// We didn't have a drag, so just init and leave
|
||||||
|
if(!_this._drag) {
|
||||||
// We didn't have a drag, so just init and leave
|
_this._initDrag();
|
||||||
if(!_this._drag) {
|
return;
|
||||||
_this._initDrag();
|
}
|
||||||
return;
|
|
||||||
|
// Animate to the finishing point
|
||||||
|
_this._animateToStop(e);
|
||||||
|
// Cleanup
|
||||||
|
_this._initDrag();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
_animateToStop: function(e) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
var totalHeight = this.el.offsetHeight;
|
||||||
|
var parentHeight = this.el.parentNode.offsetHeight;
|
||||||
|
var scrollTop = parseFloat(this.el.style.webkitTransform.replace('translate3d(', '').split(',')[1]) || 0;
|
||||||
|
var duration = +(new Date) - this._drag.startTime;
|
||||||
|
|
||||||
|
var newY = scrollTop;
|
||||||
|
|
||||||
|
if(e.gesture.velocityY) {
|
||||||
|
// Get the final resting point
|
||||||
|
var vy = e.gesture.velocityY;
|
||||||
|
var speed = Math.abs(e.gesture.deltaY) / duration;
|
||||||
|
//newY = newY + (vy * vy) / (0.05 * this.decelerationRate);
|
||||||
|
|
||||||
|
var destination = newY + ( speed * speed ) / ( 2 * (1-_this.decelerationRate)) * ( e.gesture.deltaY < 0 ? -1 : 1 );
|
||||||
|
var dur = speed / (1-_this.decelerationRate);
|
||||||
|
|
||||||
|
if((-destination + parentHeight) > totalHeight) {
|
||||||
|
destination = -(totalHeight - parentHeight);
|
||||||
|
} else if(destination > 0) {
|
||||||
|
destination = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_this._initDrag();
|
console.log('Ending at velocity and point', speed, vy, destination, dur);
|
||||||
});
|
|
||||||
|
|
||||||
|
var el = this.el;
|
||||||
|
|
||||||
|
window.requestAnimationFrame(function() {
|
||||||
|
_this.scrollTo(0, destination, dur);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Check if the dragging is beyond the bottom or top
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
setTimeout(function() {
|
||||||
|
window.requestAnimationFrame(function() {
|
||||||
|
_this.el.style.webkitTransform = 'translate3d(0,' + newY + 'px, 0)';
|
||||||
|
});
|
||||||
|
}, 50);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Turn on animation
|
||||||
|
this.el.classList.add('scroll-scrolling');
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -6,11 +6,15 @@
|
|||||||
|
|
||||||
// Extend the options with our defaults
|
// Extend the options with our defaults
|
||||||
ionic.Utils.extend(opts, {
|
ionic.Utils.extend(opts, {
|
||||||
decelerationRate: ionic.views.Scroll.prototype.DECEL_RATE_NORMAL
|
decelerationRate: ionic.views.Scroll.prototype.DECEL_RATE_NORMAL,
|
||||||
|
dragThresholdY: 10,
|
||||||
|
resistance: 2
|
||||||
});
|
});
|
||||||
|
|
||||||
this.el = opts.el;
|
this.el = opts.el;
|
||||||
this.decelerationRate = opts.decelerationRate
|
this.decelerationRate = opts.decelerationRate;
|
||||||
|
this.dragThresholdY = opts.dragThresholdY;
|
||||||
|
this.resistance = opts.resistance;
|
||||||
|
|
||||||
// Listen for drag and release events
|
// Listen for drag and release events
|
||||||
window.ionic.onGesture('drag', function(e) {
|
window.ionic.onGesture('drag', function(e) {
|
||||||
@ -25,9 +29,33 @@
|
|||||||
DECEL_RATE_NORMAL: 0.998,
|
DECEL_RATE_NORMAL: 0.998,
|
||||||
DECEL_RATE_FAST: 0.99,
|
DECEL_RATE_FAST: 0.99,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
easing = easing || 'cubic-bezier(0.1, 0.57, 0.1, 1)';
|
||||||
|
|
||||||
|
var el = this.el;
|
||||||
|
|
||||||
|
el.style.webkitTransitionTimingFunction = easing;
|
||||||
|
el.style.webkitTransitionDuration = time;
|
||||||
|
el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)';
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
_initDrag: function() {
|
_initDrag: function() {
|
||||||
this._isDragging = false;
|
this._isDragging = false;
|
||||||
this._drag = null;
|
this._drag = null;
|
||||||
|
this.el.classList.remove('scroll-scrolling');
|
||||||
|
this.el.style.webkitTransitionDuration = '0';
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,12 +67,12 @@
|
|||||||
|
|
||||||
this._initDrag();
|
this._initDrag();
|
||||||
|
|
||||||
this.el.classList.remove('scroll-scrolling');
|
var scrollTop = parseFloat(this.el.style.webkitTransform.replace('translate3d(', '').split(',')[1]) || 0;
|
||||||
|
|
||||||
var scrollTop = parseFloat(this.el.scrollTop);
|
|
||||||
|
|
||||||
this._drag = {
|
this._drag = {
|
||||||
startY: scrollTop
|
startY: scrollTop,
|
||||||
|
resist: 1,
|
||||||
|
startTime: +(new Date)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -61,24 +89,99 @@
|
|||||||
if(!_this._drag) {
|
if(!_this._drag) {
|
||||||
_this._startDrag(e);
|
_this._startDrag(e);
|
||||||
}
|
}
|
||||||
console.log('At scroll top', _this.el.scrollTop, e.gesture.deltaY);
|
|
||||||
|
|
||||||
_this.el.style.webkitTransform = 'translate3d(0,' + e.gesture.deltaY + 'px, 0)';
|
// Stop any default events during the drag
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Check if we should start dragging. Check if we've dragged past the threshold.
|
||||||
|
if(!_this._isDragging && (Math.abs(e.gesture.deltaY) > _this.dragThresholdY)) {
|
||||||
|
_this._isDragging = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_this._isDragging) {
|
||||||
|
var totalHeight = _this.el.offsetHeight;
|
||||||
|
var parentHeight = _this.el.parentNode.offsetHeight;
|
||||||
|
|
||||||
|
var newY = _this._drag.startY + e.gesture.deltaY;
|
||||||
|
|
||||||
|
// Check if the dragging is beyond the bottom or top
|
||||||
|
if(newY > 0 || (-newY + parentHeight) > totalHeight) {
|
||||||
|
// Rubber band
|
||||||
|
newY = newY + e.gesture.deltaY / (-_this.resistance);
|
||||||
|
}
|
||||||
|
// Update the new translated Y point of the container
|
||||||
|
_this.el.style.webkitTransform = 'translate3d(0,' + newY + 'px, 0)';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleEndDrag: function(e) {
|
_handleEndDrag: function(e) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
window.requestAnimationFrame(function() {
|
// We didn't have a drag, so just init and leave
|
||||||
|
if(!_this._drag) {
|
||||||
// We didn't have a drag, so just init and leave
|
_this._initDrag();
|
||||||
if(!_this._drag) {
|
return;
|
||||||
_this._initDrag();
|
}
|
||||||
return;
|
|
||||||
|
// Animate to the finishing point
|
||||||
|
_this._animateToStop(e);
|
||||||
|
// Cleanup
|
||||||
|
_this._initDrag();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
_animateToStop: function(e) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
var totalHeight = this.el.offsetHeight;
|
||||||
|
var parentHeight = this.el.parentNode.offsetHeight;
|
||||||
|
var scrollTop = parseFloat(this.el.style.webkitTransform.replace('translate3d(', '').split(',')[1]) || 0;
|
||||||
|
var duration = +(new Date) - this._drag.startTime;
|
||||||
|
|
||||||
|
var newY = scrollTop;
|
||||||
|
|
||||||
|
if(e.gesture.velocityY) {
|
||||||
|
// Get the final resting point
|
||||||
|
var vy = e.gesture.velocityY;
|
||||||
|
var speed = Math.abs(e.gesture.deltaY) / duration;
|
||||||
|
//newY = newY + (vy * vy) / (0.05 * this.decelerationRate);
|
||||||
|
|
||||||
|
var destination = newY + ( speed * speed ) / ( 2 * (1-_this.decelerationRate)) * ( e.gesture.deltaY < 0 ? -1 : 1 );
|
||||||
|
var dur = speed / (1-_this.decelerationRate);
|
||||||
|
|
||||||
|
if((-destination + parentHeight) > totalHeight) {
|
||||||
|
destination = -(totalHeight - parentHeight);
|
||||||
|
} else if(destination > 0) {
|
||||||
|
destination = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_this._initDrag();
|
console.log('Ending at velocity and point', speed, vy, destination, dur);
|
||||||
});
|
|
||||||
|
|
||||||
|
var el = this.el;
|
||||||
|
|
||||||
|
window.requestAnimationFrame(function() {
|
||||||
|
_this.scrollTo(0, destination, dur);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Check if the dragging is beyond the bottom or top
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
setTimeout(function() {
|
||||||
|
window.requestAnimationFrame(function() {
|
||||||
|
_this.el.style.webkitTransform = 'translate3d(0,' + newY + 'px, 0)';
|
||||||
|
});
|
||||||
|
}, 50);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Turn on animation
|
||||||
|
this.el.classList.add('scroll-scrolling');
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -6,23 +6,37 @@
|
|||||||
<!-- Sets initial viewport load and disables zooming -->
|
<!-- Sets initial viewport load and disables zooming -->
|
||||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
|
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
<link href="../dist/css/ionic.css" rel="stylesheet">
|
<link href="../dist/css/ionic.css" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
#filler {
|
||||||
|
border-top: 10px solid red;
|
||||||
|
border-bottom: 10px solid red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<section class="view-full">
|
||||||
<section>
|
|
||||||
<div class="bar bar-header bar-secondary">
|
<div class="bar bar-header bar-secondary">
|
||||||
<a href="#" class="button button-danger button-clear">Edit</a>
|
<a href="#" class="button button-danger button-clear">Edit</a>
|
||||||
<h1 class="title">Scroll Me</h1>
|
<h1 class="title">Scroll Me</h1>
|
||||||
<a href="#" class="button button-danger button-clear">Delete</a>
|
<a href="#" class="button button-danger button-clear">Delete</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="scroller" class="scroll">
|
<div id="scroller" class="scroll" style="margin-top:44px">
|
||||||
<div style="height: 4000px; background: url('tree_bark.png') repeat;"></div>
|
<!--<div id="filler" style="height: 1400px; background: url('tree_bark.png') repeat;"></div>-->
|
||||||
|
<ul class="list">
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<script src="../dist/js/ionic.js"></script>
|
<script src="../dist/js/ionic.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var s = document.getElementById('scroller');
|
var s = document.getElementById('scroller');
|
||||||
|
|
||||||
|
for(var i = 0; i < 100; i++) {
|
||||||
|
var li = document.createElement('li');
|
||||||
|
li.className = 'list-item';
|
||||||
|
li.innerHTML = 'Item ' + i;
|
||||||
|
s.firstElementChild.appendChild(li);
|
||||||
|
}
|
||||||
|
|
||||||
var scroll = new ionic.views.Scroll({
|
var scroll = new ionic.views.Scroll({
|
||||||
el: s
|
el: s
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user