Merge pull request #320 from jaronkk/scrollbar-margins

Support large and percentage margins on scrollbar rails
This commit is contained in:
Jun 2015-04-14 13:56:47 +09:00
commit 08d559561e
7 changed files with 53 additions and 26 deletions

View File

@ -6,27 +6,39 @@
<link href="../dist/css/perfect-scrollbar.css" rel="stylesheet"> <link href="../dist/css/perfect-scrollbar.css" rel="stylesheet">
<script src="../dist/js/perfect-scrollbar.js"></script> <script src="../dist/js/perfect-scrollbar.js"></script>
<style> <style>
.contentHolder { position:relative; margin:0px auto; padding:0px; width: 600px; height: 400px; overflow: auto; } h1 { text-align: center; }
.contentHolder .content { background-image: url('./azusa.jpg'); width: 1280px; height: 720px; } .container { position:relative; margin:0px auto; padding:0px; width: 600px; height: 400px; overflow: auto; }
.spacer { text-align:center } .container .content { background-image: url('./azusa.jpg'); width: 1280px; height: 720px; }
.ps-scrollbar-x-rail { .large-margin .ps-scrollbar-x-rail {
margin: 0 3px; margin: 0 25%;
opacity: 0.5;
background-color: #eee;
} }
.ps-scrollbar-y-rail { .large-margin .ps-scrollbar-y-rail {
margin: 3px 0; margin: 100px 0;
opacity: 0.5;
background-color: #eee;
} }
</style> </style>
</head> </head>
<body> <body>
<div id="Default" class="contentHolder"> <h1>Default</h1>
<div class="container">
<div class="content">
</div>
</div>
<h1>Margins</h1>
<div class="container large-margin">
<div class="content"> <div class="content">
</div> </div>
</div> </div>
<script> <script>
var $ = document.querySelector.bind(document);
window.onload = function () { window.onload = function () {
Ps.initialize($('#Default')); [].forEach.call(document.querySelectorAll('.container'), function (el) {
Ps.initialize(el);
});
}; };
</script> </script>
</body> </body>

View File

