我使用Konva平移和缩放包含图像和其他元素的舞台。我将draggable设置为true,我使用touchmove和touchend来设置舞台比例。但是,舞台从左上角而不是缩点进行缩放。如果我尝试根据夹点中心调整舞台位置,舞台位置似乎会跳跃,因为可拖动似乎也在设置位置。有一种很好的方法可以在缩放时设置捏合时的舞台位置吗?
答案 0 :(得分:0)
这就是我为游戏所做的事情。基本上你必须将touchMove事件处理程序的stagePosition设置为在缩放开始时设置的焦点的计算偏移量。
function getDistance(p1, p2) {
return Math.sqrt(Math.pow((p2.x - p1.x), 2) + Math.pow((p2.y - p1.y),2));
}
function getMapPointFromPoint(windowX,windowY) {
if (windowX === undefined) {
//inverse the coordinates and account for stage position
var mapX = Math.floor((-(stage.getX()) + (window.innerWidth*mapOffset)) / zoomLevel);
var mapY = Math.floor((-(stage.getY()) + (window.innerHeight/2)) / zoomLevel);
return({x: mapX, y: mapY});
} else {
var mapX = Math.floor((-(stage.getX()) + windowX) / zoomLevel);
var mapY = Math.floor((-(stage.getY()) + windowY) / zoomLevel);
return({x: mapX, y: mapY});
}
}
function setFocalPoint(mapX,mapY) {
if (mapX === undefined) {
// reverse the zoom to figure out the map coordinates at center of screen
var focalPoint = getMapPointFromPoint();
focalMapX = focalPoint.x;
focalMapY = focalPoint.y;
} else {
focalMapX = mapX;
focalMapY = mapY;
}
}
function scrollToMapPoint(x,y) {
stage.setPosition({x: Math.floor((window.innerWidth*mapOffset) - (x * zoomLevel)) , y: Math.floor((window.innerHeight/2) - (y * zoomLevel)) });
cullView();
stage.draw();
}
stage.getContent().addEventListener('touchstart', function(evt) {
var touch1 = evt.touches[0];
var touch2 = evt.touches[1];
touchInitPoint.x = touch1.clientX;
touchInitPoint.y = touch1.clientY;
if (touch1 && touch2) {
if (!pinching) {
setFocalPoint();
pinching = true;
cacheON();
}
}
});
stage.getContent().addEventListener('touchmove', function(evt) {
var touch1 = evt.touches[0];
var touch2 = evt.touches[1];
if (touch1 && touch2) {
var dist = getDistance({
x: touch1.clientX,
y: touch1.clientY
}, {
x: touch2.clientX,
y: touch2.clientY
});
if (!lastDist) {
lastDist = dist;
}
var scale = stage.getScaleX() * dist / lastDist;
if (scale < 0.2) {
scale = 0.2;
} else if (scale > 2) {
scale = 2;
}
stage.scaleX(scale);
stage.scaleY(scale);
zoomLevel = scale;
scrollToMapPoint(focalMapX,focalMapY);
stage.draw();
lastDist = dist;
} else {
if (pinching) {
//if losing contact with one touch, assume we start over on distance
lastDist = 0;
}
}
}, false);
stage.getContent().addEventListener('touchend', function(evt) {
var touch1 = evt.touches[0];
var touch2 = evt.touches[1];
if (pinching && (touch1 || touch2)) {
//wait until both gone
return;
} else {
if (pinching) {
lastDist = 0;
scrollToMapPoint(focalMapX,focalMapY);
if (pinchTimer) {
clearTimeout(pinchTimer);
}
pinchTimer = setTimeout(function () {
pinching = false;
cacheOFF();
},1000);
}
}
}, false);