如何使用 Javascript 和 Processing 创建 Google 地图样式缩放
How can I create a Google Maps style zoom using Javascript and Processing
我的地图程序以及标记已经有了平移和缩放功能,但我目前使用的缩放代码偶尔会起作用,而且感觉不自然。似乎离地图中心越远,情况就越糟。我一直在尝试实现类似于 Google 地图中看到的缩放,但运气不佳。
这是当前的缩放代码:
//Zoom function
function mouseWheel(event) {
var e = event.deltaY;
//Zoom in
if (e < 0) {
if (scale < maxScale) {
scale++;
imgW = (int)(imgOGW / (1 + (zoomFactor * abs(scale))));
imgH = (int)(imgOGH / (1 + (zoomFactor * abs(scale))));
centerX = centerX - (int)(zoomFactor * (mouseX - centerX));
centerY = centerY - (int)(zoomFactor * (mouseY - centerY));
}
}
//Zoom out
if (e > 0) {
if (scale > minScale && !(windowWidth > 1840 && scale == -3)) {
scale--;
imgH = (int)(imgOGH / (1 + (zoomFactor * abs(scale))));
imgW = (int)(imgOGW / (1 + (zoomFactor * abs(scale)))):
centerX = centerX + (int)((mouseX - centerX)
* (zoomFactor / (zoomFactor + 1)));
centerY = centerY + (int)((mouseY - centerY)
* (zoomFactor / (zoomFactor + 1)));
if (centerX - imgW / 2 > 0) {
centerX = imgW / 2;
}
if (centerX + imgW / 2 < width) {
centerX = width - imgW / 2;
}
if (centerY - imgH / 2 > 0) {
centerY = imgH / 2;
}
if (centerY + imgH / 2 < height) {
centerY = height - imgH / 2;
}
}
}
这是它在绘制循环中的显示方式:
function draw() {
var zoomModifier = (1 + (zoomFactor * abs(scale)));
background(0);
imageMode(CENTER);
image(map, centerX, centerY, imgW, imgH);
for (var m of markers) {
if (m.x/zoomModifier > viewX - (width/2) && m.x/zoomModifier < viewX + (width/2) && m.y/zoomModifier > viewY - (height/2) && m.y/zoomModifier < viewY + (height/2)) m.display();
}
}
CenterX 最初设置为整个地图宽度的一半(CenterY 设置为高度的一半)。
完整代码可以查看here and the project can be seen in action here.
如有任何帮助,我们将不胜感激。
这是我发现自己每次做涉及交互式缩放的事情时都必须考虑的问题。我总是对 MS Paint 等程序中的缩放功能如此糟糕感到惊讶。
你实际上已经很接近了,我认为你的想法是正确的:找到光标和图像中心之间的距离并适当地缩放它。我喜欢这样想:缩放是将值 (centerX - mouseX)
缩放一定量(与 Y
相同)。在模拟代码中,这看起来像
(centerX - mouseX) = zoom * (centerX - mouseX);
在实际代码中,结果证明你只是做了一些代数运算:
centerX = mouseX + (zoom * (centerX - mouseX));
顺便说一句,这与您的缩放之间存在一个关键区别。您使用的是倒数函数,而此版本是指数函数。我认为 Google 使用的可能更符合指数线。
这是我的全部改动(基于猜测你如何定义zoomFactor
):
function mouseWheel(event) {
zoom = pow(1 + zoomFactor, event.deltaY/125);
imgW *= zoom;
imgH *= zoom;
centerX = mouseX + (zoom * (centerX - mouseX));
centerY = mouseY + (zoom * (centerY - mouseY));
}
我的地图程序以及标记已经有了平移和缩放功能,但我目前使用的缩放代码偶尔会起作用,而且感觉不自然。似乎离地图中心越远,情况就越糟。我一直在尝试实现类似于 Google 地图中看到的缩放,但运气不佳。
这是当前的缩放代码:
//Zoom function
function mouseWheel(event) {
var e = event.deltaY;
//Zoom in
if (e < 0) {
if (scale < maxScale) {
scale++;
imgW = (int)(imgOGW / (1 + (zoomFactor * abs(scale))));
imgH = (int)(imgOGH / (1 + (zoomFactor * abs(scale))));
centerX = centerX - (int)(zoomFactor * (mouseX - centerX));
centerY = centerY - (int)(zoomFactor * (mouseY - centerY));
}
}
//Zoom out
if (e > 0) {
if (scale > minScale && !(windowWidth > 1840 && scale == -3)) {
scale--;
imgH = (int)(imgOGH / (1 + (zoomFactor * abs(scale))));
imgW = (int)(imgOGW / (1 + (zoomFactor * abs(scale)))):
centerX = centerX + (int)((mouseX - centerX)
* (zoomFactor / (zoomFactor + 1)));
centerY = centerY + (int)((mouseY - centerY)
* (zoomFactor / (zoomFactor + 1)));
if (centerX - imgW / 2 > 0) {
centerX = imgW / 2;
}
if (centerX + imgW / 2 < width) {
centerX = width - imgW / 2;
}
if (centerY - imgH / 2 > 0) {
centerY = imgH / 2;
}
if (centerY + imgH / 2 < height) {
centerY = height - imgH / 2;
}
}
}
这是它在绘制循环中的显示方式:
function draw() {
var zoomModifier = (1 + (zoomFactor * abs(scale)));
background(0);
imageMode(CENTER);
image(map, centerX, centerY, imgW, imgH);
for (var m of markers) {
if (m.x/zoomModifier > viewX - (width/2) && m.x/zoomModifier < viewX + (width/2) && m.y/zoomModifier > viewY - (height/2) && m.y/zoomModifier < viewY + (height/2)) m.display();
}
}
CenterX 最初设置为整个地图宽度的一半(CenterY 设置为高度的一半)。
完整代码可以查看here and the project can be seen in action here.
如有任何帮助,我们将不胜感激。
这是我发现自己每次做涉及交互式缩放的事情时都必须考虑的问题。我总是对 MS Paint 等程序中的缩放功能如此糟糕感到惊讶。
你实际上已经很接近了,我认为你的想法是正确的:找到光标和图像中心之间的距离并适当地缩放它。我喜欢这样想:缩放是将值 (centerX - mouseX)
缩放一定量(与 Y
相同)。在模拟代码中,这看起来像
(centerX - mouseX) = zoom * (centerX - mouseX);
在实际代码中,结果证明你只是做了一些代数运算:
centerX = mouseX + (zoom * (centerX - mouseX));
顺便说一句,这与您的缩放之间存在一个关键区别。您使用的是倒数函数,而此版本是指数函数。我认为 Google 使用的可能更符合指数线。
这是我的全部改动(基于猜测你如何定义zoomFactor
):
function mouseWheel(event) {
zoom = pow(1 + zoomFactor, event.deltaY/125);
imgW *= zoom;
imgH *= zoom;
centerX = mouseX + (zoom * (centerX - mouseX));
centerY = mouseY + (zoom * (centerY - mouseY));
}