<template>
	<div class="ui-scroll scrollbox" ref="box" @mousewheel.stop.prevent="handleMouseWheel"
		@mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave"
		:style="$store.state.app.device == 'mobile' ? 'overflow:hidden scroll' : ''">
		<transition name="fade">
			<div :class="['scrollbar','pointer', { force: force }]" ref="bar" v-show="show"
				:style="{ height: barHeight + 'px', width: '5px' }" @mousedown="handleMouseDown"></div>
		</transition>
		<slot></slot>
	</div>
</template>

<script setup>
	// import { nextTick, onMounted, defineEmits } from "vue";
	const {
		proxy
	} = getCurrentInstance();

	const props = defineProps({
		scrollbar: {
			type: Boolean,
			default: false,
		},
	});

	let box = ref(null); // 自定义滚动条盒子
	let bar = ref(null); // 滚动条
	let barHeight = ref(100); // 滚动条高度
	let ratio = ref(1); // 滚动条偏移率
	let force = ref(false); // 滚动条是否被鼠标光标按住
	let hover = ref(false); // 鼠标光标是否悬停在盒子上
	let show = ref(false); // 是否显示滚动条
	const {
		scrollbar
	} = toRefs(props);

	onMounted(() => {
		nextTick(() => {
			box.value = proxy.$refs["box"];
			bar.value = proxy.$refs["bar"];
			// show = proxy.$refs["scrollbar"];
			show.value = scrollbar.value;
			// 滚动条全局可拖动
			document.addEventListener("mouseup", handleMouseUp);
			document.addEventListener("mousemove", handleMouseMove);
		});
	});

	/**
	 * 鼠标滚轮事件
	 * @param {object} e 事件
	 */
	function handleMouseWheel(e) {
		box.value.scrollTop -= e.wheelDelta / 4;
		bar.value.style.transform =
			"translateY(" + (box.value.scrollTop + box.value.scrollTop / ratio.value) + "px)";
	}
	/**
	 * 鼠标按下
	 * @param {object} e 事件
	 */
	function handleMouseDown(e) {
		if (e.target === bar.value) {
			box.value.prevY = e.pageY;
			force.value = true;
		}
	}
	/**
	 * 鼠标按键释放
	 */
	function handleMouseUp() {
		force.value = false;
		// box.value.prevY = null;
		if (!hover.value) {
			show.value = false;
		}
	}
	/**
	 * 鼠标移动
	 * @param {object} e 事件
	 */
	function handleMouseMove(e) {
		if (force.value) {
			// 阻止默认选中事件(IE下无效)
			e.preventDefault();
			box.value.scrollTop += (e.pageY - box.value.prevY) * ratio.value;
			bar.value.style.transform =
				"translateY(" + (box.value.scrollTop + box.value.scrollTop / ratio.value) + "px)";
			box.value.prevY = e.pageY;
		}
	}
	/**
	 * 鼠标光标进入盒子范围
	 */
	function handleMouseEnter() {
		hover.value = true;
		if (box.value.scrollHeight > box.value.offsetHeight) {
			// 修正进度条高度和位置(建议通过事件触发)
			barHeight.value = box.value.offsetHeight ** 2 / box.value.scrollHeight;
			ratio.value =
				(box.value.scrollHeight - box.value.offsetHeight) /
				(box.value.offsetHeight - barHeight.value);
			bar.value.style.transform =
				"translateY(" + (box.value.scrollTop + box.value.scrollTop / ratio.value) + "px)";
			// 显示滚动条
			nextTick(() => (show.value = true));
		}
	}
	/**
	 * 鼠标光标离开盒子范围
	 */
	function handleMouseLeave() {
		hover.value = false;
		if (!force.value) {
			show.value = false;
		}
	}
</script>


<style>
	.ui-scroll.scrollbox {
		width: 100%;
		height: 100%;
		position: relative;
		overflow: hidden;
	}

	.ui-scroll.scrollbox .scrollbar {
		width: var(--scrollbar-width);
		height: 100%;
		background-color: gray;
		position: absolute;
		right: 0;
		border-radius: var(--scrollbar-width) / 2;
		transition: transform 0s !important;
		border-radius: 8px;
		opacity: 0.6;
		z-index: 100;
	}

	.ui-scroll.scrollbox .scrollbar:hover {
		background-color: gray;
	}

	.ui-scroll.scrollbox .scrollbar.force {
		background-color: gray;
	}

	/* // Vue进入离开动画 */
	.fade-enter-active,
	.fade-leave-active {
		transition: opacity 0.5s;
	}

	.fade-enter,
	.fade-leave-to {
		opacity: 0;
	}
</style>