当地图是一张图片时,如果不设置会导致放大缩小时,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();地图在窗口中的位置来判断