vue3拖拽滚动组件封装

1.添加拖拽滚动组件 drag.vue

<template>
    <div class="drag-outer"
       ref="dragWrap"
       :style="`--cursor: ${state.isMousedown ? 'grabbing' : 'grab'}`"
       @mouseleave="state.isMousedown = false"
       @mouseup.stop="state.isMousedown = false"
       @mousemove="dragMousemove">
    <div class="drag-inner"
         ref="dragElement"
         @mousedown="dragMousedown"
         @mouseup.stop="state.isMousedown = false">
      <slot></slot>
    </div>
</div>

</template>

<script lang="ts" setup>
import { useEventListener } from '@vueuse/core'
const props = withDefaults(defineProps<{
    scaleZoom: any,
}>(), {
  scaleZoom: {
    max: 5,
    min: 0.5
  }
})
const dragElement = ref()
const dragWrap = ref()
const state = reactive({
    isMousedown: false,
    moveStart: {},
    scale: 1,
    scrollTopStart: 0,
    scrollLeftStart: 0
})
function handleScroll(e) {
    if (e.ctrlKey) {
        event.preventDefault();
        let speed = e.wheelDelta / 120
        if (e.wheelDelta > 0 && state.scale < props.scaleZoom.max) {
            state.scale += 0.2 * speed
            dragElement.value.style.scale = state.scale
        } else if (e.wheelDelta < 0 && state.scale > props.scaleZoom.min) {
            state.scale += 0.2 * speed
            dragElement.value.style.scale = state.scale
        }
    }
}
function dragMousedown(event) {
    event.preventDefault();
    state.moveStart.x = event.clientX
    state.moveStart.y = event.clientY
    state.scrollTopStart = dragWrap.value.scrollTop
    state.scrollLeftStart = dragWrap.value.scrollLeft
    state.isMousedown = true
}
function dragMousemove(event) {
    if (state.isMousedown) {
        const xDiff = event.clientX - state.moveStart.x;
        const yDiff = event.clientY - state.moveStart.y;
        const scrollTop = state.scrollTopStart - yDiff;
        const scrollLeft = state.scrollLeftStart - xDiff;
        dragWrap.value.scrollTop = scrollTop;
        dragWrap.value.scrollLeft = scrollLeft;
    }
}
onMounted(() => {
    useEventListener(dragWrap, 'mousewheel', handleScroll)
})
</script>

<style lang="scss" scoped>
.drag-outer {
    height:100%;
    width: 100%;
    overflow: auto;
    background-color:#fff;
    .drag-inner {
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: var(--cursor);
        transform-origin: top left;
    }
}
</style>

  1. 使用拖拽滚动组件
<Drag>
        <el-image :src="state.url" fit="contain">
            <template #error>
                <div class="image-slot">
                    <el-icon><icon-picture /></el-icon>
                </div>
            </template>
        </el-image>
</Drag>
  1. 踩过的坑
    • 放大后中心点会有偏移,所以需要指定中心点
      transform-origin: top left;
      
      如果有更好的方法,欢迎大佬指点。
    • 计算逻辑
      初始滚动位置-鼠标位移差
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值