282 lines
8.8 KiB
JavaScript
282 lines
8.8 KiB
JavaScript
var scrollr = scrollr || {};
|
|
|
|
scrollr.scrollers = [];
|
|
|
|
scrollr.doInit = function() {
|
|
var elements = scrollr.getElementsByClass(document.body, 'div', 'scrollr');
|
|
for (element in elements) {
|
|
//var new_scroller = new scrollr.Scrollbar(elements[element]);
|
|
//scrollr.scrollers.push(new_scroller);
|
|
}
|
|
}
|
|
|
|
scrollr.Scrollbar = function(element) {
|
|
this.element = element;
|
|
|
|
this.element.style.overflow = "hidden";
|
|
this.element.style.whiteSpace = "nowrap";
|
|
|
|
//this.element.className = 'scrollr_js';
|
|
this.container = document.createElement('div');
|
|
this.container.className = 'scrollr_container';
|
|
this.element.parentNode.insertBefore(this.container, this.element);
|
|
this.container.appendChild(this.element);
|
|
var divs = this.element.getElementsByTagName('div');
|
|
for (div in divs) {
|
|
divs[div].className = 'scrollr_item';
|
|
}
|
|
this.location = new scrollr.Vector(0, 0, 0);
|
|
this.velocity = new scrollr.Vector(0, 0, 0);
|
|
this.acceleration = new scrollr.Vector(0, 0, 0);
|
|
this.last_x = 0;
|
|
|
|
this.createScrollbar();
|
|
this.createScroller();
|
|
this.timer = new scrollr.Loop(25,
|
|
(function(context) {
|
|
return function(e) {
|
|
context.doScroll(e);
|
|
}
|
|
})(this)
|
|
);
|
|
}
|
|
scrollr.Scrollbar.prototype.createScrollbar = function() {
|
|
this.scrollbar = document.createElement('div');
|
|
this.scrollbar.className = 'scrollr_scrollbar';
|
|
this.container.appendChild(this.scrollbar);
|
|
this.container.style.paddingBottom = (this.scrollbar.offsetHeight + (parseInt(this.container.style.paddingBottom) || 0))+"px";
|
|
|
|
this.attached_mouse = false;
|
|
this.mouse_event = (function(context) {
|
|
return function(e) {
|
|
context.onMouseMove(e);
|
|
}
|
|
})(this);
|
|
|
|
|
|
scrollr.addEvent(this.scrollbar, 'mousedown',
|
|
(function(context) {
|
|
return function(e) {
|
|
context.onClick(e);
|
|
e.preventDefault();
|
|
return false;
|
|
}
|
|
})(this)
|
|
);
|
|
scrollr.addEvent(this.scrollbar, 'mouseup',
|
|
(function(context) {
|
|
return function(e) {
|
|
context.onRelease(e);
|
|
}
|
|
})(this)
|
|
);
|
|
|
|
}
|
|
scrollr.Scrollbar.prototype.createScroller = function() {
|
|
this.scroller_box = document.createElement('div');
|
|
this.scroller_box.className = 'scrollr_scroller_box';
|
|
this.scrollbar.appendChild(this.scroller_box);
|
|
// this.scroller_box.style.width = ( this.scroller_box.offsetWidth * this.getMultiplier() )+"px";
|
|
|
|
this.scroller = document.createElement('div');
|
|
this.scroller.className = 'scrollr_scroller';
|
|
this.scroller_box.appendChild(this.scroller);
|
|
this.scroller.style.width = ( this.scroller.offsetWidth * this.getMultiplier() )+"px";
|
|
}
|
|
scrollr.Scrollbar.prototype.getInnerWidth = function() {
|
|
return (this.element.scrollWidth);
|
|
}
|
|
scrollr.Scrollbar.prototype.getMultiplier = function() {
|
|
return ( this.element.offsetWidth / this.element.scrollWidth );
|
|
}
|
|
scrollr.Scrollbar.prototype.onClick = function(event) {
|
|
var e = window.event || event;
|
|
var offset_left = e.clientX-(this.container.offsetLeft);
|
|
this.target_x = offset_left;
|
|
if (offset_left > this.scroller.offsetLeft && offset_left < this.scroller.offsetLeft+this.scroller.offsetWidth) {
|
|
if (!this.attached_mouse) {
|
|
this.attached_mouse = true;
|
|
scrollr.addEvent(window, 'mousemove', this.mouse_event);
|
|
}
|
|
}
|
|
/* if (offset_left < this.location.x) {
|
|
var move = (offset_left - this.location.x)*this.getMultiplier();
|
|
this.applyForce(new scrollr.Vector(move, 0, 0));
|
|
} else if (offset_left > this.location.x+this.scroller.offsetWidth) {
|
|
var move = 4 * (( offset_left - (this.location.x+this.scroller.offsetWidth) ));
|
|
this.applyForce(new scrollr.Vector(move, 0, 0));
|
|
}*/
|
|
this.timer.Start();
|
|
return false;
|
|
}
|
|
scrollr.Scrollbar.prototype.onRelease = function(event) {
|
|
if (this.attached_mouse) {
|
|
this.attached_mouse = false;
|
|
scrollr.removeEvent(window, 'mousemove', this.mouse_event);
|
|
}
|
|
}
|
|
scrollr.Scrollbar.prototype.onMouseMove = function(event) {
|
|
var e = window.event || event;
|
|
var offset_left = e.clientX-(this.container.offsetLeft);
|
|
//this.target_x = offset_left;
|
|
if (offset_left < this.previous_x) {
|
|
this.target_x = this.location.x - (this.previous_x-offset_left);
|
|
} else if (offset_left > this.previous_x) {
|
|
this.target_x = this.scroller.offsetWidth+this.location.x+(offset_left-this.previous_x);
|
|
}
|
|
this.previous_x = offset_left;
|
|
this.timer.Start();
|
|
}
|
|
scrollr.Scrollbar.prototype.doScroll = function(delta) {
|
|
if (this.target_x < this.location.x) {
|
|
var move = (this.target_x - this.location.x)*this.getMultiplier();
|
|
this.applyForce(new scrollr.Vector(move, 0, 0));
|
|
} else if (this.target_x > this.location.x+this.scroller.offsetWidth) {
|
|
var move = (( this.target_x - (this.location.x+this.scroller.offsetWidth) ))*this.getMultiplier();
|
|
this.applyForce(new scrollr.Vector(move, 0, 0));
|
|
}
|
|
|
|
if (this.location.x <= 8) {
|
|
// this.velocity.multiply(0);
|
|
this.applyForce(new scrollr.Vector(-this.location.x, 0, 0));
|
|
//this.container.style.paddingBottom = (this.scrollbar.offsetHeight + (parseInt(this.container.style.paddingBottom) || 0))+"px";
|
|
} else if ((this.location.x + this.scroller.offsetWidth) > this.element.offsetWidth-8) {
|
|
// this.velocity.multiply(0);
|
|
this.applyForce(new scrollr.Vector(this.element.offsetWidth-(this.location.x+this.scroller.offsetWidth), 0, 0));
|
|
}
|
|
|
|
var friction = this.velocity.copyVector();
|
|
friction.multiply(-1);
|
|
friction.normalize();
|
|
friction.multiply(2.5);
|
|
this.applyForce(friction);
|
|
|
|
this.velocity.add(this.acceleration);
|
|
this.location.add(this.velocity);
|
|
this.acceleration.multiply(0);
|
|
this.scroller.style.marginLeft = this.location.x+'px';
|
|
this.element.scrollLeft = this.location.x/this.getMultiplier();
|
|
if (this.location.x == this.last_x) {
|
|
this.timer.Stop();
|
|
}
|
|
this.last_x = this.location.x;
|
|
};
|
|
scrollr.Scrollbar.prototype.applyForce = function(force) {
|
|
var new_force = force.copyVector();
|
|
new_force.divide(15.0);
|
|
this.acceleration.add(new_force);
|
|
}
|
|
|
|
scrollr.addEvent = function(target, event_type, callback, bubble) {
|
|
bubble = (typeof bubble !== 'undefined' ? bubble : false);
|
|
if (typeof target.attachEvent !== 'undefined') {
|
|
target.attachEvent('on'+event_type, callback);
|
|
} else if (typeof target.addEventListener !== 'undefined') {
|
|
target.addEventListener(event_type, callback, bubble);
|
|
}
|
|
}
|
|
|
|
scrollr.removeEvent = function(target, event_type, callback, bubble) {
|
|
bubble = (typeof bubble !== 'undefined' ? bubble : false);
|
|
if (typeof target.detachEvent !== 'undefined') {
|
|
target.detachEvent('on'+event_type, callback);
|
|
} else if (typeof target.removeEventListener !== 'undefined') {
|
|
target.removeEventListener(event_type, callback, bubble);
|
|
}
|
|
}
|
|
scrollr.getAbsoluteElementOffset = function(element) {
|
|
var offset_top = 0;
|
|
var offset_left = 0;
|
|
var obj = element;
|
|
do {
|
|
offset_top += obj.offsetTop;
|
|
offset_left += obj.offsetLeft;
|
|
} while (obj = obj.offsetParent);
|
|
return { x: offset_left, y: offset_top };
|
|
}
|
|
scrollr.getElementsByClass = function(search_element, element_name, class_name) {
|
|
var elements = search_element.getElementsByTagName(element_name);
|
|
var return_elements = [];
|
|
for (element in elements) {
|
|
if (elements[element].className == class_name) {
|
|
return_elements.push(elements[element]);
|
|
}
|
|
}
|
|
return return_elements;
|
|
}
|
|
|
|
scrollr.Loop = function(loop_time, target_callback) {
|
|
this.start_time = new Date().getTime();
|
|
this.current_time = this.start_time;
|
|
this.previous_time = this.start_time;
|
|
this.elapsed_time = 0;
|
|
this.delta_time = 0;
|
|
this.loop_time = loop_time;
|
|
this.is_running = false;
|
|
|
|
this.Tick = function() {
|
|
this.current_time = new Date().getTime();
|
|
|
|
this.delta_time = (this.current_time - this.previous_time);
|
|
this.elapsed_time += this.delta_time;
|
|
|
|
target_callback(this.delta_time);
|
|
this.previous_time = this.current_time;
|
|
if (this.is_running) {
|
|
(function(_this) { setTimeout(function() { _this.Tick(); }, _this.loop_time-_this.delta_time)})(this);
|
|
}
|
|
};
|
|
this.Start = function() {
|
|
if (!this.is_running) {
|
|
this.start_time = new Date().getTime();
|
|
this.current_time = this.start_time;
|
|
this.previous_time = this.start_time;
|
|
this.elapsed_time = 0;
|
|
this.delta_time = 0;
|
|
this.is_running = true;
|
|
this.Tick();
|
|
}
|
|
};
|
|
this.Stop = function() {
|
|
this.is_running = false;
|
|
};
|
|
};
|
|
|
|
scrollr.Vector = function(x, y, z) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
this.add = function(vector) {
|
|
this.x += vector.x;
|
|
this.y += vector.y;
|
|
this.z += vector.z;
|
|
};
|
|
this.subtract = function(vector) {
|
|
this.x -= vector.x;
|
|
this.y -= vector.y;
|
|
this.z -= vector.z;
|
|
};
|
|
this.multiply = function(multiplier) {
|
|
this.x = this.x * multiplier;
|
|
this.y = this.y * multiplier;
|
|
this.z = this.z * multiplier;
|
|
};
|
|
this.divide = function(divisor) {
|
|
this.x = this.x / divisor;
|
|
this.y = this.y / divisor;
|
|
this.z = this.z / divisor;
|
|
};
|
|
this.getMagnitude = function() {
|
|
return Math.sqrt(this.x*this.y + this.y*this.y);
|
|
};
|
|
this.copyVector = function() {
|
|
return new scrollr.Vector(this.x, this.y, this.z);
|
|
};
|
|
this.normalize = function() {
|
|
var magnitude = this.getMagnitude();
|
|
(magnitude != 0 ? this.divide(magnitude) : '');
|
|
};
|
|
};
|
|
|
|
scrollr.addEvent(window, 'load', scrollr.doInit);
|