You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
4.5 KiB
162 lines
4.5 KiB
1 year ago
|
import * as CSS from './lib/css';
|
||
|
import * as DOM from './lib/dom';
|
||
|
import cls from './lib/class-names';
|
||
|
import { toInt } from './lib/util';
|
||
|
|
||
|
export default function(i) {
|
||
|
const element = i.element;
|
||
|
const roundedScrollTop = Math.floor(element.scrollTop);
|
||
|
|
||
|
i.containerWidth = element.clientWidth;
|
||
|
i.containerHeight = element.clientHeight;
|
||
|
i.contentWidth = element.scrollWidth;
|
||
|
i.contentHeight = element.scrollHeight;
|
||
|
|
||
|
if (!element.contains(i.scrollbarXRail)) {
|
||
|
// clean up and append
|
||
|
DOM.queryChildren(element, cls.element.rail('x')).forEach(el =>
|
||
|
DOM.remove(el)
|
||
|
);
|
||
|
element.appendChild(i.scrollbarXRail);
|
||
|
}
|
||
|
if (!element.contains(i.scrollbarYRail)) {
|
||
|
// clean up and append
|
||
|
DOM.queryChildren(element, cls.element.rail('y')).forEach(el =>
|
||
|
DOM.remove(el)
|
||
|
);
|
||
|
element.appendChild(i.scrollbarYRail);
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
!i.settings.suppressScrollX &&
|
||
|
i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth
|
||
|
) {
|
||
|
i.scrollbarXActive = true;
|
||
|
i.railXWidth = i.containerWidth - i.railXMarginWidth;
|
||
|
i.railXRatio = i.containerWidth / i.railXWidth;
|
||
|
i.scrollbarXWidth = getThumbSize(
|
||
|
i,
|
||
|
toInt(i.railXWidth * i.containerWidth / i.contentWidth)
|
||
|
);
|
||
|
i.scrollbarXLeft = toInt(
|
||
|
(i.negativeScrollAdjustment + element.scrollLeft) *
|
||
|
(i.railXWidth - i.scrollbarXWidth) /
|
||
|
(i.contentWidth - i.containerWidth)
|
||
|
);
|
||
|
} else {
|
||
|
i.scrollbarXActive = false;
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
!i.settings.suppressScrollY &&
|
||
|
i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight
|
||
|
) {
|
||
|
i.scrollbarYActive = true;
|
||
|
i.railYHeight = i.containerHeight - i.railYMarginHeight;
|
||
|
i.railYRatio = i.containerHeight / i.railYHeight;
|
||
|
i.scrollbarYHeight = getThumbSize(
|
||
|
i,
|
||
|
toInt(i.railYHeight * i.containerHeight / i.contentHeight)
|
||
|
);
|
||
|
i.scrollbarYTop = toInt(
|
||
|
roundedScrollTop *
|
||
|
(i.railYHeight - i.scrollbarYHeight) /
|
||
|
(i.contentHeight - i.containerHeight)
|
||
|
);
|
||
|
} else {
|
||
|
i.scrollbarYActive = false;
|
||
|
}
|
||
|
|
||
|
if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {
|
||
|
i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;
|
||
|
}
|
||
|
if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {
|
||
|
i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;
|
||
|
}
|
||
|
|
||
|
updateCss(element, i);
|
||
|
|
||
|
if (i.scrollbarXActive) {
|
||
|
element.classList.add(cls.state.active('x'));
|
||
|
} else {
|
||
|
element.classList.remove(cls.state.active('x'));
|
||
|
i.scrollbarXWidth = 0;
|
||
|
i.scrollbarXLeft = 0;
|
||
|
element.scrollLeft = 0;
|
||
|
}
|
||
|
if (i.scrollbarYActive) {
|
||
|
element.classList.add(cls.state.active('y'));
|
||
|
} else {
|
||
|
element.classList.remove(cls.state.active('y'));
|
||
|
i.scrollbarYHeight = 0;
|
||
|
i.scrollbarYTop = 0;
|
||
|
element.scrollTop = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function getThumbSize(i, thumbSize) {
|
||
|
if (i.settings.minScrollbarLength) {
|
||
|
thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);
|
||
|
}
|
||
|
if (i.settings.maxScrollbarLength) {
|
||
|
thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);
|
||
|
}
|
||
|
return thumbSize;
|
||
|
}
|
||
|
|
||
|
function updateCss(element, i) {
|
||
|
const xRailOffset = { width: i.railXWidth };
|
||
|
const roundedScrollTop = Math.floor(element.scrollTop);
|
||
|
|
||
|
if (i.isRtl) {
|
||
|
xRailOffset.left =
|
||
|
i.negativeScrollAdjustment +
|
||
|
element.scrollLeft +
|
||
|
i.containerWidth -
|
||
|
i.contentWidth;
|
||
|
} else {
|
||
|
xRailOffset.left = element.scrollLeft;
|
||
|
}
|
||
|
if (i.isScrollbarXUsingBottom) {
|
||
|
xRailOffset.bottom = i.scrollbarXBottom - roundedScrollTop;
|
||
|
} else {
|
||
|
xRailOffset.top = i.scrollbarXTop + roundedScrollTop;
|
||
|
}
|
||
|
CSS.set(i.scrollbarXRail, xRailOffset);
|
||
|
|
||
|
const yRailOffset = { top: roundedScrollTop, height: i.railYHeight };
|
||
|
if (i.isScrollbarYUsingRight) {
|
||
|
if (i.isRtl) {
|
||
|
yRailOffset.right =
|
||
|
i.contentWidth -
|
||
|
(i.negativeScrollAdjustment + element.scrollLeft) -
|
||
|
i.scrollbarYRight -
|
||
|
i.scrollbarYOuterWidth;
|
||
|
} else {
|
||
|
yRailOffset.right = i.scrollbarYRight - element.scrollLeft;
|
||
|
}
|
||
|
} else {
|
||
|
if (i.isRtl) {
|
||
|
yRailOffset.left =
|
||
|
i.negativeScrollAdjustment +
|
||
|
element.scrollLeft +
|
||
|
i.containerWidth * 2 -
|
||
|
i.contentWidth -
|
||
|
i.scrollbarYLeft -
|
||
|
i.scrollbarYOuterWidth;
|
||
|
} else {
|
||
|
yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;
|
||
|
}
|
||
|
}
|
||
|
CSS.set(i.scrollbarYRail, yRailOffset);
|
||
|
|
||
|
CSS.set(i.scrollbarX, {
|
||
|
left: i.scrollbarXLeft,
|
||
|
width: i.scrollbarXWidth - i.railBorderXWidth,
|
||
|
});
|
||
|
CSS.set(i.scrollbarY, {
|
||
|
top: i.scrollbarYTop,
|
||
|
height: i.scrollbarYHeight - i.railBorderYWidth,
|
||
|
});
|
||
|
}
|