From 474351752d83f0364b066d62d4d3864a9f31be15 Mon Sep 17 00:00:00 2001 From: Hyunje Alex Jun Date: Fri, 9 Nov 2012 01:32:10 +0900 Subject: [PATCH] Add x-axis scroll function. --- min/perfect-scrollbar.min.css | 2 +- min/perfect-scrollbar.min.js | 2 +- src/perfect-scrollbar.css | 16 ++++++ src/perfect-scrollbar.js | 96 +++++++++++++++++++++++++++++++---- 4 files changed, 104 insertions(+), 12 deletions(-) diff --git a/min/perfect-scrollbar.min.css b/min/perfect-scrollbar.min.css index e1bf410..db9052e 100644 --- a/min/perfect-scrollbar.min.css +++ b/min/perfect-scrollbar.min.css @@ -1 +1 @@ -.ps-container .ps-scrollbar-y{position:absolute;width:10px;right:5px;background-color:gray}.ps-container .ps-scrollbar-y:hover{background-color:#000;cursor:default}.ps-container .ps-scrollbar-y.in-scrolling{background-color:#000} \ No newline at end of file +.ps-container .ps-scrollbar-x{position:absolute;height:10px;bottom:5px;background-color:gray}.ps-container .ps-scrollbar-x:hover{background-color:#000;cursor:default}.ps-container .ps-scrollbar-x.in-scrolling{background-color:#000}.ps-container .ps-scrollbar-y{position:absolute;width:10px;right:5px;background-color:gray}.ps-container .ps-scrollbar-y:hover{background-color:#000;cursor:default}.ps-container .ps-scrollbar-y.in-scrolling{background-color:#000} \ No newline at end of file diff --git a/min/perfect-scrollbar.min.js b/min/perfect-scrollbar.min.js index 9743434..6980760 100644 --- a/min/perfect-scrollbar.min.js +++ b/min/perfect-scrollbar.min.js @@ -1,3 +1,3 @@ /* Copyright (c) 2012 HyeonJe Jun (http://github.com/noraesae) * Licensed under the MIT License - */(function(e){e.fn.perfectScrollbar=function(){var t=e(this),n=e(this).children(),r=e("
").appendTo(t),i,s,o,u;t.addClass("ps-container");var a=function(){t.scrollTop(parseInt(u*s/i))},f=function(){i=t.height(),s=n.height(),o=parseInt(i*i/s),u=parseInt(t.scrollTop()*i/s),r.css({top:u+t.scrollTop(),height:o})},l=function(e,n){var s=e+n,a=i-o;s<0?u=0:s>a?u=a:u=s,r.css({top:u+t.scrollTop()})},c=function(){var t,n;r.bind("mousedown.perfect-scroll",function(e){n=e.pageY,t=r.position().top,r.addClass("in-scrolling"),e.stopPropagation(),e.preventDefault()}),e(window).bind("mousemove.perfect-scroll",function(e){r.hasClass("in-scrolling")&&(l(t,e.pageY-n),a(),e.stopPropagation(),e.preventDefault())}),e(window).bind("mouseup.perfect-scroll",function(e){r.hasClass("in-scrolling")&&r.removeClass("in-scrolling")})},h=function(){t.mousewheel(function(e,n,r,i){t.scrollTop(t.scrollTop()-i*10),t.scrollLeft(t.scrollLeft()+r*10),f(),e.preventDefault()})};return f(),c(),t.mousewheel&&h(),t}})(jQuery); \ No newline at end of file + */(function(e){e.fn.perfectScrollbar=function(){var t=e(this).addClass("ps-container"),n=e(this).children(),r=e("
").appendTo(t),i=e("
").appendTo(t),s,o,u,a,f,l,c=parseInt(r.css("bottom")),h,p,d=parseInt(i.css("right")),v=function(){var e=parseInt(p*a/o);t.scrollTop(e),r.css({bottom:c-e})},m=function(){var e=parseInt(l*u/s);t.scrollLeft(e),i.css({right:d-e})},g=function(){s=t.width(),o=t.height(),u=n.width(),a=n.height(),so?l=o:l=i,r.css({left:l+t.scrollLeft()})},b=function(e,n){var r=e+n,s=o-h;r<0?p=0:r>s?p=s:p=r,i.css({top:p+t.scrollTop()})},w=function(){var t,n;r.bind("mousedown.perfect-scroll",function(e){n=e.pageX,t=r.position().left,r.addClass("in-scrolling"),e.stopPropagation(),e.preventDefault()}),e(window).bind("mousemove.perfect-scroll",function(e){r.hasClass("in-scrolling")&&(y(t,e.pageX-n),m(),e.stopPropagation(),e.preventDefault())}),e(window).bind("mouseup.perfect-scroll",function(e){r.hasClass("in-scrolling")&&r.removeClass("in-scrolling")})},E=function(){var t,n;i.bind("mousedown.perfect-scroll",function(e){n=e.pageY,t=i.position().top,i.addClass("in-scrolling"),e.stopPropagation(),e.preventDefault()}),e(window).bind("mousemove.perfect-scroll",function(e){i.hasClass("in-scrolling")&&(b(t,e.pageY-n),v(),e.stopPropagation(),e.preventDefault())}),e(window).bind("mouseup.perfect-scroll",function(e){i.hasClass("in-scrolling")&&i.removeClass("in-scrolling")})},S=function(){t.mousewheel(function(e,n,r,i){t.scrollTop(t.scrollTop()-i*10),t.scrollLeft(t.scrollLeft()+r*10),g(),(a>o||u>s)&&e.preventDefault()})};return g(),w(),E(),t.mousewheel&&S(),t}})(jQuery); \ No newline at end of file diff --git a/src/perfect-scrollbar.css b/src/perfect-scrollbar.css index 1a5454e..4b69c79 100644 --- a/src/perfect-scrollbar.css +++ b/src/perfect-scrollbar.css @@ -1,3 +1,19 @@ +.ps-container .ps-scrollbar-x { + position: absolute; + height: 10px; + bottom: 5px; + background-color: gray; +} + +.ps-container .ps-scrollbar-x:hover { + background-color: black; + cursor:default; +} + +.ps-container .ps-scrollbar-x.in-scrolling { + background-color: black; +} + .ps-container .ps-scrollbar-y { position: absolute; width: 10px; diff --git a/src/perfect-scrollbar.js b/src/perfect-scrollbar.js index 74051a2..1d41383 100644 --- a/src/perfect-scrollbar.js +++ b/src/perfect-scrollbar.js @@ -3,30 +3,75 @@ */ ((function($) { $.fn.perfectScrollbar = function() { - var $this = $(this), + var $this = $(this).addClass('ps-container'), $content = $(this).children(), + $scrollbar_x = $("
").appendTo($this), $scrollbar_y = $("
").appendTo($this), + container_width, container_height, + content_width, content_height, + scrollbar_x_width, + scrollbar_x_left, + scrollbar_x_bottom = parseInt($scrollbar_x.css('bottom')), scrollbar_y_height, - scrollbar_y_top; - - // add class - $this.addClass('ps-container'); + scrollbar_y_top, + scrollbar_y_right = parseInt($scrollbar_y.css('right')); var updateContentScrollTop = function() { - $this.scrollTop(parseInt(scrollbar_y_top * content_height / container_height)); + var scroll_top = parseInt(scrollbar_y_top * content_height / container_height); + $this.scrollTop(scroll_top); + $scrollbar_x.css({bottom: scrollbar_x_bottom - scroll_top}); + }; + + var updateContentScrollLeft = function() { + var scroll_left = parseInt(scrollbar_x_left * content_width / container_width); + $this.scrollLeft(scroll_left); + $scrollbar_y.css({right: scrollbar_y_right - scroll_left}); }; var updateBarSizeAndPosition = function() { + container_width = $this.width(); container_height = $this.height(); + content_width = $content.width(); content_height = $content.height(); - scrollbar_y_height = parseInt(container_height * container_height / content_height); - scrollbar_y_top = parseInt($this.scrollTop() * container_height / content_height); + if(container_width < content_width) { + scrollbar_x_width = parseInt(container_width * container_width / content_width); + scrollbar_x_left = parseInt($this.scrollLeft() * container_width / content_width); + } + else { + scrollbar_x_width = 0; + scrollbar_x_left = 0; + } + if(container_height < content_height) { + scrollbar_y_height = parseInt(container_height * container_height / content_height); + scrollbar_y_top = parseInt($this.scrollTop() * container_height / content_height); + } + else { + scrollbar_y_height = 0; + scrollbar_y_left = 0; + } - $scrollbar_y.css({top: scrollbar_y_top + $this.scrollTop(), height: scrollbar_y_height}); + $scrollbar_x.css({left: scrollbar_x_left + $this.scrollLeft(), bottom: scrollbar_x_bottom - $this.scrollTop(), width: scrollbar_x_width}); + $scrollbar_y.css({top: scrollbar_y_top + $this.scrollTop(), right: scrollbar_y_right - $this.scrollLeft(), height: scrollbar_y_height}); }; + var moveBarX = function(current_left, delta_x) { + var new_left = current_left + delta_x, + max_left = container_width - scrollbar_x_width; + + if(new_left < 0) { + scrollbar_x_left = 0; + } + else if(new_left > max_left) { + scrollbar_x_left = max_left; + } + else { + scrollbar_x_left = new_left; + } + $scrollbar_x.css({left: scrollbar_x_left + $this.scrollLeft()}); + } + var moveBarY = function(current_top, delta_y) { var new_top = current_top + delta_y, max_top = container_height - scrollbar_y_height; @@ -43,6 +88,34 @@ $scrollbar_y.css({top: scrollbar_y_top + $this.scrollTop()}); }; + var bindMouseScrollXHandler = function() { + var current_left, + current_page_x; + + $scrollbar_x.bind('mousedown.perfect-scroll', function(e) { + current_page_x = e.pageX; + current_left = $scrollbar_x.position().left; + $scrollbar_x.addClass('in-scrolling'); + e.stopPropagation(); + e.preventDefault(); + }); + + $(window).bind('mousemove.perfect-scroll', function(e) { + if($scrollbar_x.hasClass('in-scrolling')) { + moveBarX(current_left, e.pageX - current_page_x); + updateContentScrollLeft(); + e.stopPropagation(); + e.preventDefault(); + } + }); + + $(window).bind('mouseup.perfect-scroll', function(e) { + if($scrollbar_x.hasClass('in-scrolling')) { + $scrollbar_x.removeClass('in-scrolling'); + } + }); + }; + var bindMouseScrollYHandler = function() { var current_top, current_page_y; @@ -80,12 +153,15 @@ // update bar position updateBarSizeAndPosition(); - e.preventDefault(); + if(content_height > container_height || content_width > container_width) { + e.preventDefault(); + } }); }; // initialize updateBarSizeAndPosition(); + bindMouseScrollXHandler(); bindMouseScrollYHandler(); if($this.mousewheel) bindMouseWheelHandler();