254 lines
7.3 KiB
JavaScript
254 lines
7.3 KiB
JavaScript
"use strict";
|
|
|
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
var _vue = require("vue");
|
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
var _classNames = _interopRequireDefault(require("../_util/classNames"));
|
|
var _createRef = _interopRequireDefault(require("../_util/createRef"));
|
|
var _raf = _interopRequireDefault(require("../_util/raf"));
|
|
var _supportsPassive = _interopRequireDefault(require("../_util/supportsPassive"));
|
|
const MIN_SIZE = 20;
|
|
function getPageY(e) {
|
|
return 'touches' in e ? e.touches[0].pageY : e.pageY;
|
|
}
|
|
var _default = exports.default = (0, _vue.defineComponent)({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
name: 'ScrollBar',
|
|
inheritAttrs: false,
|
|
props: {
|
|
prefixCls: String,
|
|
scrollTop: Number,
|
|
scrollHeight: Number,
|
|
height: Number,
|
|
count: Number,
|
|
onScroll: {
|
|
type: Function
|
|
},
|
|
onStartMove: {
|
|
type: Function
|
|
},
|
|
onStopMove: {
|
|
type: Function
|
|
}
|
|
},
|
|
setup() {
|
|
return {
|
|
moveRaf: null,
|
|
scrollbarRef: (0, _createRef.default)(),
|
|
thumbRef: (0, _createRef.default)(),
|
|
visibleTimeout: null,
|
|
state: (0, _vue.reactive)({
|
|
dragging: false,
|
|
pageY: null,
|
|
startTop: null,
|
|
visible: false
|
|
})
|
|
};
|
|
},
|
|
watch: {
|
|
scrollTop: {
|
|
handler() {
|
|
this.delayHidden();
|
|
},
|
|
flush: 'post'
|
|
}
|
|
},
|
|
mounted() {
|
|
var _a, _b;
|
|
(_a = this.scrollbarRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('touchstart', this.onScrollbarTouchStart, _supportsPassive.default ? {
|
|
passive: false
|
|
} : false);
|
|
(_b = this.thumbRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('touchstart', this.onMouseDown, _supportsPassive.default ? {
|
|
passive: false
|
|
} : false);
|
|
},
|
|
beforeUnmount() {
|
|
this.removeEvents();
|
|
clearTimeout(this.visibleTimeout);
|
|
},
|
|
methods: {
|
|
delayHidden() {
|
|
clearTimeout(this.visibleTimeout);
|
|
this.state.visible = true;
|
|
this.visibleTimeout = setTimeout(() => {
|
|
this.state.visible = false;
|
|
}, 2000);
|
|
},
|
|
onScrollbarTouchStart(e) {
|
|
e.preventDefault();
|
|
},
|
|
onContainerMouseDown(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
},
|
|
// ======================= Clean =======================
|
|
patchEvents() {
|
|
window.addEventListener('mousemove', this.onMouseMove);
|
|
window.addEventListener('mouseup', this.onMouseUp);
|
|
this.thumbRef.current.addEventListener('touchmove', this.onMouseMove, _supportsPassive.default ? {
|
|
passive: false
|
|
} : false);
|
|
this.thumbRef.current.addEventListener('touchend', this.onMouseUp);
|
|
},
|
|
removeEvents() {
|
|
window.removeEventListener('mousemove', this.onMouseMove);
|
|
window.removeEventListener('mouseup', this.onMouseUp);
|
|
this.scrollbarRef.current.removeEventListener('touchstart', this.onScrollbarTouchStart, _supportsPassive.default ? {
|
|
passive: false
|
|
} : false);
|
|
if (this.thumbRef.current) {
|
|
this.thumbRef.current.removeEventListener('touchstart', this.onMouseDown, _supportsPassive.default ? {
|
|
passive: false
|
|
} : false);
|
|
this.thumbRef.current.removeEventListener('touchmove', this.onMouseMove, _supportsPassive.default ? {
|
|
passive: false
|
|
} : false);
|
|
this.thumbRef.current.removeEventListener('touchend', this.onMouseUp);
|
|
}
|
|
_raf.default.cancel(this.moveRaf);
|
|
},
|
|
// ======================= Thumb =======================
|
|
onMouseDown(e) {
|
|
const {
|
|
onStartMove
|
|
} = this.$props;
|
|
(0, _extends2.default)(this.state, {
|
|
dragging: true,
|
|
pageY: getPageY(e),
|
|
startTop: this.getTop()
|
|
});
|
|
onStartMove();
|
|
this.patchEvents();
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
},
|
|
onMouseMove(e) {
|
|
const {
|
|
dragging,
|
|
pageY,
|
|
startTop
|
|
} = this.state;
|
|
const {
|
|
onScroll
|
|
} = this.$props;
|
|
_raf.default.cancel(this.moveRaf);
|
|
if (dragging) {
|
|
const offsetY = getPageY(e) - pageY;
|
|
const newTop = startTop + offsetY;
|
|
const enableScrollRange = this.getEnableScrollRange();
|
|
const enableHeightRange = this.getEnableHeightRange();
|
|
const ptg = enableHeightRange ? newTop / enableHeightRange : 0;
|
|
const newScrollTop = Math.ceil(ptg * enableScrollRange);
|
|
this.moveRaf = (0, _raf.default)(() => {
|
|
onScroll(newScrollTop);
|
|
});
|
|
}
|
|
},
|
|
onMouseUp() {
|
|
const {
|
|
onStopMove
|
|
} = this.$props;
|
|
this.state.dragging = false;
|
|
onStopMove();
|
|
this.removeEvents();
|
|
},
|
|
// ===================== Calculate =====================
|
|
getSpinHeight() {
|
|
const {
|
|
height,
|
|
scrollHeight
|
|
} = this.$props;
|
|
let baseHeight = height / scrollHeight * 100;
|
|
baseHeight = Math.max(baseHeight, MIN_SIZE);
|
|
baseHeight = Math.min(baseHeight, height / 2);
|
|
return Math.floor(baseHeight);
|
|
},
|
|
getEnableScrollRange() {
|
|
const {
|
|
scrollHeight,
|
|
height
|
|
} = this.$props;
|
|
return scrollHeight - height || 0;
|
|
},
|
|
getEnableHeightRange() {
|
|
const {
|
|
height
|
|
} = this.$props;
|
|
const spinHeight = this.getSpinHeight();
|
|
return height - spinHeight || 0;
|
|
},
|
|
getTop() {
|
|
const {
|
|
scrollTop
|
|
} = this.$props;
|
|
const enableScrollRange = this.getEnableScrollRange();
|
|
const enableHeightRange = this.getEnableHeightRange();
|
|
if (scrollTop === 0 || enableScrollRange === 0) {
|
|
return 0;
|
|
}
|
|
const ptg = scrollTop / enableScrollRange;
|
|
return ptg * enableHeightRange;
|
|
},
|
|
// Not show scrollbar when height is large than scrollHeight
|
|
showScroll() {
|
|
const {
|
|
height,
|
|
scrollHeight
|
|
} = this.$props;
|
|
return scrollHeight > height;
|
|
}
|
|
},
|
|
render() {
|
|
// eslint-disable-next-line no-unused-vars
|
|
const {
|
|
dragging,
|
|
visible
|
|
} = this.state;
|
|
const {
|
|
prefixCls
|
|
} = this.$props;
|
|
const spinHeight = this.getSpinHeight() + 'px';
|
|
const top = this.getTop() + 'px';
|
|
const canScroll = this.showScroll();
|
|
const mergedVisible = canScroll && visible;
|
|
return (0, _vue.createVNode)("div", {
|
|
"ref": this.scrollbarRef,
|
|
"class": (0, _classNames.default)(`${prefixCls}-scrollbar`, {
|
|
[`${prefixCls}-scrollbar-show`]: canScroll
|
|
}),
|
|
"style": {
|
|
width: '8px',
|
|
top: 0,
|
|
bottom: 0,
|
|
right: 0,
|
|
position: 'absolute',
|
|
display: mergedVisible ? undefined : 'none'
|
|
},
|
|
"onMousedown": this.onContainerMouseDown,
|
|
"onMousemove": this.delayHidden
|
|
}, [(0, _vue.createVNode)("div", {
|
|
"ref": this.thumbRef,
|
|
"class": (0, _classNames.default)(`${prefixCls}-scrollbar-thumb`, {
|
|
[`${prefixCls}-scrollbar-thumb-moving`]: dragging
|
|
}),
|
|
"style": {
|
|
width: '100%',
|
|
height: spinHeight,
|
|
top,
|
|
left: 0,
|
|
position: 'absolute',
|
|
background: 'rgba(0, 0, 0, 0.5)',
|
|
borderRadius: '99px',
|
|
cursor: 'pointer',
|
|
userSelect: 'none'
|
|
},
|
|
"onMousedown": this.onMouseDown
|
|
}, null)]);
|
|
}
|
|
}); |