@aplus-frontend/antdv
Version:
Vue basic component library maintained based on ant-design-vue
254 lines (253 loc) • 7.46 kB
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)]);
}
});