source/class/core/component/Scroller.js
(function(undef)
{
var transformOriginProperty = core.bom.Style.property("transformOrigin");
var perspectiveProperty = core.bom.Style.property("perspective");
var transformProperty = core.bom.Style.property("transform");
if (perspectiveProperty)
{
var render = function(left, top, zoom)
{
var content = this.__container.firstElementChild;
content.style[transformProperty] = 'translate3d(' + (-left) + 'px,' + (-top) + 'px,0) scale(' + zoom + ')';
};
}
else if (transformProperty)
{
var render = function(left, top, zoom)
{
var content = this.__container.firstElementChild;
content.style[transformProperty] = 'translate(' + (-left) + 'px,' + (-top) + 'px) scale(' + zoom + ')';
};
}
else
{
var render = function(left, top, zoom)
{
var content = this.__container.firstElementChild;
content.style.marginLeft = left ? (-left/zoom) + 'px' : '';
content.style.marginTop = top ? (-top/zoom) + 'px' : '';
content.style.zoom = zoom || '';
};
}
core.Class("core.component.Scroller",
{
include : [core.util.MLogging],
construct : function(container, options)
{
if (jasy.Env.isSet("debug"))
{
core.Assert.isType(container, "Node");
if (options != null) {
core.Assert.isType(options, "Map");
}
}
this.__container = container;
this.__options = options || {};
// create Scroller instance
this.__scroller = new core.ui.Scroller(render.bind(this), options);
// bind events
this.__bindEvents();
},
members :
{
/**
*
*/
render : render,
/**
*
*/
reflow : function()
{
var container = this.__container;
var content = container.firstElementChild;
// set the right scroller dimensions
this.__scroller.setDimensions(container.clientWidth, container.clientHeight, content.offsetWidth, content.offsetHeight);
// refresh the position for zooming purposes
var rect = container.getBoundingClientRect();
this.__scroller.setPosition(rect.left + container.clientLeft, rect.top + container.clientTop);
},
/**
*
*/
__bindEvents : function()
{
var that = this;
// reflow handling
window.addEventListener("resize", function() {
that.reflow();
}, false);
// touch devices bind touch events
if ('ontouchstart' in window) {
this.__container.addEventListener("touchstart", function(e)
{
// Don't react if initial down happens on a form element
if (e.touches[0] && e.touches[0].target && e.touches[0].target.tagName.match(/input|textarea|select/i)) {
} else {
e.preventDefault();
e.stopPropagation();
}
that.__scroller.doTouchStart(e.touches, e.timeStamp);
}, false);
document.addEventListener("touchmove", function(e)
{
// Prevent from native scrolling
e.preventDefault();
that.__scroller.doTouchMove(e.touches, e.timeStamp, e.scale);
}, false);
document.addEventListener("touchend", function(e) {
that.__scroller.doTouchEnd(e.timeStamp);
}, false);
document.addEventListener("touchcancel", function(e) {
that.__scroller.doTouchEnd(e.timeStamp);
}, false);
// non-touch bind mouse events
} else {
var mousedown = false;
this.__container.addEventListener("mousedown", function(e) {
if (e.target.tagName.match(/input|textarea|select/i)) {
return;
}
that.__scroller.doTouchStart([{
pageX: e.pageX,
pageY: e.pageY
}], e.timeStamp);
mousedown = true;
e.preventDefault();
e.stopPropagation();
}, false);
document.addEventListener("mousemove", function(e) {
if (!mousedown) {
return;
}
that.__scroller.doTouchMove([{
pageX: e.pageX,
pageY: e.pageY
}], e.timeStamp);
mousedown = true;
}, false);
document.addEventListener("mouseup", function(e) {
if (!mousedown) {
return;
}
that.__scroller.doTouchEnd(e.timeStamp);
mousedown = false;
}, false);
this.__container.addEventListener("mousewheel", function(e) {
if(that.__options.zooming) {
that.__scroller.doMouseZoom(e.wheelDelta, e.timeStamp, e.pageX, e.pageY);
e.preventDefault();
}
}, false);
}
}
}
});
})();