Blog/smoothscroller/smoothscroller.js
(Deskargatu)
(function()
{
'use strict';
var rid;
var offset;
var amplitude;
var target;
var timestamp;
var timeConstant = 200;
var throttleTime = 50;
var callbacks = [];
var status = {};
var scroll_pos = 0;
var ease = function(t)
{
return (--t)*t*t+1;
};
var scroll = function(pos) {
var self=this;
scroll_pos = smoothscroller.setOffset(pos);
var previous_callback_id = '';
var previous_calledin = false;
callbacks.forEach(function(callback)
{
if(scroll_pos<callback.start)
{
if(status[callback.id]!==0)
{
status[callback.id]=0;
callback.in_callback(scroll_pos, 0);
}
}
else if(scroll_pos>callback.end)
{
if(status[callback.id]!==1)
{
status[callback.id]=1;
callback.in_callback(scroll_pos, 1);
}
}
else
{
status[callback.id]=2;
callback.in_callback(scroll_pos, callback.ease((scroll_pos - callback.start) / callback.height));
}
previous_callback_id = callback.id;
});
};
var reset = function()
{
callbacks = [];
};
var add = function(start, end, in_callback, custom_ease)
{
callbacks.push(
{
id: 'single_'+Math.random(),
start: start,
end: end,
in_callback: in_callback,
height: end - start,
ease: custom_ease || ease
});
};
var initialize = function() {
offset = target = 0;
setupEvents();
};
var setupEvents = function() {
var view = document.getElementById('content');
if (typeof window.ontouchstart !== 'undefined') {
}
document.addEventListener('scroll', manual_scroll);
};
var xpos = function(e) {
// touch event
if (e.targetTouches && (e.targetTouches.length >= 1)) {
return e.targetTouches[0].clientX;
}
// mouse event
return e.clientX;
};
var autoScroll = function() {
var elapsed;
if (amplitude) {
elapsed = Date.now() - timestamp;
var delta = amplitude * Math.exp(-elapsed / timeConstant);
if (delta > 4 || delta < -3) {
scroll(target - delta);
rid=requestAnimationFrame(autoScroll);
} else {
rid=null;
scroll(target);
}
}
else
{
rid=null;
}
}
var manual_scroll = function(e) {
var doc = document.documentElement;
var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
target = top;
amplitude = target - offset;
var newtimestamp = Date.now();
if(!timestamp || newtimestamp>timestamp+throttleTime)
{
timestamp = newtimestamp;
}
if(!rid)
{
rid = requestAnimationFrame(autoScroll);
}
//e.preventDefault();
//e.stopPropagation();
return false;
};
var getOffset = function() { return offset; };
var setOffset = function(x) { return offset = x; };
var setCallback = function(newfunction) { scroll =newfunction; scroll(target||0); return scroll; };
window.smoothscroller =
{
initialize: initialize,
getOffset : getOffset,
setOffset : setOffset,
add: add,
scroll: scroll,
update: manual_scroll,
reset: reset
};
})();