Slightly easier scroll API

This commit is contained in:
Max Lynch
2013-11-27 14:54:48 -06:00
parent 3267e80e64
commit c9b384c8a8
4 changed files with 245 additions and 7 deletions

58
dist/js/ionic.js vendored
View File

@@ -3112,14 +3112,15 @@ var Scroller;
};
/**
* A pure logic 'component' for 'virtual' scrolling/zooming.
*/
ionic.views.Scroller = ionic.views.View.inherit({
initialize: function(callback, options) {
initialize: function(options) {
this.__callback = callback;
this.__content = options.content;
this.__callback = this.getRenderFn();
this.options = {
@@ -3344,6 +3345,57 @@ var Scroller;
---------------------------------------------------------------------------
*/
getRenderFn: function() {
var content = this.__content;
var docStyle = document.documentElement.style;
var engine;
if ('MozAppearance' in docStyle) {
engine = 'gecko';
} else if ('WebkitAppearance' in docStyle) {
engine = 'webkit';
} else if (typeof navigator.cpuClass === 'string') {
engine = 'trident';
}
var vendorPrefix = {
trident: 'ms',
gecko: 'Moz',
webkit: 'Webkit',
presto: 'O'
}[engine];
var helperElem = document.createElement("div");
var undef;
var perspectiveProperty = vendorPrefix + "Perspective";
var transformProperty = vendorPrefix + "Transform";
if (helperElem.style[perspectiveProperty] !== undef) {
return function(left, top, zoom) {
content.style[transformProperty] = 'translate3d(' + (-left) + 'px,' + (-top) + 'px,0) scale(' + zoom + ')';
};
} else if (helperElem.style[transformProperty] !== undef) {
return function(left, top, zoom) {
content.style[transformProperty] = 'translate(' + (-left) + 'px,' + (-top) + 'px) scale(' + zoom + ')';
};
} else {
return function(left, top, zoom) {
content.style.marginLeft = left ? (-left/zoom) + 'px' : '';
content.style.marginTop = top ? (-top/zoom) + 'px' : '';
content.style.zoom = zoom || '';
};
}
},
/**
* Configures the dimensions of the client (outer) and content (inner) elements.
* Requires the available space for the outer element and the outer size of the inner element.

View File

@@ -65,7 +65,7 @@
var container = document.getElementById('c');
// Initialize Scroller
var scroller = new ionic.views.Scroller(render, {
var scroller = new ionic.views.Scroller({
scrollingX: false
});

View File

@@ -278,14 +278,15 @@ var Scroller;
};
/**
* A pure logic 'component' for 'virtual' scrolling/zooming.
*/
ionic.views.Scroller = ionic.views.View.inherit({
initialize: function(callback, options) {
initialize: function(options) {
this.__callback = callback;
this.__content = options.content;
this.__callback = this.getRenderFn();
this.options = {
@@ -510,6 +511,57 @@ var Scroller;
---------------------------------------------------------------------------
*/
getRenderFn: function() {
var content = this.__content;
var docStyle = document.documentElement.style;
var engine;
if ('MozAppearance' in docStyle) {
engine = 'gecko';
} else if ('WebkitAppearance' in docStyle) {
engine = 'webkit';
} else if (typeof navigator.cpuClass === 'string') {
engine = 'trident';
}
var vendorPrefix = {
trident: 'ms',
gecko: 'Moz',
webkit: 'Webkit',
presto: 'O'
}[engine];
var helperElem = document.createElement("div");
var undef;
var perspectiveProperty = vendorPrefix + "Perspective";
var transformProperty = vendorPrefix + "Transform";
if (helperElem.style[perspectiveProperty] !== undef) {
return function(left, top, zoom) {
content.style[transformProperty] = 'translate3d(' + (-left) + 'px,' + (-top) + 'px,0) scale(' + zoom + ')';
};
} else if (helperElem.style[transformProperty] !== undef) {
return function(left, top, zoom) {
content.style[transformProperty] = 'translate(' + (-left) + 'px,' + (-top) + 'px) scale(' + zoom + ')';
};
} else {
return function(left, top, zoom) {
content.style.marginLeft = left ? (-left/zoom) + 'px' : '';
content.style.marginTop = top ? (-top/zoom) + 'px' : '';
content.style.zoom = zoom || '';
};
}
},
/**
* Configures the dimensions of the client (outer) and content (inner) elements.
* Requires the available space for the outer element and the outer size of the inner element.

134
test/scroll_z.html Normal file
View File

@@ -0,0 +1,134 @@
<html>
<head>
<meta charset="utf-8">
<title>Content</title>
<!-- Sets initial viewport load and disables zooming -->
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="stylesheet" href="../../../../dist/css/ionic.css">
<script src="../../../../dist/js/ionic.js"></script>
<style>
#c{
width: 100%;
height: 100%;
position: absolute;
overflow: hidden;
font-family: sans-serif;
cursor: default;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
#content{
background: white;
width: 100%;
-webkit-transform-origin: left top;
-webkit-transform: translateZ(0);
-moz-transform-origin: left top;
-moz-transform: translateZ(0);
-ms-transform-origin: left top;
-ms-transform: translateZ(0);
-o-transform-origin: left top;
-o-transform: translateZ(0);
transform-origin: left top;
transform: translateZ(0);
}
</style>
</head>
<body>
<div id="c">
<div id="content">
<div style="height: 3000px; width: 100%; background: url('tree_bark.png') repeat"></div>
</div>
</div>
<script>
var render = function(left, top, zoom) {
content.style.webkitTransform = 'translate3d(' + (-left) + 'px,' + (-top) + 'px,0) scale(' + zoom + ')';
};
var container = document.getElementById('c');
var content = document.getElementById('content');
// Initialize Scroller
var scroller = new ionic.views.Scroller({
content: content,
scrollingX: false
});
// Update Scroller dimensions for changed content
scroller.setDimensions(container.clientWidth, container.clientHeight, content.offsetWidth, content.offsetHeight-50);
// Event Handler
if ('ontouchstart' in window) {
container.addEventListener("touchstart", function(e) {
// Don't react if initial down happens on a form element
if (e.target.tagName.match(/input|textarea|select/i)) {
return;
}
scroller.doTouchStart(e.touches, e.timeStamp);
e.preventDefault();
}, false);
document.addEventListener("touchmove", function(e) {
scroller.doTouchMove(e.touches, e.timeStamp);
}, false);
document.addEventListener("touchend", function(e) {
scroller.doTouchEnd(e.timeStamp);
}, false);
} else {
var mousedown = false;
container.addEventListener("mousedown", function(e) {
// Don't react if initial down happens on a form element
if (e.target.tagName.match(/input|textarea|select/i)) {
return;
}
scroller.doTouchStart([{
pageX: e.pageX,
pageY: e.pageY
}], e.timeStamp);
mousedown = true;
}, false);
document.addEventListener("mousemove", function(e) {
if (!mousedown) {
return;
}
scroller.doTouchMove([{
pageX: e.pageX,
pageY: e.pageY
}], e.timeStamp);
mousedown = true;
}, false);
document.addEventListener("mouseup", function(e) {
if (!mousedown) {
return;
}
scroller.doTouchEnd(e.timeStamp);
mousedown = false;
}, false);
}
</script>
</body>
</html>