@jdlinker/ui
Version:
jdLinker UI库,基于ant-design-vue封装
93 lines (80 loc) • 3.1 kB
text/typescript
import { defineComponent, h, computed, ref, getCurrentInstance, onUnmounted, inject } from 'vue';
import { on, off } from '@jdlinker/utils';
import { renderThumbStyle, BAR_MAP } from './util';
export default defineComponent({
name: 'Bar',
props: {
vertical: Boolean,
size: String,
move: Number,
},
setup(props) {
const instance = getCurrentInstance();
const thumb = ref();
const wrap = inject('scroll-bar-wrap', {}) as any;
const bar = computed(() => {
return BAR_MAP[props.vertical ? 'vertical' : 'horizontal'];
});
const barStore = ref<any>({});
const cursorDown = ref();
const clickThumbHandler = (e: any) => {
// prevent click event of right button
if (e.ctrlKey || e.button === 2) {
return;
}
window.getSelection()?.removeAllRanges();
startDrag(e);
barStore.value[bar.value.axis] =
e.currentTarget[bar.value.offset] - (e[bar.value.client] - e.currentTarget.getBoundingClientRect()[bar.value.direction]);
};
const clickTrackHandler = (e: any) => {
const offset = Math.abs(e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]);
const thumbHalf = thumb.value[bar.value.offset] / 2;
const thumbPositionPercentage = ((offset - thumbHalf) * 100) / instance?.vnode.el?.[bar.value.offset];
wrap.value[bar.value.scroll] = (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100;
};
const startDrag = (e: any) => {
e.stopImmediatePropagation();
cursorDown.value = true;
on(document, 'mousemove', mouseMoveDocumentHandler);
on(document, 'mouseup', mouseUpDocumentHandler);
document.onselectstart = () => false;
};
const mouseMoveDocumentHandler = (e: any) => {
if (cursorDown.value === false) return;
const prevPage = barStore.value[bar.value.axis];
if (!prevPage) return;
const offset = (instance?.vnode.el?.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]) * -1;
const thumbClickPosition = thumb.value[bar.value.offset] - prevPage;
const thumbPositionPercentage = ((offset - thumbClickPosition) * 100) / instance?.vnode.el?.[bar.value.offset];
wrap.value[bar.value.scroll] = (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100;
};
function mouseUpDocumentHandler() {
cursorDown.value = false;
barStore.value[bar.value.axis] = 0;
off(document, 'mousemove', mouseMoveDocumentHandler);
document.onselectstart = null;
}
onUnmounted(() => {
off(document, 'mouseup', mouseUpDocumentHandler);
});
return () =>
h(
'div',
{
class: ['scrollbar__bar', 'is-' + bar.value.key],
onMousedown: clickTrackHandler,
},
h('div', {
ref: thumb,
class: 'scrollbar__thumb',
onMousedown: clickThumbHandler,
style: renderThumbStyle({
size: props.size,
move: props.move,
bar: bar.value,
}),
})
);
},
});