Effect to smoothly scroll any element, including the window.
Fx.Scroll = new Class({
Extends: Fx,
options: {
offset: {x: 0, y: 0},
wheelStops: true
},
initialize: function(element, options){
this.element = this.subject = document.id(element);
this.parent(options);
var cancel = this.cancel.bind(this, false);
if (typeOf(this.element) != 'element') this.element = document.id(this.element.getDocument().body);
var stopper = this.element;
if (this.options.wheelStops){
this.addEvent('start', function(){
stopper.addEvent('mousewheel', cancel);
}, true);
this.addEvent('complete', function(){
stopper.removeEvent('mousewheel', cancel);
}, true);
}
},
set: function(){
var now = Array.flatten(arguments);
if (Browser.firefox) now = [Math.round(now[0]), Math.round(now[1])];
this.element.scrollTo(now[0] + this.options.offset.x, now[1] + this.options.offset.y);
},
compute: function(from, to, delta){
return [0, 1].map(function(i){
return Fx.compute(from[i], to[i], delta);
});
},
start: function(x, y){
if (!this.check(x, y)) return this;
var scrollSize = this.element.getScrollSize(),
scroll = this.element.getScroll(),
values = {x: x, y: y};
for (var z in values){
var max = scrollSize[z];
if (values[z] != null || values[z] === 0) values[z] = (typeOf(values[z]) == 'number') ? values[z] : max;
else values[z] = scroll[z];
values[z] += this.options.offset[z];
}
return this.parent([scroll.x, scroll.y], [values.x, values.y]);
},
toTop: function(){
return this.start(false, 0);
},
toLeft: function(){
return this.start(0, false);
},
toRight: function(){
return this.start('right', false);
},
toBottom: function(){
return this.start(false, 'bottom');
},
toElement: function(el){
var position = document.id(el).getPosition(this.element);
return this.start(position.x, position.y);
},
scrollIntoView: function(el, axes, offset){
axes = axes ? Array.from(axes) : ['x','y'];
var to = {};
el = document.id(el);
var pos = el.getPosition(this.element);
var size = el.getSize();
var scroll = this.element.getScroll();
var containerSize = this.element.getSize();
var edge = {
x: pos.x + size.x,
y: pos.y + size.y
};
['x','y'].each(function(axis){
if (axes.contains(axis)){
if (edge[axis] > scroll[axis] + containerSize[axis]) to[axis] = edge[axis] - containerSize[axis];
if (pos[axis] < scroll[axis]) to[axis] = pos[axis];
}
if (to[axis] == null) to[axis] = scroll[axis];
if (offset && offset[axis]) to[axis] = to[axis] + offset[axis];
}, this);
if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);
return this;
},
scrollToCenter: function(el, axes, offset){
axes = axes ? Array.from(axes) : ['x', 'y'];
el = document.id(el);
var to = {},
pos = el.getPosition(this.element),
size = el.getSize(),
scroll = this.element.getScroll(),
containerSize = this.element.getSize(),
edge = {
x: pos.x + size.x,
y: pos.y + size.y
};
['x','y'].each(function(axis){
if (axes.contains(axis)){
to[axis] = pos[axis] - (containerSize[axis] - size[axis])/2;
}
if (to[axis] == null) to[axis] = scroll[axis];
if (offset && offset[axis]) to[axis] = to[axis] + offset[axis];
}, this);
if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);
return this;
}
});