@ -125,7 +125,7 @@ gulp.task('connect', ['build'], function () {
gulp.task('watch', function () { gulp.task('watch', function () {
gulp.watch(['src/js/**/*'], ['js']); gulp.watch(['src/js/**/*'], ['js']);
gulp.watch(['src/css/**/*'], ['css']); gulp.watch(['src/css/**/*'], ['sass']);
}); });
gulp.task('serve', ['connect', 'watch']); gulp.task('serve', ['connect', 'watch']);

View File

@ -16,8 +16,8 @@ function bindClickRailHandler(element, i) {
i.event.bind(i.scrollbarY, 'click', stopPropagation); i.event.bind(i.scrollbarY, 'click', stopPropagation);
i.event.bind(i.scrollbarYRail, 'click', function (e) { i.event.bind(i.scrollbarYRail, 'click', function (e) {
var halfOfScrollbarLength = h.toInt(i.scrollbarYHeight / 2); var halfOfScrollbarLength = h.toInt(i.scrollbarYHeight / 2);
var positionTop = e.pageY - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength; var positionTop = i.railYRatio * (e.pageY - window.scrollY - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength);
var maxPositionTop = i.containerHeight - i.scrollbarYHeight; var maxPositionTop = i.railYRatio * (i.railYHeight - i.scrollbarYHeight);
var positionRatio = positionTop / maxPositionTop; var positionRatio = positionTop / maxPositionTop;
if (positionRatio < 0) { if (positionRatio < 0) {
@ -33,9 +33,8 @@ function bindClickRailHandler(element, i) {
i.event.bind(i.scrollbarX, 'click', stopPropagation); i.event.bind(i.scrollbarX, 'click', stopPropagation);
i.event.bind(i.scrollbarXRail, 'click', function (e) { i.event.bind(i.scrollbarXRail, 'click', function (e) {
var halfOfScrollbarLength = h.toInt(i.scrollbarXWidth / 2); var halfOfScrollbarLength = h.toInt(i.scrollbarXWidth / 2);
var positionLeft = e.pageX - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength; var positionLeft = i.railXRatio * (e.pageX - window.scrollX - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength);
console.log(e.pageX, i.scrollbarXRail.offsetLeft); var maxPositionLeft = i.railXRatio * (i.railXWidth - i.scrollbarXWidth);
var maxPositionLeft = i.containerWidth - i.scrollbarXWidth;
var positionRatio = positionLeft / maxPositionLeft; var positionRatio = positionLeft / maxPositionLeft;
if (positionRatio < 0) { if (positionRatio < 0) {

View File

@ -13,8 +13,8 @@ function bindMouseScrollXHandler(element, i) {
var currentPageX = null; var currentPageX = null;
function updateScrollLeft(deltaX) { function updateScrollLeft(deltaX) {
var newLeft = currentLeft + deltaX; var newLeft = currentLeft + (deltaX * i.railXRatio);
var maxLeft = i.containerWidth - i.scrollbarXWidth; var maxLeft = i.scrollbarXRail.getBoundingClientRect().left + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth));
if (newLeft < 0) { if (newLeft < 0) {
i.scrollbarXLeft = 0; i.scrollbarXLeft = 0;
@ -24,7 +24,7 @@ function bindMouseScrollXHandler(element, i) {
i.scrollbarXLeft = newLeft; i.scrollbarXLeft = newLeft;
} }
var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - i.scrollbarXWidth)); var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth)));
element.scrollLeft = scrollLeft; element.scrollLeft = scrollLeft;
} }
@ -42,7 +42,7 @@ function bindMouseScrollXHandler(element, i) {
i.event.bind(i.scrollbarX, 'mousedown', function (e) { i.event.bind(i.scrollbarX, 'mousedown', function (e) {
currentPageX = e.pageX; currentPageX = e.pageX;
currentLeft = h.toInt(d.css(i.scrollbarX, 'left')); currentLeft = h.toInt(d.css(i.scrollbarX, 'left')) * i.railXRatio;
h.startScrolling(element, 'x'); h.startScrolling(element, 'x');
i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler); i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
@ -58,8 +58,8 @@ function bindMouseScrollYHandler(element, i) {
var currentPageY = null; var currentPageY = null;
function updateScrollTop(deltaY) { function updateScrollTop(deltaY) {
var newTop = currentTop + deltaY; var newTop = currentTop + (deltaY * i.railYRatio);
var maxTop = i.containerHeight - i.scrollbarYHeight; var maxTop = i.scrollbarYRail.getBoundingClientRect().top + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight));
if (newTop < 0) { if (newTop < 0) {
i.scrollbarYTop = 0; i.scrollbarYTop = 0;
@ -69,7 +69,7 @@ function bindMouseScrollYHandler(element, i) {
i.scrollbarYTop = newTop; i.scrollbarYTop = newTop;
} }
var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - i.scrollbarYHeight)); var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight)));
element.scrollTop = scrollTop; element.scrollTop = scrollTop;
} }
@ -87,7 +87,7 @@ function bindMouseScrollYHandler(element, i) {
i.event.bind(i.scrollbarY, 'mousedown', function (e) { i.event.bind(i.scrollbarY, 'mousedown', function (e) {
currentPageY = e.pageY; currentPageY = e.pageY;
currentTop = h.toInt(d.css(i.scrollbarY, 'top')); currentTop = h.toInt(d.css(i.scrollbarY, 'top')) * i.railYRatio;
h.startScrolling(element, 'y'); h.startScrolling(element, 'y');
i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler); i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);

View File

@ -33,8 +33,12 @@ function Instance(element) {
i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN
i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : h.toInt(d.css(i.scrollbarXRail, 'top')); i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : h.toInt(d.css(i.scrollbarXRail, 'top'));
i.railBorderXWidth = h.toInt(d.css(i.scrollbarXRail, 'borderLeftWidth')) + h.toInt(d.css(i.scrollbarXRail, 'borderRightWidth')); i.railBorderXWidth = h.toInt(d.css(i.scrollbarXRail, 'borderLeftWidth')) + h.toInt(d.css(i.scrollbarXRail, 'borderRightWidth'));
// Set rail to display:block to calculate margins
d.css(i.scrollbarXRail, 'display', 'block');
i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight')); i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight'));
d.css(i.scrollbarXRail, 'display', '');
i.railXWidth = null; i.railXWidth = null;
i.railXRatio = null;
i.scrollbarYRail = d.appendTo(d.e('div', 'ps-scrollbar-y-rail'), element); i.scrollbarYRail = d.appendTo(d.e('div', 'ps-scrollbar-y-rail'), element);
i.scrollbarY = d.appendTo(d.e('div', 'ps-scrollbar-y'), i.scrollbarYRail); i.scrollbarY = d.appendTo(d.e('div', 'ps-scrollbar-y'), i.scrollbarYRail);
@ -46,8 +50,11 @@ function Instance(element) {
i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : h.toInt(d.css(i.scrollbarYRail, 'left')); i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : h.toInt(d.css(i.scrollbarYRail, 'left'));
i.scrollbarYOuterWidth = i.isRtl ? h.outerWidth(i.scrollbarY) : null; i.scrollbarYOuterWidth = i.isRtl ? h.outerWidth(i.scrollbarY) : null;
i.railBorderYWidth = h.toInt(d.css(i.scrollbarYRail, 'borderTopWidth')) + h.toInt(d.css(i.scrollbarYRail, 'borderBottomWidth')); i.railBorderYWidth = h.toInt(d.css(i.scrollbarYRail, 'borderTopWidth')) + h.toInt(d.css(i.scrollbarYRail, 'borderBottomWidth'));
d.css(i.scrollbarYRail, 'display', 'block');
i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom')); i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom'));
d.css(i.scrollbarYRail, 'display', '');
i.railYHeight = null; i.railYHeight = null;
i.railYRatio = null;
} }
function getId(element) { function getId(element) {

View File

@ -70,6 +70,7 @@ module.exports = function (element) {
if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) { if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) {
i.scrollbarXActive = true; i.scrollbarXActive = true;
i.railXWidth = i.containerWidth - i.railXMarginWidth; i.railXWidth = i.containerWidth - i.railXMarginWidth;
i.railXRatio = i.containerWidth / i.railXWidth;
i.scrollbarXWidth = getThumbSize(i, h.toInt(i.railXWidth * i.containerWidth / i.contentWidth)); i.scrollbarXWidth = getThumbSize(i, h.toInt(i.railXWidth * i.containerWidth / i.contentWidth));
i.scrollbarXLeft = h.toInt(element.scrollLeft * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth)); i.scrollbarXLeft = h.toInt(element.scrollLeft * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth));
} else { } else {
@ -82,6 +83,7 @@ module.exports = function (element) {
if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) { if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) {
i.scrollbarYActive = true; i.scrollbarYActive = true;
i.railYHeight = i.containerHeight - i.railYMarginHeight; i.railYHeight = i.containerHeight - i.railYMarginHeight;
i.railYRatio = i.containerHeight / i.railYHeight;
i.scrollbarYHeight = getThumbSize(i, h.toInt(i.railYHeight * i.containerHeight / i.contentHeight)); i.scrollbarYHeight = getThumbSize(i, h.toInt(i.railYHeight * i.containerHeight / i.contentHeight));
i.scrollbarYTop = h.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight)); i.scrollbarYTop = h.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight));
} else { } else {

View File

@ -4,18 +4,25 @@
'use strict'; 'use strict';
var d = require('../lib/dom') var d = require('../lib/dom')
, h = require('../lib/helper')
, instances = require('./instances') , instances = require('./instances')
, updateGeometry = require('./update-geometry'); , updateGeometry = require('./update-geometry');
module.exports = function (element) { module.exports = function (element) {
var i = instances.get(element); var i = instances.get(element);
// Recalculate rail margins
d.css(i.scrollbarXRail, 'display', 'block');
d.css(i.scrollbarYRail, 'display', 'block');
i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight'));
i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom'));
// Hide scrollbars not to affect scrollWidth and scrollHeight // Hide scrollbars not to affect scrollWidth and scrollHeight
d.css(i.scrollbarXRail, 'display', 'none'); d.css(i.scrollbarXRail, 'display', 'none');
d.css(i.scrollbarYRail, 'display', 'none'); d.css(i.scrollbarYRail, 'display', 'none');
updateGeometry(element); updateGeometry(element);
d.css(i.scrollbarXRail, 'display', 'block'); d.css(i.scrollbarXRail, 'display', '');
d.css(i.scrollbarYRail, 'display', 'block'); d.css(i.scrollbarYRail, 'display', '');
}; };