1 |
- /*
*
* 2011 www.g-u-i.net
*
*/
(function($){
jQuery.extend({
mouse: {
x: 0,
y: 0
},
clickNScroll: {
mousedown:false,
emaX: 0,
emaY: 0,
started : false
}
});
var methods = {
init : function(options){
var settings = {
scroller:'',
allowHiliting:false,
acceleration:.65,
deceleration:.85,
decelRate:64,
reverse:false,
rightMouse:false,
allowThrowing:true,
throwOnOut:true,
stepableparent:false,
changeLimit:3,
stepInSpeed:500,
axis:false,
distance:0,
easing:'linear',
disabled : false,
started:false,
};
return this.each(function(){
var $this = $(this),
ops = $.extend({}, settings, options || {});
ops.scroller = ops.scroller != '' ? $(ops.scroller, $this) : $this;
ops.id = $this.attr('id');
$this.data("clicknscroll", ops);
if(!ops.allowHiliting) {
if (jQuery.browser.msie) {
$this.get(0).onselectstart = function () { return false; };
} else {
$this.get(0).onmousedown = function(e){e.preventDefault()}
}
}
this.addEventListener('mouseup', function(e) {
if($(this).data('clicknscroll').disabled)
return;
if($(this).hasClass('cns-scrolling')){
e.stopPropagation(); // stopPropagation to prevent mouseUp on dom children when just scrolling
$(document).trigger('mouseup');
if(ops.allowThrowing)
sling($(this));
}
$.clickNScroll.mousedown = false;
}, true); // add this event listener with addEventListener because of useCapture = true, that is impossible yet with jQuery bind() …
$this
.mousedown(function(e) {
// $this.bind('mousedown click name', function(e) {
// $.log('mousedown | $(this)',$(this));
if($(this).data('clicknscroll').disabled)
return false;
$this.stop().clearQueue();
$.clickNScroll.startX = e.pageX;
$.clickNScroll.startY = e.pageY;
$.clickNScroll.mousedown = $this;
})
.mouseout(function(e) {
if($(this).data('clicknscroll').disabled)
return;
var from = e.relatedTarget || e.toElement;
if (!from || from.nodeName == "HTML") {
if($.clickNScroll.mousedown && ops.allowThrowing && ops.throwOnOut) sling($(this));
$.clickNScroll.mousedown = false;
}
});
});
},
enable : function(){
// $.log('clickNScroll | enable | this',this);
return this.each(function() {
$(this).data('clicknscroll').disabled = false;
});
},
disable : function(){
// $.log('clickNScroll | disable | this',this);
return this.each(function() {
$(this).data('clicknscroll').disabled = true;
});
},
isStarted : function(){
return $(this).data('clicknscroll').started;
},
stop : function(){
return this.each(function() {
if(!$(this).data('clicknscroll').started){
$.clickNScroll.mousedown = false;
$(this).data('clicknscroll').started = false;
}
});
},
scrollTo : function(delta){
// $.log('scrollTo | delta = '+delta);
return this.each(function() {
$(this).data('clicknscroll').scroller.scrollLeft(delta);
});
}
};
jQuery.fn.extend({
clickNScroll: function(options) {
// Method calling logic
if ( methods[options] ) {
return methods[ options ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof options === 'object' || ! options ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + options + ' does not exist on jQuery.clickNScroll' );
}
}
});
/**
* sling($this)
*/
function sling($this) {
var data = $this.data("clicknscroll"),
$scroller = data.scroller,
changeX = ($.clickNScroll.emaX)*data.deceleration,
changeY = ($.clickNScroll.emaY)*data.deceleration;
if( Math.abs(changeX) > 0 && Math.abs(changeX) <= data.changeLimit && data.stepableparent) {
// $.log('ClicknScroll :: end sling X');
var scrollPos = $scroller.scrollLeft()+$scroller.width()*.5;
$(data.stepableparent, $scroller).children(':visible').each(function(i) {
var $child = $(this),
childPos = $child.position();
if(scrollPos >= childPos.left && scrollPos <= childPos.left+$child.width() ){
var stepLeft = childPos.left + $child.width()*.5 - $scroller.width()*.5;
var e = jQuery.Event('stepInLeft');
e.options = data;
e.stepIndex = i;
e.stepTarget = $child;
e.direction = changeX < 0 ? -1 : 1;
$this.trigger(e);
$scroller.animate({scrollLeft: stepLeft}, {easing:data.easing, duration:data.stepInSpeed, queue:false , complete:function() {
$this.trigger('stepedInLeft',data);
}
});
$.clickNScroll.emaX = 0;
changeX = 0;
return;
}
});
}
if( Math.abs(changeY) > 0 && Math.abs(changeY) <= data.changeLimit && data.stepableparent) {
// $.log('ClicknScroll :: end sling Y');
var scrollPos = $scroller.scrollTop()+$scroller.height()*.5;
$(data.stepableparent, $scroller).children(':visible').each(function(i) {
var $child = $(this),
childPos = $child.position();
if(scrollPos >= childPos.top && scrollPos <= childPos.top+$child.height() ){
var stepTop = childPos.top + $child.height()*.5 - $scroller.height()*.5;
var e = jQuery.Event('stepInTop');
e.options = data;
e.stepIndex = i;
e.stepTarget = $child;
e.direction = changeY < 0 ? -1 : 1;
$this.trigger(e);
$scroller.animate({scrollTop: stepTop}, {easing:data.easing, duration:data.stepInSpeed, queue:false , complete:function() {
$this.trigger('stepedInTop',data);
}
});
$.clickNScroll.emaY = 0;
changeY = 0;
return;
}
});
}
if(Math.abs(changeX) < .01 && Math.abs(changeY) < .01 && $this.hasClass('cns-scrolling')){
$this.removeClass('cns-scrolling').trigger('clickNScrollStop');
return;
}
// return;
move($this, changeX, changeY);
setTimeout(function() {
sling($this);
}, 1000/data.decelRate);
};
/**
* move($scroller, changeX, changeY)
*/
function move($this, changeX, changeY) {
$.log('clicknscroll | move');
// if(!$this.data('clicknscroll').started){
// $this.trigger('clickNScrollStart').data('clicknscroll').started = true;
// }
if(!$this.hasClass('cns-scrolling')){
$this.addClass('cns-scrolling').trigger('clickNScrollStart');
}
$this.trigger('clickNScrollMove');
if(($.clickNScroll.emaX < 0 && changeX > 0) || ($.clickNScroll.emaX > 0 && changeX < 0))
$.clickNScroll.emaX = 0;
if(($.clickNScroll.emaY < 0 && changeY > 0) || ($.clickNScroll.emaY > 0 && changeY < 0))
$.clickNScroll.emaY = 0;
var ops = $this.data("clicknscroll"),
$scroller = ops.scroller,
amntX = ops.acceleration * changeX + (1 - ops.acceleration) * $.clickNScroll.emaX,
amntY = ops.acceleration * changeY + (1 - ops.acceleration) * $.clickNScroll.emaY,
scrollRight = $scroller[0].scrollWidth ? $scroller[0].scrollWidth - $scroller[0].clientWidth : $scroller[0].body.scrollWidth - $scroller[0].body.clientWidth,
scrollBottom = $scroller[0].scrollHeight ? $scroller[0].scrollHeight - $scroller[0].clientHeight : $scroller[0].body.scrollHeight - $scroller[0].body.clientHeight;
if(($scroller.scrollLeft() >= 0 && changeX >= 0) || ($scroller.scrollLeft() <= scrollRight && changeX <= 0))
$scroller.scrollLeft($scroller.scrollLeft() + (amntX));
if(($scroller.scrollTop() >= 0 && changeY >= 0) || ($scroller.scrollTop() <= scrollBottom && changeY <= 0))
$scroller.scrollTop($scroller.scrollTop() + (amntY));
$.clickNScroll.emaX = amntX;
$.clickNScroll.emaY = amntY;
};
/**
* mousemove event
*/
$(document).mousemove(function(e) {
if($.clickNScroll.mousedown) {
var $this = $.clickNScroll.mousedown,
ops = $this.data("clicknscroll");
if(ops.rightMouse && e.button != 2) return;
else if(!ops.rightMouse && e.button == 2) return;
var changeX = ops.axis != 'y' ? e.pageX - $.mouse.x : 0,
changeY = ops.axis != 'x' ? e.pageY - $.mouse.y : 0;
if(!ops.reverse) {
changeX = 0-changeX;
changeY = 0-changeY;
}
if((Math.abs($.clickNScroll.startX - e.pageX) > ops.distance && ops.axis != 'y')
|| (Math.abs($.clickNScroll.startY - e.pageY) > ops.distance && ops.axis != 'x'))
move($this, changeX, changeY);
}
$.mouse = {
x: e.pageX,
y: e.pageY
};
});
})(jQuery);
|