kettek2/wiki/games/newsboy/scrollr.js

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);