Bootstrap

konva以鼠标为中心实现 地图滚轮放大、缩小以及拖拽功能

当地图是一张图片时,如果不设置会导致放大缩小时,x、y的值默认为(0,0)。并且拖拽时地图会超出镜头。
konva中stage是舞台
stage.x(),stage.y()是地图超出视口的偏移量
在这里插入图片描述
在这里插入图片描述

// 滚轮放大缩小
import Konva from "konva";
    function mapZoom() {
        let stageX = 0;//设置最开始地图偏移量为0,0
        let stageY = 0;
        stage.on("wheel", (e) => {
            var max = 9;
            // 放大最大的比例
            var min = 1; // 缩小最小的比例
            var step = 0.4; // 每次缩放的比例
            
            // console.log('xxyy',x,y)
            if (e.evt.wheelDelta) {
                if (e.evt.wheelDelta > 0) { // 放大
                    var offsetX = e.evt.offsetX,//鼠标在视口中的位置,距离x,y的坐标
                		offsetY = e.evt.offsetY;
                        if (mapConfig.zoom >= mapConfig.zoomMax) {
                        //如果放大超出最大比例停止
                        return;
                    }
                    // mapConfig.zoom++;
                    mapConfig.zoom = mapConfig.zoom + step;
                    stageX = Math.abs(stageX) / (mapConfig.zoom - step) * mapConfig.zoom + (offsetX / (mapConfig.zoom - step) * mapConfig.zoom - offsetX);
                    stageY = Math.abs(stageY)/(mapConfig.zoom-step)* mapConfig.zoom+(offsetY / (mapConfig.zoom-step) * mapConfig.zoom- offsetY);
                    //计算偏移量
                    stage.scaleX(stage.scaleX() +step);
                    stage.scaleY(stage.scaleY() + step);
                    stage.setAttrs({
                            x: -stageX,
                            y: -stageY
                        })
                    //设置xy的移动距离
                } else {// 缩小
                    var offsetX = e.evt.offsetX,
                		offsetY = e.evt.offsetY;
                    if (mapConfig.zoom <= mapConfig.zoomMin) {
                        return;
                    }
                    mapConfig.zoom = mapConfig.zoom - step;
                    stageX = Math.abs(stageX) / (mapConfig.zoom + step) * mapConfig.zoom + (offsetX / (mapConfig.zoom + step) * mapConfig.zoom - offsetX);
                    stageY = Math.abs(stageY) / (mapConfig.zoom + step) * mapConfig.zoom + (offsetY / (mapConfig.zoom + step) * mapConfig.zoom - offsetY);
                    if (stage.scaleX() > min && stage.scaleY() > min) {
                        stage.scaleX(stage.scaleX() - step);
                        stage.scaleY(stage.scaleY() - step);
                        stage.setAttrs({ x: -stageX, y: -stageY})
                        //     // 跟随鼠标偏移位置
                    }
                }
                //保证图片在视口中不会有留白
                if (stage.x() > 0) {
                    stage.setAttrs({ x: 0 })
                    stageX=0
                }
                if (stage.x() < -(canvasSize * mapConfig.zoom - canvasSize)) {
                    stage.setAttrs({ x: -(canvasSize * mapConfig.zoom - canvasSize) })
                    stageX=-(canvasSize * mapConfig.zoom - canvasSize)
                }
                if (stage.y() > 0) {
                    stage.setAttrs({ y: 0 })
                    stageY=0
                }
                if (stage.y() < -(canvasSize * mapConfig.zoom - canvasSize)) {
                    stage.setAttrs({ y: -(canvasSize * mapConfig.zoom - canvasSize) })
                    stageY= -(canvasSize * mapConfig.zoom - canvasSize)
                }
            }
            if (mapConfig.zoom > 1) {
           	//当放大倍数大于1时鼠标可以拖动
                stage.setAttrs({ draggable: true })
                stage.on('dragmove', (e) => {
                //鼠标拖动
                    stageX = stage.x();
                    stageY = stage.y();
                    // dragZoom=mapConfig.zoom
                    // dragZoom = (-offsetX - stagex) / mapConfig.zoom;
                    // dragZoomy = (-offsetY - stagey) / mapConfig.zoom;
                    if (stage.x() > 0) {
                        stage.setAttrs({ x: 0 })
                        stageX=0
                    }
                    if (stage.x() < -(canvasSize * mapConfig.zoom - canvasSize)) {
                        stage.setAttrs({ x: -(canvasSize * mapConfig.zoom - canvasSize) })
                        stageX=-(canvasSize * mapConfig.zoom - canvasSize)
                    }
                    if (stage.y() > 0) {
                        stage.setAttrs({ y: 0 })
                        stageY=0
                    }
                    if (stage.y() < -(canvasSize * mapConfig.zoom - canvasSize)) {
                        stage.setAttrs({ y: -(canvasSize * mapConfig.zoom - canvasSize) })
                        stageY=-(canvasSize * mapConfig.zoom - canvasSize)
                    }
                })
            } else {
            //当放大倍数等于1时鼠标不可以拖动
                stage.setAttrs({ draggable: false })
            }
        })
        layer.batchDraw();//重绘
    }

拖拽时主要使用stage.x();地图在窗口中的位置来判断

;