【发布时间】:2018-05-16 20:34:20
【问题描述】:
我正在使用 Konva 平移和缩放包含图像和其他元素的舞台。我已将 draggable 设置为 true,并且正在使用 touchmove 和 touchend 设置舞台比例。但是,舞台从左上角而不是夹点缩放。如果我尝试根据捏合中心调整舞台位置,舞台位置似乎会跳来跳去,因为 Draggable 似乎也在设置位置。有没有一种在缩放时将舞台位置设置为捏合的好方法?
【问题讨论】:
标签: konvajs
我正在使用 Konva 平移和缩放包含图像和其他元素的舞台。我已将 draggable 设置为 true,并且正在使用 touchmove 和 touchend 设置舞台比例。但是,舞台从左上角而不是夹点缩放。如果我尝试根据捏合中心调整舞台位置,舞台位置似乎会跳来跳去,因为 Draggable 似乎也在设置位置。有没有一种在缩放时将舞台位置设置为捏合的好方法?
【问题讨论】:
标签: konvajs
这是我为我的游戏所做的。本质上,您必须在 touchMove 事件处理程序上将舞台的 setPosition 设置为在缩放开始时设置的焦点的计算偏移量。
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);
【讨论】: