js实现以鼠标所在点元素为中心对页面进行缩放与拖拽功能

vue组件

<template>
	<div id="mydiv"></div>
</template>

<script setup>
import {onMounted} from 'vue';
import {mouseEvent} from "@/assets/js/pageEventSc";

onMounted(() => {
  //缩放与拖拽
  mouseEvent("#publicSvg", 0.5);
});

</script>

pageEventSc.js

import $ from 'jquery';

/**
 *
 * @param target 传入控制的dom元素
 * @param initialScale 传入控制的dom元素
 * @param type 特殊类型
 * 此方法不适用于canvas操作
 */

export function mouseEvent(target, initialScale = 0.1, type = "") {
    (function () {
        let isElement = (obj) => {
            return typeof HTMLElement === "object"
                ? obj instanceof HTMLElement
                : !!(
                    obj &&
                    typeof obj === "object" &&
                    (obj.nodeType === 1 || obj.nodeType === 9) &&
                    typeof obj.nodeName === "string"
                )
        }

        /**
         * 被拖拽物、被缩放元素
         */
        let drawEl = target;
        if (!isElement(target)) {
            drawEl = document.querySelector(target)
        }

        /**
         * 父元素:容器
         */
        const parent = drawEl.parentElement

        /**
         * 获取父元素的大小及其相对于视口的位置。
         */
        const parentRect = parent.getBoundingClientRect()

        /**
         * 鼠标相对于目标物缩放点的距离
         */
        let diffX = 0,
            diffY = 0

        /**
         * 是否正在拖拽
         */
        let isDrawing = false

        /**
         * 鼠标当前相对于父容器的坐标
         */
        let mouseX = 0,
            mouseY = 0

        /**
         * 偏移坐标,缩放比例
         */
        let translateX = 0,
            translateY = 0
        let scale = initialScale

        /**
         * 一次缩放的比例
         */
        const diff = 0.05

        /**
         * 滚轮滚动方向是否向上
         * 向上,缩小
         * 向下,放大
         */
        let isUpward = false


        /**
         * 刷新鼠标距离目标元素缩放点的距离
         */
        let refreshMousePositionDiffValue = () => {
            diffX = mouseX - translateX
            diffY = mouseY - translateY
        }

        /**
         * 更新样式
         */
        let refreshTargetStyle = () => {
            setTimeout(() => {
                drawEl.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`
                parent.style.cursor = isDrawing ? "move" : "default"
            }, 0)
        }

        /**
         * 鼠标移动事件
         */
        parent.addEventListener("mousemove", (e) => {
            mouseX = e.x - parentRect.left
            mouseY = e.y - parentRect.top

            if (isDrawing) {

                translateX = mouseX - diffX
                translateY = mouseY - diffY

                refreshTargetStyle()
            }
        })

        /**
         * 鼠标按下事件
         */
        parent.addEventListener("mousedown", (e) => {
            if (e.button === 1) {
                refreshMousePositionDiffValue()
                isDrawing = true
                refreshTargetStyle()
            }
        })

        /**
         * 鼠标抬起事件
         */
        window.addEventListener("mouseup", () => {
            isDrawing = false
            refreshTargetStyle()
        })

        /**
         * 鼠标滚动事件
         */

        let mouseZoom = (e) => {
            e = e || window.event

            if (e.wheelDelta) {
                isUpward = e.wheelDelta > 0
            } else if (e.detail) {
                isUpward = e.detail < 0
            }

            let oldWidth = scale * drawEl.clientWidth
            let oldHeight = scale * drawEl.clientHeight
            // console.log("当前原始值:", scale)
            if (isUpward && scale < 2.5) {
                scale += diff;
            } else if (!isUpward && scale > 0.06) {
                scale -= diff
            }
            let s = scale.toFixed(1);
            let dom1 = document.querySelector(".msg-li li") !== null;
            let dom2 = document.querySelector(".msg-li li") !== undefined;
            if ((dom1 || dom2) && s === "0.8") {
                $(".msg-box").show();
            } else {
                $(".msg-box").hide();
            }

            let newWidth = scale * drawEl.clientWidth
            let newHeight = scale * drawEl.clientHeight

            //刷新鼠标距离目标元素缩放点坐标
            refreshMousePositionDiffValue()

            /**
             * 重新计算缩放偏移量
             */
            translateX -= (newWidth - oldWidth) * (diffX / oldWidth)
            translateY -= (newHeight - oldHeight) * (diffY / oldHeight)

            refreshTargetStyle()
        }

        // if (document.attachEvent) {
        //     parent.attachEvent("onmousewheel", mouseZoom)
        // }
        if (document.addEventListener) {
            parent.addEventListener("wheel", mouseZoom, false)
        }
        // parent.onmousewheel = mouseZoom


        /**
         * 页面初始化
         */

        /**
         * 判断缩放元素高度是否高于容器高度
         * 如果大于,则缩放值容器高度
         */
        if ((drawEl.clientHeight > parent.clientHeight) && type !== "plzh") {
            scale = 1 - (drawEl.clientHeight - parent.clientHeight) / drawEl.clientHeight
            // console.log(drawEl.clientHeight, parent.clientHeight)
            // console.log(scale)
        }

        /**
         * 让目标元素居中显示
         */
        translateX = (parent.clientWidth - (scale * drawEl.clientWidth)) / 2
        translateY = (parent.clientHeight - (scale * drawEl.clientHeight)) / 2

        //设置初始样式
        drawEl.style.transformOrigin = "0 0"

        /**
         * 当目标元素 是img时,需要禁用元素鼠标可拖拽
         * div user-drag 默认是none 可以不设置
         */
        drawEl.style.userDrag = 'none'
        drawEl.style.webkitUserDrag = 'none';

        //禁用选则,防止拖拽时出现先择元素内部元素的情况
        drawEl.style.userSelect = 'none'

        refreshTargetStyle()
    })()
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值